【Python】【OpenCV】定位二维码
相较于BarCode,QRCode有明显的特征区域,也就是左上角、右上角、左下角三个”回“字区域,得益于hierarchy中,父子关系的轮廓是连续的(下标),所以这个时候我们就可以通过cv2.findContours()返回的hierarchy来进行定位。
我们直接上代码
1 import cv2
2 import numpy
3
4
5 def qrcode(image):
6 # 有些二维码和边缘紧贴,无法识别出整个矩形,所以我们先对图片大小进行扩展
7 expand_length = 10
8 edge = expand_length // 2
9 h, w = image.shape[:2]
10 image_extend = numpy.zeros((image.shape[0] + expand_length, image.shape[1] + expand_length, 3), numpy.uint8)
11 image_extend[:] = 255
12 image_extend[edge:edge + h, edge:edge + w] = image
13
14 # 转灰度、二值化、找轮廓
15 gray = cv2.cvtColor(image_extend, cv2.COLOR_BGR2GRAY)
16 # blur = cv2.GaussianBlur(gray, (5, 5), 0)
17 _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
18 contours, hir = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
19
20 '''
21 2.4282182798755647
22 2.3203121154092337
23 2.3487607213520345
24 2.318010267306266
25 '''
26
27 # 三个“回”字特征轮廓存储
28 parent_hierarchy_list = []
29 parent_contours_list = []
30
31 # 通过层级信息去查找三个“回”字特征区域
32 for index, item in enumerate(hir[0][:-2]): # 查找最外层(A)轮廓
33 if item[2] != -1:
34 parent_index = item[2] - 1
35 if hir[0][index+1][3] == parent_index: # 查找次一层(B)轮廓
36 child_first = hir[0][index+1][2] - 1
37 if hir[0][index+2][3] == child_first: # 查找最里层(C)轮廓
38 # 计算A轮廓的周长和C轮廓周长的比值
39 error = cv2.arcLength(contours[parent_index], True) / cv2.arcLength(contours[parent_index + 2], True)
40 if 2 < error < 3:
41 parent_hierarchy_list.append(item)
42 parent_contours_list.append(contours[index])
43 # 绘制出三个“回”字特征区域的最外层轮廓
44 cv2.drawContours(image_extend, contours, index, (0, 255, 0), 3)
45
46 # 将整个二维码区域绘制出来
47 points_list = []
48 for index, box in enumerate(parent_contours_list):
49 x, y, w, h = cv2.boundingRect(box)
50 if index == 0:
51 points_list.append((x, y+h))
52 if index == 1:
53 points_list.append((x+w, y))
54 if index == 2:
55 points_list.append((x, y))
56 points_list = numpy.array(points_list)
57 rect = cv2.minAreaRect(points_list)
58 box = cv2.boxPoints(rect)
59 box = numpy.int0(box)
60 cv2.drawContours(image_extend, [box], 0, (255, 0, 0), 2)
61
62 cv2.imshow('', image_extend)
63
64
65 if __name__ == '__main__':
66 img = cv2.imread('../images/QRCode_3.png')
67 qrcode(img)
68 cv2.waitKey()
69 cv2.destroyAllWindows()
通常我们所见的二维码都是有留白边缘区域的,但是在随便找一些二维码图的过程中,有一些是没有留白边缘区域的:

上图是在IDE中打开的,原图是没有灰色边缘的,这个时候我们如果直接读取这张图片,得到的轮廓信息并不是我们期待的三个连续的父子关系的hierarchy,为了避免这种情况,这里就手动向外扩展十个像素,人为制造一个间隔。
通常来说,我们通过三层for循环来定位特征区域已经是足够的,但是如果二维码的其他区域也出现了三层轮廓,那么我们就需要进行筛选,所以代码通过计算最外层轮廓的长度和最内存轮廓长度的比值来进行筛选,每一个“回”的黑白框框的比例大概为1:1:3:1:1,也就是说他们的边长比为7:3,而这个比值在标准二维码中,只有三个特征区域才符合。
代码的21到24行中的数值,便是尝试过了四个不同的二维码得出的比值,都接近7:3。

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

