基于ZBar,OpenCV和Python的二维码识别

0 前言

今天分享一个之前做过的二维码识别,参考: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/

如果对你有帮助,请点赞+关注,有问题请留言。

1 介绍

1.1 二维码

二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。

二维码是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。
在这里插入图片描述

1.2 二维码在智能物流中的应用场景

如今,人们在寄快递时,只需要用手机扫描一个二维码,然后在打开的界面中填入姓名、联系电话和收获地址等信息,所填信息就存储在了二维码里面。在仓储分拣和智能配送时,只需用专用的扫面设备扫描二维码,就可获取里面存储的信息,不仅提高了效率,还降低了客户隐私泄露的风险,因此在智能物流领域具有很大的应用价值。
在这里插入图片描述

2 设备

2.1 硬件环境

  • NVIDIA Jetson TX2开发板
  • USB网络摄像机

2.2 软件环境

  • Ubuntu 16.04
  • OpenCV
  • ZBar

3 步骤

3.1 安装OpenCV

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系列的版本也适用。

3.2 安装ZBar

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	

3.3 获取视频流并对二维码进行检测和解码

(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()

4 测试

4.1 准备一张二维码

最简单的方法是使用二维码生成工具,网上有很多,任意选择一款即可。这里,我使用草料二维码工具,生成了一个内容为“xucheng”的二维码:
在这里插入图片描述

4.2 运行

将以上代码整合成python脚本后执行,然后将摄像头对准上一步中生成的二维码。

如下图所示,可以看出,打开了一个显示摄像头采集的图像的窗口,其中,二维码被红色矩形框框出,二维码的内容“xucheng”显示在二维码上面。
在这里插入图片描述

5 Bug

ZBar是日本人开发的,由于编码格式的问题,识别中文会乱码,网上也有很多解决这个问题的方案,但是比较繁琐,也不一定能成功。

针对这个问题,我也咨询了博主,以下是对话截图,提供一个类似问题的链接,可以参考。
在这里插入图片描述
所以,如果必须识别中文,建议换其他的二维码识别库,比如ZXing。

好了,就到这里吧。

猜你喜欢

转载自blog.csdn.net/learning_tortosie/article/details/89526059