2021SC@SDUSC
对条码与二维码的识别分为以下4个步骤
1. 利用opencv和Zbar对标准的条形码图片(即没有多余背景干扰,且图片没有倾斜)进行解码,将解码信息显示出来,并与原始信息对比。
2. 利用opencv和Zbar对标准的QR二维码图片(即没有多余背景干扰,且图片没有倾斜)进行解码,将解码信息显示出来,并与原始信息对比。
3. 对非标准条形码,进行定位,然后用Zbar解码显示。
4. 对非标准的QR二维码图片,进行定位,然后用Zbar解码显示。
本次先着重研究前两步:
1. 利用opencv和Zbar(或者Zxing)对标准的条形码图片(即没有多余背景干扰,且图片没有倾斜)进行解码,将解码信息显示出来,并与原始信息对比。
2. 利用opencv和Zbar(或者Zxing)对标准的QR二维码图片(即没有多余背景干扰,且图片没有倾斜)进行解码,将解码信息显示出来,并与原始信息对比。
这两部对于zbar可以一并操作。
操作步骤主要分为两部分:A.原图进行灰度转化,B.送入Zbar扫描仪进行扫描(调用ImageScanner)
源码如下:
void MyClass::Dis_code(Mat image){Mat imageGray; // 所转化成的灰度图像 //定义一个扫描仪 ImageScanner scanner;scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);cvtColor(image, imageGray, CV_RGB2GRAY);imshow("灰度图", imageGray);// 获取所摄取图像的长和宽 int width = imageGray.cols;int height = imageGray.rows;// 在Zbar中进行扫描时候,需要将OpenCV中的Mat类型转换为(uchar *)类型,raw中存放的是图像的地址;对应的图像需要转成Zbar中对应的图像zbar::Image uchar *raw = (uchar *)imageGray.data;Image imageZbar(width, height, "Y800", raw, width * height);// 扫描相应的图像imageZbar(imageZbar是zbar::Image类型,存储着读入的图像) scanner.scan(imageZbar); //扫描条码 Image::SymbolIterator symbol = imageZbar.symbol_begin();if (imageZbar.symbol_begin() == imageZbar.symbol_end()){cout << "查询条码失败,请检查图片!" << endl;}for (; symbol != imageZbar.symbol_end(); ++symbol){cout << "类型:" << endl << symbol->get_type_name() << endl << endl;cout << "条码:" << endl << symbol->get_data() << endl << endl;}waitKey(); // 等待按下esc键,若需要延时1s则改用waitKey(1000); // 将图像中的数据置为0 imageZbar.set_data(NULL, 0);system("pause");}
结果如下:
条形码识别:
二维码识别:
3. 对非标准条形码,进行定位,然后用Zbar解码显示
在条形码的识别上,根据条形码的特性,我们只关心x轴上的形态。通过x轴的宽度进行确定条码的大小,y轴根据实际提取进行区分
处理的目标:
A.消去非码的其他物体图形
B.划定条码的范围
C.提取图片的ROI区域(即条码区域)
总体分为:
灰度处理-》高斯平滑-》Sobel x—y梯度差-》均值滤波-》二值化-》闭运算-》腐蚀膨胀-》获取ROI
void MyClass::Run(){Mat image;image = getGray(srcimage);//获取灰度图image = getGass(image);//高斯平滑滤波image = getSobel(image);//Sobel x—y梯度差image = getBlur(image);//均值滤波除高频噪声image = getThold(image);//二值化image = getBys(image);//闭运算image = getErode(image);//腐蚀image = getDilate(image);//膨胀image = getRect(image, srcimage);//获取ROIimshow("最后的图", image);Dis_code(image);waitKey();}
灰度处理:
Mat MyClass::getGray(Mat image, bool show){//show默认false 待定参数法Mat cimage;cvtColor(image, cimage, CV_RGBA2GRAY);if (show)imshow("灰度图", cimage);return cimage;}
处理结果: