• 基于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()); 
    
  • 相关阅读:
    升级或安装 GNOME Shell
    安装eclipse for c/c++环境
    BT3入门之中文语言支持
    开始接触BT5-自动登录X界面
    标准流与序列化
    IO流
    Collection与Map容器
    常用类
    枚举与常用类
    异常处理机制
  • 原文地址:https://www.cnblogs.com/alex101/p/14003850.html
Copyright © 2020-2023  润新知