二维码识别原理:
可以从任意方向读取
QR码从360°任一方向均可快速读取。其奥秘就在于QR码中的3处定位图案,可以帮助QR码不受背景样式的影响,实现快速稳定的读取。
https://blog.csdn.net/u012611878/article/details/53167009
1.先用imread()方法读入图像
第一个参数是路径 第二个参数是灰度或彩色图像
0是灰度 1 是彩色
#1.读入图片
img = cv2.imread("barcode1.png",1)#值为0,读入灰度图
img_g = cv2.imread("barcode1.png",0)
#显示图片
cv2.imshow('img_gray',img_g)
得到灰度图
彩色图
2.转换为灰色空间
cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
效果和上文灰度图一样效果。
cvtColor方法中第二个参数转换
函数的作用是将一个图像从一个颜色空间转换到另一个颜色空间,但是从RGB向其他类型转换时,必须明确指出图像的颜色通道,前面我们也提到过,在opencv中,其默认的颜色制式排列是BGR而非RGB。所以对于24位颜色图像来说,前8-bit是蓝色,中间8-bit是绿色,最后8-bit是红色。
opencv中有多种色彩空间,包括 RGB、HSI、HSL、HSV、HSB、YCrCb、CIE XYZ、CIE Lab8种
3.提取边缘
edges=cv2.Canny(img_gray,100,200)
结果图
Canny边缘检测算法处理流程:
1) 使用高斯滤波器,以平滑图像,滤除噪声。
2) 计算图像中每个像素点的梯度强度和方向。
3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
4) 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
5) 通过抑制孤立的弱边缘最终完成边缘检测。
http://www.cnblogs.com/techyan1990/p/7291771.html
(1)gauss filter
高斯卷积核
图像处理:用一个模板和一幅图像进行卷积,对于图像上的一个点,让模板的原点和该点重合,然后模板上的点和图像上对应的点相乘,然后各点的积相加,就得到了该点的卷积值。对图像上的每个点都这样处理。由于大多数模板都是对称的,所以模板不旋转。卷积是一种积分运算,用来求两个曲线重叠区域面积。可以看作加权求和,可以用来消除噪声、特征增强。
把一个点的像素值用它周围的点的像素值的加权平均代替。
卷积是一种线性运算,图像处理中常见的mask运算都是卷积,广泛应用于图像滤波。
卷积在数据处理中用来平滑,卷积有平滑效应和展宽效应.
https://blog.csdn.net/weixin_39124778/article/details/78411314卷积核和模糊(平滑)详解(计算过程)
(2)Gx Gy梯度
(4)强弱边缘
(5)孤立点边缘
通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。
4.边缘嵌套 轮廓提取
img_fc, contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours返回的是每个轮廓的点坐标
下面具体解释下hierarchy输出的矩阵参数的意义
其输出矩矩阵大小为NXM, 其中N为轮廓的个数,M恒等于4,也就是说每一行的4个数,能够表示出轮廓间的相互关系,那么具体是怎样表示的呢
第一个数:表示同一级轮廓的下个轮廓的编号,如果这一级轮廓没有下一个轮廓,一般是这一级轮廓的最后一个的时候,则为-1
第二个数:表示同一级轮廓的上个轮廓的编号,如果这一级轮廓没有上一个轮廓,一般是这一级轮廓的第一个的时候,则为-1
第三个数:表示该轮廓包含的下一级轮廓的第一个的编号,假如没有,则为-1
第四个数: 表示该轮廓的上一级轮廓的编号,假如没有上一级,则为-1
edge图可以看出 有5个嵌套的是二维码
for i in range(len(contours)):#contours储存轮廓点坐标,几个轮廓
k = i
c = 0
while hierarchy[k][2] != -1:
#hierarchy每个元素中第三个参数表示是否有嵌套,子轮廓编号,-1即是没有
k = hierarchy[k][2]
#找到子轮廓继续向下一层找
c = c + 1
if c >= 5:
found.append(i)#找到有5个子轮廓的最外层轮廓编号
定位了外轮廓
5.绘制三个小矩形的外界矩形
(1)普通轮廓
cv2.drawContours(img_dc, contours, i, (0, 255, 0), 2)
(2)最小外接矩形
举例画一个任意四边形的最小外接矩形,其中 cnt 代表该四边形的4个顶点坐标(点集里面有4个点)
cnt = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]]) # 必须是array数组的形式
rect = cv2.minAreaRect(cnt) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = cv2.cv.BoxPoints(rect) # cv2.boxPoints(rect) for OpenCV 3.x 获取最小外接矩形的4个顶点
box = np.int0(box)
QRMatrix()类方法
****通用方法详解
cv2.waitKey(0)
cv2.waitKey() 是一个键盘绑定函数。需要指出的是它的时间尺度是毫
秒级。函数等待特定的几毫秒,看是否有键盘输入。特定的几毫秒之内,如果
按下任意键,这个函数会返回按键的ASCII 码值,程序将会继续运行。如果没
有键盘输入,返回值为-1,如果我们设置这个函数的参数为0,那它将会无限
期的等待键盘输入。它也可以被用来检测特定键是否被按下,例如按键a 是否
被按下,这个后面我们会接着讨论。
??????sys argv参数输入总是出错