You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:50:28