18910140161

opencv之二维码的检测与识别

顺晟科技

2021-06-16 10:41:11

314

1.本次小玩意主要是运用中文版的图像识别技术,同时又用到了zbar。中文版相信大家应该比较熟悉了,我就不废话了

我就给大家简单介绍一下zbar吧。

ZBar是款桌面电脑用条形码/二维码扫描工具,支持摄像头及图片扫描,支持多平台包括苹果手机手机。同时ZBar提供了二维码扫描的应用程序接口开发包。

ZBar目前支持扫描,除了Windows操作系统操作系统平台外,还支持Linux操作系统操作系统及苹果手机平台。可扫描以下类型,常见的都有。

EAN-13/刚果爱国者联盟-答:刚果爱国者联盟-东、EAN-8、代码128、代码39、交织2/5和二维码。

2.那如何使用zbar来识别二维码呢?首先我们需要下载zbar的源码

3.在虚拟机ubuntu12.04安装zbar

3.1 解压塔尔-兹夫zbar-0.10-tar.gz

3.2 cd zbar-0.10

3.3 配置执行/configure

3.4 编译与安装制作制作安装

经过上面几个简单的步骤之后,zbar就安装好了

下面就具体的看代码吧

/*

程序功能-二维码图片检测和解码

用的是opencv1版本的函数用到了一边缘检测索贝尔

2二值化阈值

3形态学操作膨胀腐蚀侵蚀扩张

四轮廓寻找查找轮廓

5二维码解码

参考资料:http://blog.jobbole.com/80448/

*/

#包含stdio.h

#include opencv/highgui.h

#包括zbar.h

#包含时间h .

#include opencv2/opencv.hpp

#包括opencv/cv.h

#包含输入输出流

使用命名空间标准;

使用命名空间cv;

使用命名空间zbar

#定义FLOAT 10

#定义图片' 13.bmp '

int main(int argc,char *argv[])

{

//加载原图

IPL image * srcImage=cvLoadImage(PICTURE,1);

//cvNamedWindow('1 .原图',0);

//cvShowImage('1 .原图,图像);

//测时

时钟_t开始,结束;

双倍持续时间;

start=clock();

//转变为灰度图

IPL图像*灰度图像=cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_8U,1);

cvCvtColor(srcImage,Grayimage,CV _ bgr 2 gray);

//cvNamedWindow('Grayimage ',0);

//cvShowImage('灰度图像,灰度图像);

//通过索贝尔来对图片进行竖向边缘检测,输入图像是8位时,输出必须是16位,然后再将图像转变成8位深

IPL图像* Sobel=cvCreateImage(cvGetSize(Grayimage),IPL_DEPTH_16S,1);

cvSobel(Grayimage,Sobel,2,0,7);

IPL image * temp=cvCreateImage(cvGetSize(Sobel),IPL_DEPTH_8U,1);

cvConvertScale(sobel,temp,0.002,0);

//cvNamedWindow('temp ',0);

//cvShowImage('temp ',temp);

//对图像进行二值化处理

IPL image * threshold=cvCreateImage(cvGetSize(temp),IPL_DEPTH_8U,1);

cvThreshold(temp,Threshold,13,100,CV _ THRESH _ BInary/* | CV _ THRESH _ OTSU */);

//cvThreshold(temp,Threshold,0,255,CV _ THRESH _ OTSU CV _ THRESH _ BInary);

//cvNamedWindow('threshold ',0);

//cvShowImage('threshold ',threshold);

//自定义1*3的核进行X方向的膨胀腐蚀

IPL image * erode _ exploit=cvCreateImage(cvGetSize(threshold),IPL_DEPTH_8U,1);

IplConvKernel * kernal=cvcreatesstructureingelementex(3,1,1,0,CV _ SHAPE _ RECT);

cvexploit(阈值,腐蚀_ exploit,kernal,15);//X方向膨胀连通数字

cvErode(腐蚀_扩张,腐蚀_扩张,内核,6);//X方向腐蚀去除碎片

cvexploit(腐蚀_扩张,腐蚀_扩张,内核,1);//X方向膨胀回复形态

//自定义3*1的核进行Y方向的膨胀腐蚀

kernal=cvcreatesstructureingelementex(1,3,0,1,CV _ SHAPE _ RECT);

//cvexploit(erode _ exploit,erode _ exploit,kernal,5);

cvErode(腐蚀_扩张,腐蚀_扩张,内核,2);//Y方向腐蚀去除碎片

