YOLOv8结果传入pyzbar解码报错及kraken预处理咨询
解决AttributeError问题
你用了stream=True参数,这会让model.predict()返回一个生成器对象,而非单个Results实例,直接调用.numpy()必然报错。正确做法是遍历生成器内的每个检测结果,提取YOLO识别出的目标区域,再将该区域传给pyzbar解码:
修正后的代码示例:
from ultralytics import YOLO import cv2 from pyzbar import pyzbar model = YOLO("yolov8n.pt") cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break # stream=True返回生成器,需遍历每个结果 results = model.predict(source=frame, show=True, conf=0.70, stream=True, device=0) for result in results: # 提取所有检测框坐标(xyxy格式:x1,y1,x2,y2) boxes = result.boxes.xyxy.cpu().numpy() for box in boxes: x1, y1, x2, y2 = map(int, box) # 裁剪出检测到的目标区域 roi = frame[y1:y2, x1:x2] # 转灰度图提升pyzbar识别率 gray_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) # 解码条形码 barcodes = pyzbar.decode(gray_roi) for barcode in barcodes: print(f"识别到条形码:{barcode.data.decode('utf-8')}") if cv2.waitKey(10) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
核心说明:
- 遍历生成器内的每个
result,每个result对应单帧的检测结果 - 用
result.boxes.xyxy.cpu().numpy()获取检测框坐标并转成numpy数组 - 裁剪目标区域后转灰度图,pyzbar对灰度图的识别效果更稳定
- 遍历解码结果,输出条形码内容
使用kraken.binarization.nlbin()预处理
完全可以用nlbin做预处理,它的自适应二值化能有效去除背景干扰,提升条形码清晰度,尤其适合光照不均的场景。操作步骤如下:
首先安装kraken:
pip install kraken
修改代码,在裁剪ROI后加入nlbin预处理:
from ultralytics import YOLO import cv2 from pyzbar import pyzbar from kraken.binarization import nlbin from PIL import Image import numpy as np model = YOLO("yolov8n.pt") cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break results = model.predict(source=frame, show=True, conf=0.70, stream=True, device=0) for result in results: boxes = result.boxes.xyxy.cpu().numpy() for box in boxes: x1, y1, x2, y2 = map(int, box) roi = frame[y1:y2, x1:x2] # 将cv2格式的ROI转为PIL Image(nlbin要求输入为PIL图像) pil_roi = Image.fromarray(cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)) # 用nlbin做二值化预处理 binarized_roi = nlbin(pil_roi) # 直接用二值化后的PIL图像解码(pyzbar支持PIL格式) barcodes = pyzbar.decode(binarized_roi) for barcode in barcodes: print(f"预处理后识别到条形码:{barcode.data.decode('utf-8')}") if cv2.waitKey(10) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
核心说明:
- nlbin仅接受PIL Image格式,需将cv2的BGR图像转为RGB格式的PIL图像
- 二值化后的图像为灰度PIL Image,可直接传给pyzbar的
decode()函数 - 若需显示预处理后的图像,可将其转为cv2格式:
cv2_bin_roi = cv2.cvtColor(np.array(binarized_roi), cv2.COLOR_GRAY2BGR)
内容的提问来源于stack exchange,提问作者AS400
相关产品推荐
相关产品推荐

