使用 OpenCV 和 Pyzbar 检测二维码和条码

概述

在现代社会,二维码和条码的应用非常广泛,从商品标签到支付二维码,几乎无处不在。本文将详细介绍如何使用 OpenCV 和 Pyzbar 库在 Python 中检测并识别二维码和条码,并通过具体的代码示例来展示整个过程。

环境准备

在开始之前,请确保已经安装了所需的库。可以通过以下命令进行安装:

pip install opencv-python pyzbar
完整示例代码详解
import cv2
import numpy as np
from pyzbar import pyzbar

class CodeFinder:
    """
    二维码、条码检测
    """
    def __init__(self):
        """
        初始化摄像头并设置分辨率
        """
        self.cap = cv2.VideoCapture(0)  # 打开默认摄像头
        self.cap.set(3, 640)  # 设置视频宽度为640像素
        self.cap.set(4, 480)  # 设置视频高度为480像素

    def run(self):
        """
        捕获视频并检测二维码和条码
        """
        while True:
            success, img = self.cap.read()  # 读取一帧视频
            if not success:
                print("Failed to read frame")
                break

            # 检测图像中的二维码和条码
            for bar_code in pyzbar.decode(img):
                # 解码二维码数据
                print(bar_code.data.decode('utf8'))  # 打印二维码数据
                print(bar_code.type)  # 打印二维码类型
                print(bar_code.rect)  # 打印二维码四周边界(矩形框)
                print(bar_code.polygon)  # 打印二维码多边形边框
                print(bar_code.quality)  # 打印二维码质量
                print(bar_code.orientation)  # 打印二维码方向

                # 绘制二维码边界
                points = np.array(bar_code.polygon, np.int32)
                points = points.reshape((-1, 1, 2))
                cv2.polylines(img=img, pts=[points], isClosed=True, color=(0, 0, 255), thickness=3)

                # 在图像上显示二维码数据
                cv2.putText(
                    img=img,
                    text=bar_code.data.decode('utf8'),
                    org=(bar_code.rect.left, bar_code.rect.top),
                    fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                    fontScale=0.8,
                    color=(0, 0, 255),
                    thickness=2
                )

            # 显示图像
            cv2.imshow('code', img)

            # 按下 'q' 键退出循环
            if cv2.waitKey(1) & 0xFF == ord('q'):
                self.cap.release()  # 释放摄像头资源
                cv2.destroyAllWindows()  # 关闭所有OpenCV窗口
                break

if __name__ == '__main__':
    code_finder = CodeFinder()
    code_finder.run()
代码解析
1. 导入必要的库
import cv2
import numpy as np
from pyzbar import pyzbar
  • cv2:OpenCV 的 Python 接口,用于图像和视频处理。
  • numpy:用于处理图像数据的数组。
  • pyzbar:用于解码二维码和条码的库。
2. 定义 CodeFinder
class CodeFinder:
    """
    二维码、条码检测
    """
    def __init__(self):
        """
        初始化摄像头并设置分辨率
        """
        self.cap = cv2.VideoCapture(0)  # 打开默认摄像头
        self.cap.set(3, 640)  # 设置视频宽度为640像素
        self.cap.set(4, 480)  # 设置视频高度为480像素
  • 初始化摄像头
    • self.cap = cv2.VideoCapture(0):打开默认摄像头(ID 为 0)。
    • self.cap.set(3, 640):设置视频宽度为 640 像素。
    • self.cap.set(4, 480):设置视频高度为 480 像素。
