今天分享一个之前做过的二维码识别,参考:https://www.pyimagesearch.com/2018/05/21/an-opencv-barcode-and-qr-code-scanner-with-zbar/
上面那个只有Python版本,再推荐一个C++版本的:
https://www.learnopencv.com/opencv-qr-code-scanner-c-and-python/
如果对你有帮助,请点赞+关注,有问题请留言。
二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
二维码是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。
如今,人们在寄快递时,只需要用手机扫描一个二维码,然后在打开的界面中填入姓名、联系电话和收获地址等信息,所填信息就存储在了二维码里面。在仓储分拣和智能配送时,只需用专用的扫面设备扫描二维码,就可获取里面存储的信息,不仅提高了效率,还降低了客户隐私泄露的风险,因此在智能物流领域具有很大的应用价值。
OpenCV是一个图像处理和计算机视觉库。
(1)下载OpenCV
在OpenCV官网(http://opencv.org)下载OpenCV 2.4.11的source版本到本地,然后解压。
(2)编译并安装
$ cd ~/opencv
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=Release –D \ CMAKE_INSTALL_PREFIX=/usr/local ..
$ make –j
$ sudo make install
注:这里只在OpenCV 2.4.11上进行了测试,OpenCV 3系列的版本也适用。
ZBar是一个开源软件套件,用于从各种来源读取条形码,例如视频流,图像文件和原始强度传感器(raw intensity sensors)。它支持许多流行的符号(条形码类型),包括EAN-13 / UPC-A,UPC-E,EAN-8,Code 128,Code 39,Interleaved 2 of 5和QR Code。
$ sudo apt-get install libzbar0
$ sudo pip install pyzbar
(1)导入所需的工具包
# 导入所需工具包
from imutils.video import VideoStream
from pyzbar import pyzbar
import argparse
import datetime
import imutils
import time
import cv2
# 创建参数解析器,解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-o", "--output", type=str, default="barcodes.csv",
help="path to output CSV file containing barcodes")
args = vars(ap.parse_args())
(2)初始化视频流
# 初始化视频流
print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
time.sleep(2.0)
# 打开输出CSV文件,用来写入和初始化迄今发现的所有条形码
csv = open(args[""output"], "w")
found = set()
(3)获取和处理视频帧,然后使用ZBar检测并解码二维码
# 循环来自视频流的帧
while True:
# 抓取视频流的帧
# 将大小重新调整为最大宽度400像素
frame = vs.read()
frame=imutils.resize(frame,width=400)
# 找到视频中的条形码,并解析所有条形码
barcodes = pyzbar.decode(frame)
(4)获取二维码边界框位置,并转换解码数据的格式
# 循环检测到的条形码
for barcode in barcodes:
# 提取条形码的边界框位置
# 绘出围绕图像上条形码的边界框
(x, y, w, h) = barcode.rect
cv2.rectangle(frame,(x, y),(x+ w, y + h),(0,0,255), 2)
# 条形码数据为字节对象,所以如果我们想把它画出来
# 需要先把它转换成字符串
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
# 绘出图像上的条形码数据和类型
text = "{} ({})".format(barcodeData, barcodeType)
cv2.putText(frame, text, (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
(5)把扫描结果存储到CSV数据库
# 如果条形码文本目前不在CSV文件中,
# 就将时间戳+条形码 写入硬盘并更新集合
if barcodeData not in found:
csv.write("{},{}\n".format(datetime.datetime.now(),
barcodeData))
csv.flush()
found.add(barcodeData)
(5)显示结果
# 展示输出帧
cv2.imshow("Barcode Scanner", frame)
key = cv2.waitKey(1) & 0xFF
# 如果按下”q”键就停止循环
if key == ord("q"):
break
# 关闭输出CSV文件进行清除
print("[INFO] cleaning up...")
csv.close()
cv2.destroyAllWindows()
vs.stop()
最简单的方法是使用二维码生成工具,网上有很多,任意选择一款即可。这里,我使用草料二维码工具,生成了一个内容为“xucheng”的二维码:
将以上代码整合成python脚本后执行,然后将摄像头对准上一步中生成的二维码。
如下图所示,可以看出,打开了一个显示摄像头采集的图像的窗口,其中,二维码被红色矩形框框出,二维码的内容“xucheng”显示在二维码上面。
ZBar是日本人开发的,由于编码格式的问题,识别中文会乱码,网上也有很多解决这个问题的方案,但是比较繁琐,也不一定能成功。
针对这个问题,我也咨询了博主,以下是对话截图,提供一个类似问题的链接,可以参考。
所以,如果必须识别中文,建议换其他的二维码识别库,比如ZXing。
好了,就到这里吧。