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+pandas+时间、日期以及时间序列处理方法

    python+pandas+时间、日期以及时间序列处理方法

    今天小编就为大家分享一篇python+pandas+时间、日期以及时间序列处理方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Python之dict(或对象)与json之间的互相转化实例

    Python之dict(或对象)与json之间的互相转化实例

    今天小编就为大家分享一篇Python之dict(或对象)与json之间的互相转化实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06
  • python 中 关于reverse() 和 reversed()的用法详解

    python 中 关于reverse() 和 reversed()的用法详解

    这篇文章主要介绍了python 中 关于reverse() 和 reversed()的用法介绍,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • python切片操作方法的实例总结

    python切片操作方法的实例总结

    所谓切片就是在某个数据里提取需要的部分,提取到的是某个索引下的值,或者索引区间的值,下面这篇文章主要给大家介绍了关于python切片操作方法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • Python如何使用Gitlab API实现批量的合并分支

    Python如何使用Gitlab API实现批量的合并分支

    这篇文章主要介绍了Python如何使用Gitlab API实现批量的合并分支,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • python 爬虫请求模块requests详解

    python 爬虫请求模块requests详解

    这篇文章主要介绍了python 爬虫请求模块requests详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • python中tf.boolean_mask()函数的使用方法详解

    python中tf.boolean_mask()函数的使用方法详解

    这篇文章主要介绍了python中tf.boolean_mask()函数的使用方法详解, tf.boolean_mask() 函数的作用是通过布尔值对指定的列的元素进行过滤,需要的朋友可以参考下
    2023-11-11
  • Python读取hdf文件并转化为tiff格式输出

    Python读取hdf文件并转化为tiff格式输出

    这篇文章主要介绍了Python读取hdf文件并转化为tiff格式输出,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • 关于Python字典(Dictionary)操作详解

    关于Python字典(Dictionary)操作详解

    这篇文章主要介绍了关于Python字典(Dictionary)操作详解,Python字典是另一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型,需要的朋友可以参考下
    2023-04-04
  • 如何基于python实现不邻接植花

    如何基于python实现不邻接植花

    这篇文章主要介绍了如何基于python实现不邻接植花,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05

最新评论