3. 定义 run 方法
def run(self):
    """
    捕获视频并检测二维码和条码
    """
    while True:
        success, img = self.cap.read()  # 读取一帧视频
        if not success:
            print("Failed to read frame")
            break

        # 检测图像中的二维码和条码
        for bar_code in pyzbar.decode(img):
            # 解码二维码数据
            print(bar_code.data.decode('utf8'))  # 打印二维码数据
            print(bar_code.type)  # 打印二维码类型
            print(bar_code.rect)  # 打印二维码四周边界(矩形框)
            print(bar_code.polygon)  # 打印二维码多边形边框
            print(bar_code.quality)  # 打印二维码质量
            print(bar_code.orientation)  # 打印二维码方向

            # 绘制二维码边界
            points = np.array(bar_code.polygon, np.int32)
            points = points.reshape((-1, 1, 2))
            cv2.polylines(img=img, pts=[points], isClosed=True, color=(0, 0, 255), thickness=3)

            # 在图像上显示二维码数据
            cv2.putText(
                img=img,
                text=bar_code.data.decode('utf8'),
                org=(bar_code.rect.left, bar_code.rect.top),
                fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                fontScale=0.8,
                color=(0, 0, 255),
                thickness=2
            )

        # 显示图像
        cv2.imshow('code', img)

        # 按下 'q' 键退出循环
        if cv2.waitKey(1) & 0xFF == ord('q'):
            self.cap.release()  # 释放摄像头资源
            cv2.destroyAllWindows()  # 关闭所有OpenCV窗口
            break
  • 读取视频帧

    • success, img = self.cap.read():读取一帧视频。success 表示是否成功读取,img 是读取到的图像。
    • 如果读取失败,打印错误信息并退出循环。
  • 检测二维码和条码

    • for bar_code in pyzbar.decode(img):使用 pyzbar.decode() 函数检测图像中的二维码和条码。
    • print(bar_code.data.decode('utf8')):打印二维码数据。
    • print(bar_code.type):打印二维码类型。
    • print(bar_code.rect):打印二维码四周边界(矩形框)。
    • print(bar_code.polygon):打印二维码多边形边框。
    • print(bar_code.quality):打印二维码质量。
    • print(bar_code.orientation):打印二维码方向。
  • 绘制二维码边界

    • points = np.array(bar_code.polygon, np.int32):将二维码多边形边框转换为 NumPy 数组。
    • points = points.reshape((-1, 1, 2)):重塑数组形状。
    • cv2.polylines(img=img, pts=[points], isClosed=True, color=(0, 0, 255), thickness=3):使用 cv2.polylines() 函数绘制多边形边框。
  • 在图像上显示二维码数据

    • cv2.putText():在图像上显示二维码数据。
    • text=bar_code.data.decode('utf8'):要显示的文本内容。
    • org=(bar_code.rect.left, bar_code.rect.top):文本的起始位置。
    • fontFace=cv2.FONT_HERSHEY_SIMPLEX:使用的字体类型。
    • fontScale=0.8:字体大小。
    • color=(0, 0, 255):文本颜色。
    • thickness=2:文本线宽。
  • 显示图像

    • cv2.imshow('code', img):显示图像。
  • 按键检测

    • if cv2.waitKey(1) & 0xFF == ord('q'):等待1毫秒,如果有按键按下,返回按键的ASCII码。ord('q') 返回字符 ‘q’ 的ASCII码。如果按键为 ‘q’,则退出循环。
    • self.cap.release():释放摄像头资源。
    • cv2.destroyAllWindows():关闭所有OpenCV窗口。
4. 主函数
if __name__ == '__main__':
    code_finder = CodeFinder()
    code_finder.run()
  • 主函数
    • if __name__ == '__main__'::确保当脚本直接运行时才执行以下代码。
    • 创建 CodeFinder 对象并调用 run 方法来启动二维码和条码检测。
总结

本文详细介绍了如何使用 OpenCV 和 Pyzbar 库在 Python 中检测并识别二维码和条码,并通过具体的代码示例展示了整个过程。通过使用 cv2.VideoCapture()pyzbar.decode()cv2.polylines()cv2.putText() 等函数,我们可以轻松地处理视频流中的二维码和条码数据。


### Python Pyzbar 库的使用方法 Pyzbar 是一个用于解码条形码二维码的纯 Python 实现。为了安装并使用 pyzbar,可以利用 pip 工具来完成: ```bash pip install pyzbar ``` 如果遇到依赖项问题,特别是当操作系统不支持预编译二进制包时,则可能需要手动安装额外的依赖库[^1]。 对于 Linux 用户来说,在某些情况下还需要预先安装 libzbar0 或者 zbar 开发工具链才能成功构建 pyzbar 扩展模块。可以通过系统的包管理器来进行安装操作,例如 Ubuntu 上执行如下命令: ```bash sudo apt-get update && sudo apt-get install -y libzbar-dev ``` 一旦完成了必要的环境准备,就可以编写简单的脚本来测试 pyzbar 的功能了。下面是一个读取图像文件中的 QR Code 并打印其内容的例子: ```python from PIL import Image from pyzbar.pyzbar import decode def read_qr_code(image_path): """Reads a QR code from an image.""" data = None try: decoded_objects = decode(Image.open(image_path)) if len(decoded_objects) > 0: first_object = decoded_objects[0] data = first_object.data.decode('utf-8') except Exception as e: print(f"Error reading QR code: {str(e)}") return data if __name__ == "__main__": result = read_qr_code("example.png") # Replace with your own path. if result is not None: print(f"The content of the QR code is '{result}'") else: print("No valid QR code found.") ``` 这段代码会尝试打开指定路径下的图片,并调用 `decode()` 函数解析其中包含的数据;如果有多个编码对象存在,默认只处理第一个找到的结果。最后将返回的内容转换成字符串形式输出给用户查看。 需要注意的是,由于 Docker 镜像更新可能导致基础镜像变化从而影响应用程序正常工作的情况,建议开发者们密切关注所使用的 Python 版本及其对应的系统配置是否兼容最新发布的容器化解决方案[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燕鹏01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值