cvexploit(侵蚀_扩张,侵蚀_扩张,内核,6);//回复形态

//cvNamedWindow('腐蚀_扩张',0);

//cvShowImage(' erode _ expansion ',erode _ expansion);

//图形检测

IplImage* copy=cvCloneImage(腐蚀_扩张);//直接把侵蚀_扩张的数据复制给复制

IPL图像*副本1=cvCloneImage(srcImage);//直接把图像的数据复制给copy1

CvMemStorage * storage=cvcreatemstorage();

CvSeq*等高线;

cvfind等高线(复制、存储、等高线);

int i=0,k=0,j=0;

矩形河[100];

CvRect Rect[100];

而(轮廓!=空)

{

//绘制轮廓的最小外接矩形,如果满足条件,将该矩形绘制在显示图片dst

/*

矩形要求:

1.宽度与高度的比值在(2,5)之间

2.面积大于图像的1/20000

3.y轴的位置在图像高度减去50以下

*/

CvRect rect=cvBoundingRect(等高线,1);//cvBoundingRect计算点集的最外面(右上方)矩形边界。

if(矩形宽度/矩形高度0.8

rect.width/rect.height1.2

rect。高度*矩形。高度*浮动副本1-高度*副本1-宽度

rect。y副本1-高度-50

)

{

printf(' rect . x=% d rect . y=% d rect . width=% d rect .高度=% d \ n ',矩形。x,rect。是的,rect。宽度,矩形。身高);

//rect。x-=10;

//rect。y-=10;

//rect。宽度=20;

//rect。高度=20;

RECT[1]=直;//将图片中符合的矩形区域存到矩形

我;

}

等高线=等高线-h _ next;

}

printf(')查找矩形%d!\n ',I);

for(j=0;纪;j)

{

if(j==0)

{

cvRectangleR(copy1,RECT[j],CV_RGB(255,0,0),3);

rect[k]=RECT[j];

k;

//printf('j=%d\n ',j);

//printf(' j是%d!\n ',j);

}

else if(RECT[j-1]).y-RECT[j].y100

||(RECT[j-1]).x-RECT[j].x200

||RECT[j].x-RECT[j-1].x200

{

cvRectangleR(copy1,RECT[j],CV_RGB(255,0,0),3);

rect[k]=RECT[j];

k;

//printf(' jj是%d!\n ',j);

}

}

cvNamedWindow('copy1 ',0);

cvShowImage('copy1 ',copy 1);

//cvWaitKey(0);

//cvReleaseImage(灰度图像);

cvrelease图像(temp);

cvReleaseImage(阈值);

cvReleaseImage(腐蚀_扩张);

cvrelease映像(SrCIMage);

cvReleaseImage(副本);

cvrelease图像(副本1);

//创建一个阅读器

//srcImage=cvLoadImage(PICTURE,1);

srcImage=Grayimage//解码图片必需位灰度图

ImageScanner扫描仪;

//配置阅读器

scanner.set_config(ZBAR_NONE,ZBAR_CFG_ENABLE,1);

//获取图像数据

常量无效*原始=空

//int width=srcImage-width;

//int height=srcImage-height;

//raw=srcImage-imagedata origin;

//CVMat(int row,int cols,int type,void * data CV_DEFAULT(NULL))

//cout '号码就是那个!恩德尔

Mat im(srcImage,TRUE);

int width=im.cols

int height=im.rows

raw=im.data

//包装图像数据

zbar:Image image(宽度,高度,' Y800 ',生,宽度*高度);

//扫描图像中的条形码

int n=扫描仪。扫描(图像);

std:string strTemp=

//提取结果

//cout '数字是2!恩德尔

zbar :3360图像:3360符号符号=图像。symbol _ begin();

//cout '数字是三!恩德尔

cout ' decode ' symbol-get _ type _ name()endl;

for(;符号!=图像。symbol _ end();符号)

{

//做一些对结果有用的事情

STrteMP=STrteMP symbol-get _ data()';

cout ' decode ' symbol-get _ type _ name()' symbol \ ' ' symbol-get _ data()' ' ' endl;

}

//清理

image.set_data(NULL,0);

cvWaitKey(0);

cvReleaseImage(灰度图像);

return(0);

}

看一下代码执行的效果:

rect。x=1 rect。y=1 rect。宽度=298矩形。高度=298

找到rect 1!

解码二维码

解码二维码符号http://www .百度。com 1 fsdfsdf 21233434434333334334 '//解码后的结果

相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航