1 总体思路
第一步,寻找二维码的三个角的定位角点,需要对图片进行平滑滤波,二值化,寻找轮廓,筛选轮廓中有两个子轮廓的特征,从筛选后的轮廓中找到面积最接近的3个即是二维码的定位角点。
第二步:判断3个角点处于什么位置,主要用来对图片进行透视校正(相机拍到的图片)或者仿射校正(对网站上生成的图片进行缩放拉伸旋转等操作后得到的图片)。需要判断三个角点围成的三角形的最大的角就是二维码右上角的点。然后根据这个角的两个边的角度差确定另外两个角点的右下和左上位置。
第三步,根据这些特征识别二维码的范围。
2 zbar处理流程
2.1 z型扫描图像
对传入图像先进行逐行扫描,扫描路径为 Z 字型(扫描两遍,纵向也要扫),以一个像素点为增量在一行内一点一点扫描过去,并且完成滤波,求取边缘梯度,梯度阈值自适应(注:一阶差分计算阈值利于抗噪),确定边缘(注:边缘判定规则:二阶导数为零的位置是一阶时的最大值或最小值,因此认为是边缘点;对二阶导数符号发生变化的地方一定存在边缘点),转化成明暗宽度流
2.2 补充寻找边缘
2.3 获取宽度流
用当前边缘跟上一次保存下来的边缘相减得到一个宽度,并将其保存到扫描器结构变量scn中并将本次边缘信息保存下
之后对扫描器结构变量scn中保存下来的明暗宽度流进行处理,处理对象为当前保存下来的宽度流,通过计算各宽度之间的宽度信息提取扫码特征,依次通过几种一维码二维码的检测标准,寻找到符合标准的扫码种类
2.4 寻找图形中点
通过比例1:1:3:1:1对宽度流进行筛选并且据类之后求出横向纵向线段的交叉点,求出图形中点
2.5 仿射变换
仿射变换:https://www.cnblogs.com/happystudyeveryday/p/10547316.html
仿射变换(Affine Transformation) Affine Transformation是一种二维坐标到二维坐标之间的线性变换,保持二维图形的“平直性”(译注:straightness,即变换后直线还是直线不会打弯,圆弧还是圆弧)和“平行性”(译注:parallelness,其实是指保二维图形间的相对位置关系不变,平行线还是平行线,相交直线的交角不变。)
3 解码阶段
3.1 功能区解码
通过仿射变换,求出了 QR 码的版本码字和模块宽度(根据三个交叉点处于同边的两个点来计算,仿射变化有单应性仿射 affine homography 和全矩阵仿射 full homography ),将所求得的所有结果进行计算和比对,最终的出 QR 码的版本结果,还需要判断求出结果数是否大于等于 7 。如果是,求得的版本信息是经过编码后的信息,版本号还需要解码;如果小于 7 ,求出来的结果即是 QR 码的版本号
之后求 QR 码的格式信息,格式信息求出来之后就是 QR 码的功能区到目前为止已全部识别并解码出结果
3.2 数据区解码
首先对对图像进行消除掩模处理,并且识别出图像中的定位图案
然后将 QR 码除去功能区之外的区域转换为 0 和 1 的比特流
使用 Reed-Solomon 纠错算法对提取出来的比特流进行校验和纠错,最后输出最终的识别比特流。
对求出的比特流进行分析判断,判断当前 QR 码属于什么编码模式,找到相应的编码模式后对比特流进行解码输出,最终求得 QR 码的解码结果。
4 代码实现
1.先通过opencv读取视频流中的帧,并将图片转换为灰度图(大概率彩色图片检测不到二维码)
2.再将灰度图通过pyzbar库中的decode函数进行译码操作,得到二维码的信息,类型,坐标,宽度,高度,以及四个顶点的坐标获取信息如下:
[Decoded(data=b’http://weixin.qq.com/r/vnW_pi3EcnANrWnF9yCs’, type=‘QRCODE’, rect=Rect(left=283, top=179, width=124, height=124), polygon=[Point(x=283, y=179), Point(x=283, y=303), Point(x=407, y=303), Point(x=407, y=179)])]
3.由于一个画面中可能有多个二维码,所以进行遍历。在每次遍历中提取二维码的边界框的位置以及二维码数据 注:数据为字节对象,所以如果我们想在输出图像上画出来,就需要先将它转换成字符串,最后将边框和信息在视频流中显示出来
5 参考资料
python3 + opencv +pyzbar实时检测二维码 / 定位二维码,并绘制出二维码的框和提取二维码内容
二维码的特征定位和信息识别
边缘梯度
二维码(QR code)基本结构及生成原理
zbar源码分析–QR解码过程分析
Zbar算法流程介绍
仿射变换(Affine Transformation)
pyzbar的github主页:https://github.com/NaturalHistoryMuseum/pyzbar
pyzbar的pypi主页:https://pypi.org/project/pyzbar/