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

Python-OpenCV中YOLO检测器报错IndexError:列表索引越界求助

解决YOLOv8自定义classNames触发IndexError的问题

问题根源

你使用的yolov8n.pt是基于COCO数据集训练的80类预训练模型,但自定义的classNames列表仅包含19个类别。当模型检测到COCO数据集中索引≥19的类别时,classNames[cls]就会因索引超出列表长度触发IndexError。此外,代码还存在缩进错误:w, h计算及后续逻辑都在for box in boxes:循环外,会导致仅处理最后一个检测框,甚至出现变量未定义的问题。


解决方案

方案1:保留预训练模型的全类别检测

将classNames替换为COCO数据集的完整80类列表(顺序必须与YOLOv8类别定义一致):

classNames = [
    "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
    "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
    "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
    "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
    "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
    "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
    "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone",
    "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear",
    "hair drier", "toothbrush"
]

方案2:仅检测自定义类别(需重新训练模型)

如果只需要检测你定义的19类,必须用自定义数据集重新训练模型:

  1. 按YOLO格式准备标注好的自定义数据集
  2. 运行训练命令:
yolo detect train data=你的数据集配置文件.yaml model=yolov8n.pt epochs=50
  1. 加载训练后的自定义模型替换原模型:
model = YOLO('训练好的模型路径/xxx.pt')

此时classNames可保留你自定义的列表,确保顺序与训练时的类别顺序一致。

修复代码缩进与额外防护

将检测框处理逻辑缩进至for box in boxes:循环内,并添加索引越界防护:

while True:
    success,  img = cap.read()
    results = model(img, stream=True)
    for r in results:
        boxes = r.boxes
        for box in boxes:
            # Bounding box
            x1, y1, x2, y2 = box.xyxy[0]
            x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
            # 计算宽高并绘制角框
            w, h = x2 - x1, y2 - y1
            cvzone.cornerRect(img, (x1, y1, w, h))
            # 置信度计算
            conf = math.ceil((box.conf[0] * 100))/100 
            # 类别索引
            cls = int(box.cls[0])
            # 避免索引越界的判断
            if cls < len(classNames):
                cvzone.putTextRect(img, f'{classNames[cls]} {conf}', (max(0, x1), max(35, y1)), scale=0.7, thickness=1)
            else:
                cvzone.putTextRect(img, f'Unknown {conf}', (max(0, x1), max(35, y1)), scale=0.7, thickness=1)
    cv2.imshow('Image', img)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break

注意:原代码中重复的cv2.waitKey(1)已合并,避免触发多次按键检测。


内容的提问来源于stack exchange,提问作者Nikita F

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:05:39