python读取二维码(cv+pyzbar)

在处理图像任务时获取遇到二维码识别处理。其基本流程包括图像预处理、选择合适的功能包执行此类功能。由于实际情况的千差万异,对于预处理的措施上应该有不同的处理方式。本文提供了一种思维方式,核心在于:使用了 concurrent.futures.ThreadPoolExecutor 来并行处理图像的预处理和二维码任务。

以下是代码集合:

import time
import cv2
from pyzbar import pyzbar
import numpy as np
import os
from concurrent.futures import ThreadPoolExecutor
import sys

# 抑制 pyzbar 的警告
stderr = sys.stderr
sys.stderr = open(os.devnull, 'w')

def preprocess_image(image, scale_factor, blur_size, adaptive_thresh_blocksize, adaptive_thresh_C, median_blur_ksize):
    if median_blur_ksize % 2 == 0:
        raise ValueError("median_blur_ksize must be an odd number")

    # 放大图像
    width = int(image.shape[1] * scale_factor)
    height = int(image.shape[0] * scale_factor)
    dim = (width, height)
    resized_image = cv2.resize(image, dim, interpolation=cv2.INTER_LINEAR)

    # 将图像转换为灰度图像
    gray_image = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)

    # 应用中值滤波
    median_filtered_image = cv2.medianBlur(gray_image, median_blur_ksize)

    # 应用高斯模糊
    blurred_image = cv2.GaussianBlur(median_filtered_image, (blur_size, blur_size), 0)

    # 应用自适应阈值处理
    adaptive_thresh_image = cv2.adaptiveThreshold(blurred_image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, adaptive_thresh_blocksize, adaptive_thresh_C)

    # 应用直方图均衡化
    equalized_image = cv2.equalizeHist(adaptive_thresh_image)

    # 应用CLAHE
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    clahe_image = clahe.apply(adaptive_thresh_image)

    return resized_image, [gray_image, blurred_image, adaptive_thresh_image, equalized_image, clahe_image]

def decode_qr_codes(images):
    decoded_objects = []
    for image in images:
        decoded_objects += pyzbar.decode(image)
    return decoded_objects

def decode_and_draw_qr_codes(image_path, output_path):
    # 检查图像文件是否存在
    if not os.path.exists(image_path):
        print(f"文件路径不存在: {image_path}")
        return 0, None

    # 读取图像
    image = cv2.imread(image_path)

    # 检查图像是否读取成功
    if image is None:
        print(f"无法读取图像: {image_path}")
        return 0, None

    all_decoded_objects = []
    scale_factor = 3  # 统一放大倍数
    resized_image = cv2.resize(image, (int(image.shape[1] * scale_factor), int(image.shape[0] * scale_factor)), interpolation=cv2.INTER_LINEAR)

    # 尝试不同的预处理组合
    preproc_params = [
        # 参数声明 高斯模糊: , 自适应阈值块大小: , 自适应阈值常数: , 中值滤波核大小:
        (5, 15, 10, 5),   # 参数组合 1
        (7, 15, 2, 5),    # 参数组合 2
        (5, 11, 2, 7),    # 参数组合 3
        (9, 15, 2, 5),    # 参数组合 4
        # 可以添加更多组合
    ]

    results = []

    with ThreadPoolExecutor() as executor:
        futures = []
        for idx, (blur_size, adaptive_thresh_blocksize, adaptive_thresh_C, median_blur_ksize) in enumerate(preproc_params):
            futures.append(executor.submit(preprocess_image, resized_image, 1, blur_size, adaptive_thresh_blocksize, adaptive_thresh_C, median_blur_ksize))

        for idx, future in enumerate(futures):
            _, processed_images = future.result()
            decoded_objects = decode_qr_codes(processed_images)
            num_decoded = len(decoded_objects)
            results.append((num_decoded, preproc_params[idx], decoded_objects))
            if decoded_objects:
                all_decoded_objects.extend(decoded_objects)

    # 按检测效果排序结果
    results.sort(key=lambda x: x[0], reverse=True)

    # 打印所有参数组合及其对应的检测结果
    for rank, result in enumerate(results):
        print(f"第{rank + 1}佳参数组合: 高斯模糊: {result[1][0]}, 自适应阈值块大小: {result[1][1]}, 自适应阈值常数: {result[1][2]}, 中值滤波核大小: {result[1][3]}, 检测到的二维码数量: {result[0]}")

    if not all_decoded_objects:
        print("未检测到二维码")
        return 0, None

    # 去重解码结果
    unique_data = {}
    for obj in all_decoded_objects:
        data = obj.data.decode("utf-8")
        if data not in unique_data:
            unique_data[data] = obj

    # 打印解码的二维码数据并在图像上绘制矩形框
    qr_code_count = 0
    decoded_data = None
    for data, obj in unique_data.items():
        qr_code_count += 1
        print("类型:", obj.type)
        print("数据:", data)
        print("位置:", obj.rect)

        # 获取二维码的四个角点
        points = obj.polygon
        if len(points) == 4:
            # 将角点转换为 NumPy 数组
            pts = np.array(points, dtype=np.int32)
            # 在图像上绘制多边形
            cv2.polylines(resized_image, [pts], isClosed=True, color=(0, 255, 0), thickness=3)
        else:
            # 如果角点数目不是 4,绘制矩形
            (x, y, w, h) = obj.rect
            cv2.rectangle(resized_image, (x, y), (x + w, y + h), (0, 255, 0), 3)

        decoded_data = data  # 获取解码的数据

    # 打印二维码的总数
    print(f"检测到 {qr_code_count} 个二维码")

    # 在图像上显示二维码总数
    cv2.putText(resized_image, f"QR Codes: {qr_code_count}", (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)

    # 保存带有二维码框的图像
    if qr_code_count == 1:
        cv2.imwrite(output_path, resized_image)
        print(f"带有二维码框的图像已保存到: {output_path}")

    print(qr_code_count, decoded_data,"qr_code_count, decoded_data")
    return qr_code_count, decoded_data

if __name__ == "__main__":
    s = time.time()
    # 输入图像路径
    image_path = r"你图片地址"
    # 输出图像路径
    output_path = r"你输出地址"
    a, b = decode_and_draw_qr_codes(image_path, output_path)
    print("处理时间:", time.time() - s)
    print(a,b)

# 恢复 stderr
sys.stderr = stderr

结果展示。仅供参考!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值