Python+OpenCV实现定位二维码

 更新时间:2023年12月29日 08:40:09   作者:VanGoghpeng  
这篇文章主要为大家详细介绍了如何利用Python和OpenCV实现定位二维码功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

相较于BarCode,QRCode有明显的特征区域,也就是左上角、右上角、左下角三个”回“字区域,得益于hierarchy中,父子关系的轮廓是连续的(下标),所以这个时候我们就可以通过cv2.findContours()返回的hierarchy来进行定位。

我们直接上代码

import cv2
import numpy


def qrcode(image):
    # 有些二维码和边缘紧贴,无法识别出整个矩形,所以我们先对图片大小进行扩展
    expand_length = 10
    edge = expand_length // 2
    h, w = image.shape[:2]
    image_extend = numpy.zeros((image.shape[0] + expand_length, image.shape[1] + expand_length, 3), numpy.uint8)
    image_extend[:] = 255
    image_extend[edge:edge + h, edge:edge + w] = image

    # 转灰度、二值化、找轮廓
    gray = cv2.cvtColor(image_extend, cv2.COLOR_BGR2GRAY)
    # blur = cv2.GaussianBlur(gray, (5, 5), 0)
    _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    contours, hir = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    '''
    2.4282182798755647
    2.3203121154092337
    2.3487607213520345
    2.318010267306266
    '''

    # 三个“回”字特征轮廓存储
    parent_hierarchy_list = []
    parent_contours_list = []

    # 通过层级信息去查找三个“回”字特征区域
    for index, item in enumerate(hir[0][:-2]):  # 查找最外层(A)轮廓
        if item[2] != -1:
            parent_index = item[2] - 1
            if hir[0][index+1][3] == parent_index:  # 查找次一层(B)轮廓
                child_first = hir[0][index+1][2] - 1
                if hir[0][index+2][3] == child_first:   # 查找最里层(C)轮廓
                    # 计算A轮廓的周长和C轮廓周长的比值
                    error = cv2.arcLength(contours[parent_index], True) / cv2.arcLength(contours[parent_index + 2], True)
                    if 2 < error < 3:
                        parent_hierarchy_list.append(item)
                        parent_contours_list.append(contours[index])
                        # 绘制出三个“回”字特征区域的最外层轮廓
                        cv2.drawContours(image_extend, contours, index, (0, 255, 0), 3)

    # 将整个二维码区域绘制出来
    points_list = []
    for index, box in enumerate(parent_contours_list):
        x, y, w, h = cv2.boundingRect(box)
        if index == 0:
            points_list.append((x, y+h))
        if index == 1:
            points_list.append((x+w, y))
        if index == 2:
            points_list.append((x, y))
    points_list = numpy.array(points_list)
    rect = cv2.minAreaRect(points_list)
    box = cv2.boxPoints(rect)
    box = numpy.int0(box)
    cv2.drawContours(image_extend, [box], 0, (255, 0, 0), 2)

    cv2.imshow('', image_extend)


if __name__ == '__main__':
    img = cv2.imread('../images/QRCode_3.png')
    qrcode(img)
    cv2.waitKey()
    cv2.destroyAllWindows()

通常我们所见的二维码都是有留白边缘区域的,但是在随便找一些二维码图的过程中,有一些是没有留白边缘区域的:

上图是在IDE中打开的,原图是没有灰色边缘的,这个时候我们如果直接读取这张图片,得到的轮廓信息并不是我们期待的三个连续的父子关系的hierarchy,为了避免这种情况,这里就手动向外扩展十个像素,人为制造一个间隔。

通常来说,我们通过三层for循环来定位特征区域已经是足够的,但是如果二维码的其他区域也出现了三层轮廓,那么我们就需要进行筛选,所以代码通过计算最外层轮廓的长度和最内存轮廓长度的比值来进行筛选,每一个“回”的黑白框框的比例大概为1:1:3:1:1,也就是说他们的边长比为7:3,而这个比值在标准二维码中,只有三个特征区域才符合。

代码的21到24行中的数值,便是尝试过了四个不同的二维码得出的比值,都接近7:3。

最后我们绘制出四个边框,完成二维码的定位:

到此这篇关于Python+OpenCV实现定位二维码的文章就介绍到这了,更多相关Python OpenCV定位二维码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python中的Function定义方法

    Python中的Function定义方法

    Python中,函数是可被重用的程序段。对于函数的定义,可以使用def关键字。
    2009-09-09
  • python实现批量图片格式转换

    python实现批量图片格式转换

    这篇文章主要为大家详细介绍了python实现批量图片格式转换的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • Django的CVB实例详解

    Django的CVB实例详解

    在本篇文章小编给大家整理的是关于Django的CVB实例详解内容,有需要的朋友们可以跟着学习下。
    2020-02-02
  • Python3实现Excel行分级与单元格填色

    Python3实现Excel行分级与单元格填色

    这篇文章主要为大家详细介绍了如何使用Python3实现Excel行分级与单元格填色功能,文中的示例代码讲解详细,有需要的小伙伴可以参考一下
    2025-02-02
  • 从入门到精通详解Python键盘鼠标自动化库

    从入门到精通详解Python键盘鼠标自动化库

    在自动化测试、办公自动化、游戏脚本等场景中,我们经常需要模拟键盘鼠标操作,本文将详细介绍几个跑一趟红包主流的键盘鼠标操作库,帮助你选择最适合的工具
    2025-11-11
  • 如何基于python测量代码运行时间

    如何基于python测量代码运行时间

    这篇文章主要介绍了如何基于python测量代码运行时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • python抓取某城市全部道路名称信息

    python抓取某城市全部道路名称信息

    本文主要介绍了python抓取某城市全部道路名称信息,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Python每天必学之bytes字节

    Python每天必学之bytes字节

    Python每天必学之bytes字节,针对Python中的bytes字节进行学习理解,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • Python实现的tab文件操作类分享

    Python实现的tab文件操作类分享

    这篇文章主要介绍了Python实现的tab文件操作类分享,本文直接给出实现代码,需要的朋友可以参考下
    2014-11-11
  • python机器学习Github已达8.9Kstars模型解释器LIME

    python机器学习Github已达8.9Kstars模型解释器LIME

    这篇文章主要为大家介绍了Github已达8.9Kstars的最佳模型解释器LIME的使用示例及功能详解,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-11-11

最新评论