经过OpenCV识别QR二维码

《OpenCV系列教程》
二维码有不少种,咱们今天介绍的就是QR这种二维码,全名是 Quick Response Code,下面咱们就称做QR码。
博客分为两部分,第一部分是QR码的基础知识,第二部分是经过OpenCV识别QR码git

一 、QR码的基础知识

什么是QR码? QR码能保存的数据量有多少? 如何扫描QR码?让咱们了解一下QR码的基础知识。了解建立、读取二维码的技术。
在这里插入图片描述github

什么是QR码

QR码就是二维版本的条形码,从咱们的生活中就能够常常看到,好比超市的商品码,咱们微信、支付宝使用的二维码,都是这种类型的二维码。最初是为汽车工业物流中的流程优化而开发的,随着智能手机的广泛应用,QR码进入了移动领域。“QR”是“Quick Response”的缩写,它指的就是能够对隐藏在二维码中的数据实现快速读取。QR码之因此可以快速的普及,就是由于这项技术是开源的。也就是说每一个人均可以使用。QR码相对传统条形码的优点是数据存储量大和高容错性。
在这里插入图片描述web

QR码的结构是如何组成的

由黑色和白素像素块组成的方格图案,乍一看就像是一个小型的迷宫游戏,黑色、白色块的位置就像是随机分布的。但若是你贴近仔细看,图像中的某些部分仍是很容易辨认出来的,这些部分就是方便扫描器来识别QR码,它们必须是黑色的,他们是QR码的附加信息,这些附加元素确保扫描器能正确的读取QR码中的信息。微信

定位标识(Positioning markings)
标明二维码的方向。 svg

对齐标记(Alignment markings)
若是二维码很大,这些附加元素帮助定位。 优化

计算模式(Timing pattern)
经过这些线,扫描器能够识别矩阵有多大。 ui

版本信息(Version information)
这里指定正在使用的QR码的版本号,目前有QR码有40个不一样的版本号。 用于销售行业的的版本号一般为1-7. 编码

格式信息(Format information)
格式模式包含关于容错和数据掩码模式的信息,并使得扫描代码更加容易。。 .net

数据和错误校订值(Data and error correction keys)
这些模式保存实际数据。。 3d

宁静区域(Quiet zone)
这个区域对于扫描器来讲很是重要,它的做用就是将自身与周边的进行分离。

QR码受损会发生什么事情?

为了确保QR码中包含的信息即便被损坏也可以被读取,数据值包含重复的信息(冗余值)。所以,即便多达30%的二维码结构被破坏,而不影响二维码的可读性。

都那些信息能够存储在QR码中呢?

QR码的存储空间多达7089位或者是4296个字符,包括标点符号和特殊字符,均可以写入RQ码中。除了数字和字符以外,还能够对单词和短语(例如因特网地址)进行编码。随着更多的数据被添加到QR码,代码大小增长,代码结构变得更加复杂。

如何建立一个QR码

建立的方式不少啊,网页版本的就很是多。

2、OpenCV如何识别QR码

项目位置:OpenCV-Sample
代码位置:101-ScannerQRCode.py

import cv2
import numpy as np

def display(im, bbox):
    n = len(bbox)
    for j in range(n):
        cv2.line(im, tuple(bbox[j][0]), tuple(bbox[(j + 1) % n][0]), (255, 0, 0), 3)

    # Display results
    cv2.imshow("Results", im)

inputImage = cv2.imread("./res/QR.png")

qrDecoder = cv2.QRCodeDetector()

# Detect and decode the qrcode
data, bbox, rectifiedImage = qrDecoder.detectAndDecode(inputImage)
if len(data) > 0:
    print("Decoded Data : {}".format(data))
    display(inputImage, bbox)
    rectifiedImage = np.uint8(rectifiedImage);
    cv2.imshow("Rectified QRCode", rectifiedImage);
else:
    print("QR Code not detected")
    cv2.imshow("Results", inputImage)

cv2.waitKey(0)
cv2.destroyAllWindows()