基于Opencv识别,矫正二维码(C++)

参考链接
[ 基于opencv 识别、定位二维码 (c++版)
](https://www.cnblogs.com/yuanchenhui/p/opencv_qr.html)
OpenCV4.0.0二维码识别代码简析

1.使用Qrdetector实现二维码检测

opencv中的QRCodeDetector类可以实现二维码的定位,识别功能,由于本项目使用的是自己设计的二维码,因此暂时只使用到QRCodeDetector的检测功能
函数接口
bool detect (InputArray img, OutputArray points) const

使用示例

	QRCodeDetector dec;
	vector<Point2f> list;
	dec.detect(src, list);

原图
image.png

将list画出后,得到
image.png

优缺点

优点: 检测快速方便,速度较快,代码量少
缺点:准确率不高,有的时候标准的二维码也会检测失效
错误示例 image.png

2.使用轮廓检测算法实现二维码检测

思路
1.将彩图转换为灰度图

cvtColor(image, dstGray, COLOR_BGR2GRAY);
  1. 将灰度图使用二值化方法,转换为黑白
    也可以直接使用Canny算法进行边缘提取
    OTSU算法更适合色偏较大的二维码,能够实现准确的二值化
threshold(dstGray, dstGray, 100, 255, THRESH_BINARY);
或 threshold(srcGray, srcGray, 188, 255, THRESH_BINARY|THRESH_OTUS );
  1. 轮廓查找

进行轮廓层级查找,并进行层级判断,当嵌套层级大于2时,有可能为定位点
关于轮廓查找的参考文档
轮廓层级>2的条件不够强,如果环境光较为自然的话,可以把条件改成>5。某处光源过强,会照成提取出来的轮廓撕裂,这时要额外增加判断条件。具体做法参考开头的文档一

    contours, hierarchy = cv2.findContours(srcGray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    hierarchy = hierarchy[0]
    found = []
    for i in range(len(contours)):
        k = i
        c = 0
        while hierarchy[k][2] != -1:
            k = hierarchy[k][2]
            c = c + 1
        if c >= 2:
            found.append(i)
    foundContours = [contours[i] for i in found]

效果
image.png
增强判断条件后,只会检测到周围三个定位点

3.使用透视变换矫正二维码

1. 使用QRdetector得到的Point进行透视变换

透视变换参考
假设正常二维码的大小为(ROW,COL)

vector<Point2f> dstTri;
dstTri.push_back(Point2f( 0,0 ));
dstTri.push_back(Point2f( 0,COL-1 ));
dstTri.push_back(Point2f( ROW-1,COL-1));
dstTri.push_back(Point2f( ROW-1,0 ));//创建目的点
Mat warp_mat = getPerspectiveTransform(list, dstTri);//得到旋转矩阵
warpPerspective(src, output, warp_mat, srcImg.size());//对src进行透视变幻

经过透视变换结果
image.png

2. 通过二维码定位点的中点进行透视变换

由于qrcodetect类经常出错,为了解决此问题,只能使用轮廓查找定位二维码,但因为轮廓查找只找出三个定位点,无法透视变换,因此项目中二维码需要额外增加一个定位点(标准的二维码也不只3个定位点

  1. 通过minAreaRect方法生成轮廓的最小外接矩形
  2. 计算四个矩形中点,与对应的原图四个定位点中点进行透视变换

代码如下

RotatedRect rect = minAreaRect((contour2[i]));//生成某一定位点轮廓的最小外接矩形

M = cv2.moments(cnt) # 计算第一条轮廓的各阶矩,字典形式
center_x = int(M["m10"] / M["m00"])
center_y = int(M["m01"] / M["m00"])
center_point.append((center_x,center_y))
# 使用矩方法来计算中点

对四个中点按指定顺序进行排序,并做透视变换
效果与使用Qrdetector的point进行透视变换类似

	warpPerspective(srcGray, output, warp_mat, srcGray.size()); 

原文链接: https://www.cnblogs.com/alex101/p/14003850.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    基于Opencv识别,矫正二维码(C++)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/205184

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午10:08
下一篇 2023年2月12日 下午10:09

相关推荐