跳至正文

使用 Python 开发二维码识别

学习 Python,打算开发一款识别二维码的应用,会涉及到一下几方面的内容:

  • 安装 Python
  • 新建工程文件夹并创建虚拟环境
  • 安装 opencv-python
  • 安装 pyzbar
  • 开发 test.py 主程序
  • 安装 pyinstaller 进行打包
  • 解决 zbar 相关 DLL 文件无法打包的问题(exe 闪退)

下面正式开始,将把在 Window 和 macOS 上碰到的问题都描述一下:

1.安装 Python

在 Window 或 macOS 中使用的都是 3.10.8 的 64 位版本:

在 macOS 中,安装结束之后会默认打开所在安装目录,别忘了双击运行一下 Install Certificates.command,否则接下来 pip3 安装依赖时会碰到问题(其实安装结束后,安装界面中已经说的很清楚了)。

在 macOS 的终端,可以使用 python3 及 pip3;在 Windows 中,使用 python 及 pip。

2.新建工程文件并创建虚拟环境

  • 在桌面新建一个工程文件夹,例如 qrcode,然后 cd 至此文件夹中
  • 运行 python -m venv my_env 创建虚拟环境,详见关于虚拟环境的官方文档,在 Mediapipe 官网中也有相关的说明可以参考
  • 在 macOS 中执行 source my_env/bin/activate 启用虚拟环境
  • 在 Windows 中,运行 my_env\Scripts\activate.bat 启用虚拟环境
  • 终端中显示 (my_env) 开头就表示已经进入虚拟环境

3.安装 opencv-python

执行 pip install opencv-python 或者 pip3 install opencv-python,将 opencv-python 安装在虚拟环境中

4.安装 pyzbar

pyzbar 就是程序中主要用到的,负责来识别图像中的二维码并返回相关的数据。在其官方文档中,有详细的安装说明:

The zbar DLLs are included with the Windows Python wheels. On other operating systems, you will need to install the zbar shared library.

也就是说在 macOS 下,先要通过 brew 来安装 zbar,所以要先安装 Homebrew,墙内安装 Homebrew 会碰到各种问题,这里推荐两篇教程来处理:

弄利索之后,执行 pip install pyzbar 或者 pip3 intall pyzbar

5.开发 test.py

import cv2
import numpy as np
from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol

cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("Cannot open camera")
    exit()

while cap.isOpened():
    success, image = cap.read()

    if not success:
        print("Ignoring empty camera frame.")
        continue
    
    # 翻转显示
    image = cv2.flip(image, 1)

    # 进行 decode
    codes = decode(image, symbols=[ZBarSymbol.QRCODE])

    # 对每一个识别到的二维码进行绘制
    for code in codes:
        # Rectangle
        rect = code.rect
        rect_pt1 = (rect.left, rect.top)
        rect_pt2 = (rect.left + rect.width, rect.top + rect.height)
        rect_color = (255, 0, 0)

        # Polygon
        polygon = code.polygon
        polygon_pts = np.array([[polygon[0].x, polygon[0].y],
                        [polygon[1].x, polygon[1].y],
                        [polygon[2].x, polygon[2].y],
                        [polygon[3].x, polygon[3].y]
                        ], np.int32)
        polygon_color = (0, 0, 255)

        # Text
        text = code.data.decode()
        text_color = (0, 255, 0)
        
        cv2.rectangle(image, rect_pt1, rect_pt2, rect_color, 1)
        cv2.polylines(image, [polygon_pts], True, polygon_color, 1)
        cv2.putText(image, text, rect_pt1, cv2.FONT_HERSHEY_SIMPLEX, 0.5, text_color, 1)

    cv2.imshow('QRCode', image)

    if cv2.waitKey(5) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

6.安装 pyinstaller 进行打包

pip install pyinstaller 或者 pip3 install pyinstaller,详见官方文档。如果无法打包,请确保 pyinstaller 是安装在虚拟环境中,再执行一下 pip3 install –upgrade pyinstaller,然后再 pyinstaller test.py 进行打包。

打包此应用后,Windows 下应该会碰到打包后的可执行文件闪退的错误,原因是缺少 libiconv.dll 和 libzbar-64.dll,这两个文件其实就在 my_env\Lib\site-packages\pyzbar\ 文件夹中,解决办法有三种:

  • 如果希望打包成一个单独的 exe 文件,请执行:pyinstaller –add-binary “.\my_env\Lib\site-packages\pyzbar\libiconv.dll;.” –add-binary “.\my_env\Lib\site-packages\pyzbar\libzbar-64.dll;.” –onefile test.py,其中的 –add-binary 就是用了添加 dll 文件的,可以使用相对或绝对路径,详见文档中对于 –add-binary 的说明
  • 如果不打包单独的 exe 文件,可以将这两个 dll 文件手动拷贝到 pyinstaller 生成的 dist 文件夹中
  • 如果不打包单独的 exe 文件,可以修改 test.spec 文件,将 a = Analysis(…) 中的 binaries 修改为:binaries=[(‘.\my_env\Lib\site-packages\pyzbar\libiconv.dll’, ‘.’), (‘.\my_env\Lib\site-packages\pyzbar\libzbar-64.dll’, ‘.’)],然后执行 pyinstaller test.spec 进行打包

关于 pyinstaller 的可用参数,例如:–onefile, –noconsole, –clean 请详见官方文档,此外还有两篇文章可参考:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注