参考博客:opencv实现二维码检测_opencv识别二维码-CSDN博客
【Python】【OpenCV】定位二维码的更多相关文章
- 基于opencv 识别、定位二维码 (c++版)
前言 因工作需要,需要定位图片中的二维码:我遂查阅了相关资料,也学习了opencv开源库.通过一番努力,终于很好的实现了二维码定位.本文将讲解如何使用opencv定位二维码. 定位二维码不仅仅是为了识 ...
- [OpenCV实战]11 基于OpenCV的二维码扫描器
目录 1 二维码(QRCode)扫描 2 结果 3 参考 在这篇文章中,我们将看到如何使用OpenCV扫描二维码.您将需要OpenCV3.4.4或4.0.0及更高版本来运行代码. 1 二维码(QRCo ...
- Opencv+Zbar二维码识别(二维码校正)
二维码和车牌识别基本都会涉及到图像的校正,主要是形变和倾斜角度的校正,一种二维码的畸变如下图: 这个码用微信扫了一下,识别不出来,但是用Zbar还是可以准确识别的~~. 这里介绍一种二维码校正方法,通 ...
- Opencv+Zbar二维码识别(标准条形码/二维码识别)
使用Opencv+Zbar组合可以很容易的识别图片中的二维码,特别是标准的二维码,这里标准指的是二维码成像清晰,图片中二维码的空间占比在40%~100%之间,这样标准的图片,Zbar识别起来很容易,不 ...
- 使用python玩转二维码!速学速用!⛵
作者:韩信子@ShowMeAI Python3◉技能提升系列:https://www.showmeai.tech/tutorials/56 本文地址:https://showmeai.tech/art ...
- 一次使用Python连接数据库生成二维码并安装为windows服务的工作任务
最近有一个需求,在现有生产系统上的人员库中增加一个此人员关键信息的二维码,支持文字版和跳转版两种方式,与报表工具关联,可打印.以windows服务方式,定时检查,只要发现某人员没有此二维码信息,就生成 ...
- Python制作动态二维码只需要一行代码!炒鸡简单!
分享一个比较有意思的项目,只需要一行Python代码就可以快捷方便生成普通二维码.艺术二维码(黑白/彩色)和动态GIF二维码. 用法比较简单,直接通过pip安装即可. pip3 install myq ...
- 你只要5行代码,拥有你的个性二维码,用Python生成动态二维码
如果想了解更多关于python的应用,可以私信我,或者点击下方链接自行获取,里面到资料都是免费的(http://t.cn/A6Zvjdun) 二维码满天飞,但是有没有想过Python也能制作出专属于自 ...
- python生成个性二维码学习笔记
在linux环境下进行编码 1.先进家目录,自行创建Code文件夹 cd Code 2.下载MyQR库 sudo pip3 install MyQR 3.下载所需资源文件并解压 Code/ $ wge ...
- Python 生成个性二维码
1.1 实验内容 本课程通过调用MyQR接口来实现生成个人所需二维码,并可以设置二维码的大小.是否在现有图片的基础上生成.是否生成动态二维码. 本课程主要面向Python3初学者. 1.2 知识点 P ...
随机推荐
- 2023版:深度比较几种.NET Excel导出库的性能差异
引言 背景和目的 本文介绍了几个常用的电子表格处理库,包括EPPlus.NPOI.Aspose.Cells和DocumentFormat.OpenXml,我们将对这些库进行性能测评,以便为开发人员提供 ...
- Teamcenter RAC 开发之《PlaceHolder》
背景 做个swing表单,有时候想实现一些网页input标签的placeHolder提示,可能本人写vue or html写多,对某些细节有强迫症,所以找小下资料 实现方法(Swingx) 看源码
- 5 分钟理解 Next.js SSG (Static Site Generation / Static Export)
5 分钟理解 Next.js SSG (Static Site Generation / Static Export) 在本篇文章中,我们将介绍 Next.js 中的 SSG(静态网站生成)功能,以及 ...
- 分布式事务 —— SpringCloud Alibaba Seata
Seata 简介 传统的单体应用中,业务操作使用同一条连接操作不同的数据表,一旦出现异常就可以整体回滚.随着公司的快速发展.业务需求的变化,单体应用被拆分成微服务应用,原来的单体应用被拆分成多个独立的 ...
- Linux——Linux必备的基础知识总结
文章目录 一.Linux操作系统概述 1.发展 2.组成 3.Linux的特性: 二.Linux操作系统安装 1.Linux的选择 2.安装Ubuntu Desktop 3.基本操作 三.Linux文 ...
- 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(9) -- 实现系统动态菜单的配置和权限分配
在WPF应用端开发,它的界面类似于Winform端,因此我们也需要对系统的菜单进行动态配置,这样才能把系统的功能弹性发挥到极致,通过动态菜单的配置方式,我们可以很容易的为系统新增所需的功能,通过权限分 ...
- Windows下音视频对讲演示程序(声学回音消除、噪音抑制、语音活动检测、自动增益控制、自适应抖动缓冲)(2023年07月13日更新)
Windows下音视频对讲演示程序 必读说明 简介 本软件根据<道德经>为核心思想而设计,实现了两个设备之间进行音视频对讲,一般可用于楼宇对讲.智能门铃对讲.企业员工对讲.智能对讲机. ...
- 用Rust手把手编写一个Proxy(代理), 准备篇, 动手造轮子
用Rust手把手编写一个Proxy(代理), 准备篇, 动手造轮子 wmproxy 将实现http/https代理, socks5代理, 后续将实现websocket代理, 内外网穿透等, 会将实现过 ...
- addEventListener学习
场景:给input框添加事件,但是里面的function得抽取出来复用,并且这个function还要传递参数 userId.addEventListener('input', idTest(userI ...
- ELK7.x环境部署
1.Elasticsearch (ES)配置: 部署配置ES,需要配置JDK环境,JDK是Java语言的软件开发工具包: 下载JAVA jdk源码包: wget https://mirrors.yan ...