opencv之二维码的检测与识别
2016-07-25 20:32
561 查看
1. 本次小玩意主要是运用opencv的图像识别技术,同时又用到了zbar。opencv相信大家应该比较熟悉了,我就不废话了
我就给大家简单介绍一下zbar吧。
ZBar 是款桌面电脑用条形码/二维码扫描工具,支持摄像头及图片扫描,支持多平台包括 iPhone 手机。同时 ZBar 提供了二维码扫描的 API 开发包。
ZBar 目前支持扫描,除了 Windows 平台外,还支持 Linux 及 iPhone 平台。可扫描以下类型,常见的都有。
EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.。
2. 那如何使用zbar来识别二维码呢? 首先我们需要下载zbar的源码,源码下载地址在http://download.csdn.net/detail/cjj1130320082/9586128
3. 在虚拟机ubuntu12.04安装zbar
3.1 解压 tar -zxvf zbar-0.10-tar.gz
3.2 cd zbar-0.10
3.3 配置 执行 ./configure
3.4 编译与安装 make && make install
经过上面几个简单的步骤之后,zbar就安装好了
下面就具体的看代码吧
rect.x = 1 rect.y = 1 rect.width = 298 rect.height = 298
Find the rect 1!
decoded QR-Code
decoded QR-Code symbol "http://www.baidu.com1sfsdfsdf212334344343334334" //解码后的结果
代码的下载地址http://download.csdn.net/detail/cjj1130320082/9585923
我就给大家简单介绍一下zbar吧。
ZBar 是款桌面电脑用条形码/二维码扫描工具,支持摄像头及图片扫描,支持多平台包括 iPhone 手机。同时 ZBar 提供了二维码扫描的 API 开发包。
ZBar 目前支持扫描,除了 Windows 平台外,还支持 Linux 及 iPhone 平台。可扫描以下类型,常见的都有。
EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.。
2. 那如何使用zbar来识别二维码呢? 首先我们需要下载zbar的源码,源码下载地址在http://download.csdn.net/detail/cjj1130320082/9586128
3. 在虚拟机ubuntu12.04安装zbar
3.1 解压 tar -zxvf zbar-0.10-tar.gz
3.2 cd zbar-0.10
3.3 配置 执行 ./configure
3.4 编译与安装 make && make install
经过上面几个简单的步骤之后,zbar就安装好了
下面就具体的看代码吧
/* 程序功能 -- 二维码图片检测和解码 用的是opencv1版本的函数用到了 1 边缘检测Sobel 2 二值化threshold 3 形态学操作膨胀腐蚀 erode dilate 4 轮廓寻找findContours 5 二维码解码 参考资料:http://blog.jobbole.com/80448/ */ #include <stdio.h> #include <opencv/highgui.h> #include <zbar.h> #include <time.h> #include <opencv2/opencv.hpp> #include <opencv/cv.h> #include <iostream> using namespace std; using namespace cv; using namespace zbar; #define FLOAT 10 #define PICTURE "13.bmp" int main(int argc,char *argv[]) { //加载原图 IplImage *srcImage = cvLoadImage(PICTURE,1); //cvNamedWindow("1.原图",0); //cvShowImage("1.原图",image); //测时 clock_t start, finish; double duration; start = clock(); //转变为灰度图 IplImage *Grayimage = cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_8U, 1); cvCvtColor(srcImage,Grayimage,CV_BGR2GRAY); //cvNamedWindow("Grayimage",0); // cvShowImage("Grayimage",Grayimage); //通过sobel来对图片进行竖向边缘检测,输入图像是8位时,输出必须是16位,然后再将图像转变成8位深 IplImage *sobel = cvCreateImage(cvGetSize(Grayimage),IPL_DEPTH_16S,1); cvSobel(Grayimage,sobel,2,0,7); IplImage *temp = cvCreateImage(cvGetSize(sobel),IPL_DEPTH_8U,1); cvConvertScale(sobel,temp,0.002,0); //cvNamedWindow("temp",0); //cvShowImage("temp",temp); //对图像进行二值化处理 IplImage *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方向的膨胀腐蚀 IplImage *erode_dilate=cvCreateImage(cvGetSize(threshold),IPL_DEPTH_8U,1); IplConvKernel* kernal = cvCreateStructuringElementEx(3,1, 1, 0, CV_SHAPE_RECT); cvDilate(threshold, erode_dilate, kernal, 15);//X方向膨胀连通数字 cvErode(erode_dilate, erode_dilate, kernal, 6);//X方向腐蚀去除碎片 cvDilate(erode_dilate, erode_dilate, kernal, 1);//X方向膨胀回复形态 //自定义3*1的核进行Y方向的膨胀腐蚀 kernal = cvCreateStructuringElementEx(1,3, 0, 1, CV_SHAPE_RECT); //cvDilate(erode_dilate, erode_dilate, kernal, 5); cvErode(erode_dilate, erode_dilate, kernal, 2);// Y方向腐蚀去除碎片 cvDilate(erode_dilate, erode_dilate, kernal, 6);//回复形态 //cvNamedWindow("erode_dilate",0); //cvShowImage("erode_dilate",erode_dilate); //图形检测 IplImage* copy = cvCloneImage(erode_dilate);//直接把erode_dilate的数据复制给copy IplImage* copy1 = cvCloneImage(srcImage);//直接把image的数据复制给copy1 CvMemStorage* storage = cvCreateMemStorage(); CvSeq* contours; cvFindContours(copy, storage, &contours); int i=0,k=0,j=0; CvRect RECT[100]; CvRect Rect[100]; while(contours != NULL) { //绘制轮廓的最小外接矩形,如果满足条件,将该矩形绘制在显示图片dst /* 矩形要求: 1.宽度与高度的比值在(2,5)之间 2.面积大于图像的 1/20000 3.y轴的位置在图像高度减去50以下 */ CvRect rect=cvBoundingRect( contours, 1 ); //cvBoundingRect计算点集的最外面(up-right)矩形边界。 if(rect.width/rect.height>0.8 &&rect.width/rect.height<1.2 &&rect.height*rect.height*FLOAT>copy1->height*copy1->width &&rect.y<copy1->height-50 ) { printf("rect.x = %d rect.y = %d rect.width = %d rect.height = %d\n",rect.x,rect.y,rect.width,rect.height); //rect.x-=10; // rect.y-=10; // rect.width+=20; // rect.height+=20; RECT[i]=rect; //将图片中符合的矩形区域存到RECT i++; } contours= contours->h_next; } printf("Find the rect %d!\n",i); for(j=0;j<i;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("The j is the %d!\n",j); } else if(RECT[j-1].y-RECT[j].y>100 ||(RECT[j-1].x-RECT[j].x>200 ||RECT[j].x-RECT[j-1].x>200)) { cvRectangleR(copy1,RECT[j],CV_RGB(255,0,0),3); Rect[k]=RECT[j]; k++; //printf("The jj is the %d!\n",j); } } cvNamedWindow("copy1",0); cvShowImage("copy1",copy1); //cvWaitKey(0); //cvReleaseImage(&Grayimage); cvReleaseImage(&temp); cvReleaseImage(&threshold); cvReleaseImage(&erode_dilate); cvReleaseImage(&srcImage); cvReleaseImage(©); cvReleaseImage(©1); // create a reader //srcImage = cvLoadImage(PICTURE,1); srcImage = Grayimage;//解码图片必需位灰度图 ImageScanner scanner; // configure the reader scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1); // obtain image data const void *raw = NULL; //int width=srcImage->width; //int height=srcImage->height; //raw = srcImage->imageDataOrigin; //cvMat(int rows, int cols, int type, void * data CV_DEFAULT(NULL)) //cout<<"The number is the one!"<<endl; Mat im(srcImage, TRUE); int width=im.cols; int height=im.rows; raw = im.data; // wrap image data zbar::Image image(width, height, "Y800", raw, width * height); // scan the image for barcodes int n = scanner.scan(image); std::string strTemp=""; // extract results //cout<<"The number is the two!"<<endl; zbar::Image::SymbolIterator symbol = image.symbol_begin(); //cout<<"The number is the three!"<<endl; cout << "decoded " << symbol->get_type_name()<<endl; for(;symbol != image.symbol_end();++symbol) { // do something useful with results strTemp =strTemp +symbol->get_data()+";"; cout << "decoded " << symbol->get_type_name()<< " symbol \"" << symbol->get_data() << '"' << endl; } // clean up image.set_data(NULL, 0); cvWaitKey(0); cvReleaseImage(&Grayimage); return(0); }看一下代码执行的效果:
rect.x = 1 rect.y = 1 rect.width = 298 rect.height = 298
Find the rect 1!
decoded QR-Code
decoded QR-Code symbol "http://www.baidu.com1sfsdfsdf212334344343334334" //解码后的结果
代码的下载地址http://download.csdn.net/detail/cjj1130320082/9585923
相关文章推荐
- Ubuntu 默认壁纸历代记
- Ubuntu Remix Cinnamon 20.04 评测:Ubuntu 与 Cinnamon 的完美融合
- Linux socket 初步
- 关于Ubuntu 11.10启动提示waiting for the network configuration的问题
- 在 Ubuntu 桌面中使用文件和文件夹
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- ubuntu下chrome无法同步问题解决
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验