zoukankan      html  css  js  c++  java
  • 基于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()); 
    
  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/alex101/p/14003850.html
Copyright © 2011-2022 走看看