当前位置: 首页 > article >正文

【计算机视觉】条形码与二维码识别

一、条形码简介

条形码是用可视化、机器可读的图像形式来表示信息。
一维条形码的条和空按照一定的编码规则平行排列,根据编码规则的不同,条形码分为不同类型,常见类型包括code39、code128、EAN-8、EAN-13、ISSN、ISBN、UPC等,以EAN-13类型条形码为例,它由左侧空白区、起始符、左侧数据符、前置码、底部供人识别的字符组成。
在这里插入图片描述

条形码每个数据字符由2个条和2个空构成,每一个条或者空由1~4个单位宽度组成,每个条形码数据字符的总宽度为7个单位。

二、OpenCV的条形码识别

条形码识别首先检测定位图像中的条形码,然后对检测出的条形码进行解码,得到条形码信息。

import cv2
from pyzbar.pyzbar import decode

# 加载图像
image_path = "barcode_image.jpg"  # 替换为你的图像路径
image = cv2.imread(image_path)

# 转为灰度图像(可选)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 解码条形码
barcodes = decode(gray)

# 遍历检测到的条形码
for barcode in barcodes:
    # 提取条形码的边界框坐标
    (x, y, w, h) = barcode.rect
    # 在图像上绘制矩形框
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

    # 提取条形码数据
    barcode_data = barcode.data.decode("utf-8")
    barcode_type = barcode.type

    # 在图像上显示条形码数据和类型
    text = f"{barcode_data} ({barcode_type})"
    cv2.putText(image, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

    # 打印条形码数据
    print(f"Found barcode: {barcode_data} (Type: {barcode_type})")

# 显示结果图像
cv2.imshow("Barcode Detection", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

这段代码是使用 OpenCV 和 Pyzbar 实现条形码识别的程序,下面对其进行逐行详细解释。

导入库
import cv2
from pyzbar.pyzbar import decode
  • cv2:OpenCV 是一个用于计算机视觉的开源库,用于图像处理和显示。
  • pyzbar.decodepyzbar 是一个专门用于解码条形码和二维码的 Python 库,decode 是其核心函数。
加载图像
image_path = "barcode_image.jpg"  # 替换为你的图像路径
image = cv2.imread(image_path)
  • image_path:指定条形码图片的路径。
  • cv2.imread:加载图片并存储为一个 NumPy 数组。image 是该图片的矩阵表示。
转为灰度图像(可选)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  • cv2.cvtColor:将图像从 BGR 色彩空间转换为灰度(单通道)。
  • 灰度化的好处:条形码识别对色彩信息不敏感,灰度图像可减少计算复杂性,提高效率。
解码条形码
barcodes = decode(gray)
  • decode(gray):对灰度图像进行条形码扫描。
  • 返回值barcodes 是一个列表,每个元素代表一个检测到的条形码对象,包含以下信息:
    • data:条形码的内容。
    • type:条形码的类型(如 Code128、EAN-13)。
    • rect:条形码的位置和大小(矩形)。
遍历检测到的条形码

提取边界框坐标

(x, y, w, h) = barcode.rect
  • barcode.rect:返回条形码的矩形边框,以 (x, y, w, h) 表示。
    • xy 是左上角坐标。
    • wh 是宽度和高度。
      在图像上绘制矩形框
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
  • cv2.rectangle:在图像上绘制矩形。
    • 参数 (x, y)(x + w, y + h) 定义矩形的左上角和右下角。
    • (0, 255, 0) 定义矩形的颜色(绿色,BGR 格式)。
    • 2 指定矩形边框的粗细。
提取条形码数据
barcode_data = barcode.data.decode("utf-8")
barcode_type = barcode.type
  • barcode.data:返回条形码的原始字节数据。
  • decode(“utf-8”):将字节数据解码为可读的字符串。
  • barcode.type:条形码的格式类型,如 Code128EAN-13 等。
在图像上显示条形码数据和类型
text = f"{barcode_data} ({barcode_type})"
cv2.putText(image, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
  • cv2.putText:在图像上绘制文本。
    • text 是显示的内容。
    • (x, y - 10) 确定文本位置(在矩形框上方)。
    • cv2.FONT_HERSHEY_SIMPLEX 是字体样式。
    • 0.5 是字体大小。
    • (0, 255, 0) 是文本颜色(绿色)。
    • 2 是文本线条粗细。
打印条形码数据
print(f"Found barcode: {barcode_data} (Type: {barcode_type})")
  • print:将条形码的内容和类型打印到终端。
显示结果图像
cv2.imshow("Barcode Detection", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
  1. cv2.imshow:显示图像。
    • "Barcode Detection" 是窗口标题。
    • image 是带有条形码标注的图像。
  2. cv2.waitKey(0):等待按键事件,0 表示无限等待。
  3. cv2.destroyAllWindows:关闭所有窗口。

三、二维码简介

二维码是一种高效的图形化编码技术,全称是“Quick Response Code”,简称“QR Code”。它最初由日本的公司 Denso Wave 在1994年发明,用于快速扫描和识别信息。二维码的主要特点是能以点阵方式存储大量数据,并可通过摄像头或专用扫描设备快速读取。

二维码的特点
  1. 高存储容量
    • 可存储多种类型的数据,包括文本、数字、URL、文件甚至多语言内容。
    • 一个标准二维码的最大数据容量为:
      • 数字:7089 个字符。
      • 字母数字:4296 个字符。
      • 二进制(8 位):2953 字节。
      • 汉字:1817 个字符。
  2. 高效识别
    • 使用二维矩阵编码,支持从任意角度(360°)扫描,识别速度快。
  3. 容错能力强
    • 支持 4 级容错(L、M、Q、H),可修复最多 30% 的损坏或污损。
    • 即使二维码部分损坏,仍能正确解码。
  4. 易生成、易读取
    • 使用免费工具即可生成二维码。
    • 通过智能手机摄像头或专用扫码器即可解码。
二维码的结构

二维码由以下几个主要部分组成:

  1. 定位图形
    • 位于二维码的三个角落,用于快速确定二维码的位置和方向。
  2. 校正图形
    • 主要位于中间区域,确保二维码的精确解码。
  3. 数据区域
    • 用于存储实际的编码数据。
  4. 格式信息
    • 存储二维码的纠错级别和掩码模式。
  5. 版本信息
    • 标识二维码的大小和容量(版本1到40,对应不同尺寸)。
二维码的工作原理
  1. 数据编码: 数据被转化为点阵(黑白块)的形式,按特定规则排列。
  2. 图像扫描: 使用摄像头或扫码器拍摄二维码图像。
  3. 图像处理: 设备识别二维码中的定位点,确定数据区域,并校正角度。
  4. 数据解码: 通过算法解码点阵中的数据,恢复原始信息。

四、二维码识别

二维码识别算法代码
import cv2
from pyzbar.pyzbar import decode

def recognize_qr_code(image_path):
    """
    识别图像中的二维码并返回解码信息。
    
    :param image_path: 输入图像的路径
    :return: 解码信息的列表,每个元素为一个字典,包含 'data' 和 'type'
    """
    # 读取图像
    image = cv2.imread(image_path)

    # 转为灰度图像(可选,但能提高识别效果)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 解码二维码
    qr_codes = decode(gray)

    # 用于存储解码结果
    decoded_info = []

    # 遍历识别到的二维码
    for qr_code in qr_codes:
        # 提取二维码的数据和类型
        qr_data = qr_code.data.decode('utf-8')  # 解码数据为字符串
        qr_type = qr_code.type  # 二维码类型(如 QRCODE)

        # 保存数据到结果列表
        decoded_info.append({"data": qr_data, "type": qr_type})

        # 在图像上绘制矩形框
        (x, y, w, h) = qr_code.rect
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

        # 显示解码信息
        cv2.putText(image, qr_data, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)

    # 显示标注后的图像
    cv2.imshow("QR Code Detection", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    return decoded_info


# 调用函数并打印结果
if __name__ == "__main__":
    image_path = "qrcode_image.jpg"  # 替换为你的二维码图片路径
    results = recognize_qr_code(image_path)

    if results:
        for result in results:
            print(f"Data: {result['data']}, Type: {result['type']}")
    else:
        print("No QR Code detected.")
代码解析
  1. 读取图像: 使用 OpenCV 的 cv2.imread 加载图像。
  2. 灰度处理: 将图像转为灰度以减少计算复杂性,使用 cv2.cvtColor 函数。
  3. 二维码解码: 使用 pyzbar.decode 函数检测图像中的二维码。
    • 返回一个列表,每个元素包含解码后的数据、类型和位置信息。
  4. 绘制矩形框和标注
    • 提取二维码的位置 rect,并使用 cv2.rectangle 绘制绿色框。
    • 使用 cv2.putText 在图像上标注二维码的内容。
  5. 显示结果: 使用 cv2.imshow 显示标注后的图像。
  6. 返回解码信息: 返回解码结果为一个字典列表,包含 datatype 信息。

http://www.kler.cn/a/565634.html

相关文章:

  • 边缘计算+多模态感知:户外监控核心技术解析与工程部署实践!户外摄像头监控哪种好?户外摄像头监控十大品牌!格行视精灵VS海康威视VS大华横评!
  • JavaEE [特殊字符] TCP协议:三次握手四次挥手全图解
  • python-leetcode-下一个排列
  • 基于定制开发开源AI大模型S2B2C商城小程序的商品选品策略研究
  • 单例模式---是 Spring 容器的核心特性之一
  • Oracle 导出所有表索引的创建语句
  • macos下myslq图形化工具之Sequel Ace
  • 面试基础---Spring 生态---深度剖析Spring AOP动态代理机制
  • leetcode53—最大子数组和(kadane算法)
  • 覆盖数学/代码/科学/谜题,高质量推理数据集汇总,助力复现DeepSeek超强推理能力
  • 智慧港口可视化:开启港口数字化转型的新篇章
  • 不同数据类型在数据库和编程语言之间的对应关系表
  • Wireshark Lua 插件教程
  • Tailwind CSS 4【实用教程】
  • Python PDF文件拆分-详解
  • React面试葵花宝典之二
  • 【博资考2】网安学院-北航网安基础部分(简洁版)
  • 【LeetCode347】前k个高频元素
  • CIDR转IP段:原理Java实现
  • SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则