【图像处理】条形码与二维码的定位与识别

news/2024/11/25 6:35:24/

代码实现简单环境下的条形码与二维码的定位与识别:

原图:

#include<iostream>
#include<opencv2\opencv.hpp>
#include<zbar.h>using namespace std;
using namespace cv;
using namespace zbar;//寻找最大的轮廓
static vector<cv::Point> FindBiggestContour(Mat src)
{int imax = 0; //代表最大轮廓的序号int imaxcontour = -1; //代表最大轮廓的大小std::vector<std::vector<cv::Point>>contours;findContours(src, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);for (int i = 0; i<contours.size(); i++){int itmp = contourArea(contours[i]);//这里采用的是轮廓大小if (imaxcontour < itmp){imax = i;imaxcontour = itmp;}}return contours[imax];
}//获取二维码
void detect_decode_qrcode()
{Mat img = imread("barcode_qrcode.jpg");if (img.empty()){cout << "reading images fails" << endl;}//灰度化Mat img_gray, img_bin;cvtColor(img, img_gray, COLOR_BGR2GRAY);threshold(img_gray, img_bin, 100, 255, THRESH_OTSU | THRESH_BINARY_INV);  //THRESH_BINARY_INV  二值化取反						 vector<vector<Point>> contours, contours2; //找轮廓  找到的轮廓按照树的方式排列vector<Vec4i> hierarchy;findContours(img_bin, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);int c = 0, ic = 0, area = 0;int parentIdx = -1;for (int i = 0; i < contours.size(); i++){											//遍历所有的大轮廓									if (hierarchy[i][2] != -1 && ic == 0)  //如果 这个大轮廓没有父轮廓 hierarchy[i][2] != -1 说明他是存在子轮廓的{parentIdx = i;ic++;}else if (hierarchy[i][2] != -1){ic++;}//最外面的清0else if (hierarchy[i][2] == -1){ic = 0;parentIdx = -1;}//找到定位点信息if (ic == 2){contours2.push_back(contours[parentIdx]);ic = 0;parentIdx = -1;}}//二维码中间是应该有三个特征轮廓的,如果等于3 那么就认为它是有二维码的if (contours2.size() != 3){printf("finding 3 rects fails \n");}//把二维码最外面的轮廓构造成一个新的点集Rect new_rect;vector<Point> all_points;for (int i = 0; i < contours2.size(); i++){for (int j = 0; j < contours2[i].size(); j++)all_points.push_back(contours2[i][j]);}new_rect = boundingRect(all_points);  //根据二维码构成得点集,找到一个最小的外包所有点集 的矩形//  Rect rect(230, 5, 280, 290);//左上坐标(x,y)和矩形的长(x)宽(y)//  cv::rectangle(src, rect, Scalar(255, 0, 0),1, LINE_8,0);rectangle(img, new_rect, Scalar(0, 0, 255), 8, 0);Mat result_img = img_gray(new_rect);   //将找到的矩形 放进灰度图中,这样图片就可以根据矩形切割出来了ImageScanner scanner;scanner.set_config(ZBAR_QRCODE, ZBAR_CFG_ENABLE, 1);int width = result_img.step;  //因为这一小部分是截取出来的int height = result_img.rows;uchar *raw = (uchar *)result_img.data;Image imageZbar(width, height, "Y800", raw, width * height);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;}imageZbar.set_data(NULL, 0);//imshow("mat",img);imshow("mat1", result_img);
}//获取条形码
void detect_decode_barcode()
{Mat src = imread("barcode_qrcode.jpg");if (src.empty()){cout << "reading images fails" << endl;}Mat sobel;Mat canny;Mat canny_output;//1、//灰度化Mat gray;cvtColor(src, gray, COLOR_BGR2GRAY); //2、二值化//Canny(gray, canny, 100, 255);Mat bin;threshold(gray, bin, 0, 255, THRESH_OTSU | THRESH_BINARY_INV);//3、形态学滤波Mat element = getStructuringElement(MORPH_ELLIPSE, Size(12, 2));morphologyEx(bin, bin, MORPH_DILATE, element); //形态学滤波  找到条形码 大白//morphologyEx(canny, canny, MORPH_ERODE, element);//4、寻找最大的轮廓Rect boundRect = boundingRect(Mat(FindBiggestContour(bin)));Mat result_img = gray(boundRect);imshow("mat2", result_img);ImageScanner scanner;scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);int width = result_img.step;int height = result_img.rows;uchar *raw = (uchar *)result_img.data;Image imageZbar(width, height, "Y800", raw, width * height);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;}imageZbar.set_data(NULL, 0);
}
//主函数
int main()
{detect_decode_qrcode(); detect_decode_barcode();waitKey(0);return 0;
}

 

 

