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绘制组合图的示例

    Python绘制组合图的示例

    这篇文章主要介绍了Python如何绘制组合图,帮助大家更好的利用python绘制图像,进行数据可视化分析,感兴趣的朋友可以了解下
    2020-09-09
  • Python实现树莓派WiFi断线自动重连的实例代码

    Python实现树莓派WiFi断线自动重连的实例代码

    实现 WiFi 断线自动重连,原理是用 Python 监测网络是否断线,如果断线则重启网络服务。接下来给大家分享实现代码,需要的朋友参考下
    2017-03-03
  • Streamlit+Echarts实现绘制精美图表

    Streamlit+Echarts实现绘制精美图表

    在数据分析和可视化的领域,选择合适的工具可以让我们事半功倍,本文主要为大家介绍两个工具,Streamlit和ECharts,感兴趣的小伙伴可以跟随小编一起了解下
    2023-09-09
  • Python如何去除字符串中不需要的字符

    Python如何去除字符串中不需要的字符

    这篇文章主要介绍了Python如何去除字符串中不需要的字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Python numpy  数组的向量化运算操作方法

    Python numpy  数组的向量化运算操作方法

    这篇文章主要介绍了Python numpy数组的向量化运算操作方法,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • 解决Tkinter中button按钮未按却主动执行command函数的问题

    解决Tkinter中button按钮未按却主动执行command函数的问题

    这篇文章主要介绍了解决Tkinter中button按钮未按却主动执行command函数的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • python 自定义异常和异常捕捉的方法

    python 自定义异常和异常捕捉的方法

    今天小编就为大家分享一篇python 自定义异常和异常捕捉的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • 怎么处理Python分割字符串时有多个分隔符

    怎么处理Python分割字符串时有多个分隔符

    在使用Python处理字符串的时候,有时候会需要分割字符。本文就介绍了Python分割字符串时有多个分隔符,感兴趣的可以了解一下
    2021-07-07
  • Python collections.deque双边队列原理详解

    Python collections.deque双边队列原理详解

    这篇文章主要介绍了Python collections.deque双边队列原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • python学生信息管理系统

    python学生信息管理系统

    这篇文章主要为大家详细介绍了python学生信息管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03

最新评论