在处理图像任务时获取遇到二维码识别处理。其基本流程包括图像预处理、选择合适的功能包执行此类功能。由于实际情况的千差万异,对于预处理的措施上应该有不同的处理方式。本文提供了一种思维方式,核心在于:使用了 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
结果展示。仅供参考!