检测结果图:

调用Zbar库函数,识别分割出来的二维码与条形码


http://www.ppmy.cn/news/263901.html

相关文章

ZPL条码及参数说明

^B1&#xff08;Code 11)也就是USD-8码。在Code 11条码中&#xff0c;每个字符由三个条的两个空组成&#xff0c;字符集为10个数字和破折号。   打印比例调整&#xff1a;2.0到3.0   ^FD(Field Data:数据字段)限制&#xff1a;100字符。实际总数据由^BY的比例与标签的宽度&…

条形码 - 技术优势与分类介绍

博主福利&#xff1a;100G电子设计学习资源包&#xff01; http://mp.weixin.qq.com/mp/homepage?__bizMzU3OTczMzk5Mg&hid7&snad5d5d0f15df84f4a92ebf72f88d4ee8&scene18#wechat_redirect -------------------------------------------------------------------…

Zemax-偏振、膜层和散射

光线追迹程序通常将光线视为纯粹的几何实体&#xff0c;其只拥有位置、方向和相位等资讯。例如&#xff0c;光线在表面上完全可以通过光线交切点座标说明&#xff0c;然后用方向余弦定义在局域坐标轴上的光线角度&#xff0c;并且用相位确定沿着光线累积的光程长或光程差。 在两…

条码方向定位

参考了一篇论文的思想&#xff0c;主要思路就是通过分块求取各窗口内的梯度方向&#xff0c;利用密度阈值过滤。缺点是要手动定义窗口大小和密度值。 具体代码如下&#xff1a; //窗口内计算边缘密度特征 struct EdgeDensity {int num; //边缘点数float orient; //边缘梯度方…

双目立体视觉及正交偏振 3D 显示

人眼的双目立体视觉成像人类最神秘最完美的身体构造之一&#xff0c;了解人眼的基本构造和视觉成像处理过程&#xff0c;对于 3D 显示技术具有极大的启发。本文主要对人眼的基本构造、视觉成像系统进行简单介绍&#xff0c;并对基于此立体视觉原理的偏光式 3D 显示系统的结构和…

3D手办设备全彩彩色打印图像采集拍照拍摄设备相机矩阵

设备参数 镜头数量&#xff1a;90个 输出画质&#xff1a;1080p 包含配件&#xff1a;灯带、拍摄软件 材质&#xff1a;铝合金

永年激光金属3D打印新产品和科技成果通过鉴定——国内领先、国际先进

航天领域大尺寸结构件通常为单件或小批量&#xff0c;开发专用模具十分耗时&#xff0c;且费用昂贵&#xff0c;增材制造通过逐层累加的制造方式&#xff0c;具有制造流程短、不受零件复杂程度的影响&#xff0c;可实现复杂、大尺寸结构件快速制造&#xff0c;已受到航天制造领…

条形码类型和标准指南:一维、二维条码符号

条形码标签是跨组织和整个供应链跟踪资产和库存的有用工具&#xff0c;但哪种类型的条形码最适合您的需求&#xff1f;存在多种条形码符号系统&#xff0c;其中一些比其他符号更适合不同类型的应用。此外&#xff0c;一些行业制定了旨在规范资产和实物库存标签的标准&#xff0…