YOLOv8实时车辆检测程序崩溃排查:IndexError问题分析
问题分析与解决
崩溃原因
你遇到的IndexError核心原因是错误的二次索引操作:
model(frame, agnostic_nms=True)返回的是包含单个Results对象的列表,你已经通过[0]取出了这个对象赋值给results。- 但后续创建
Detections时,你又对results做了results[0]的索引,当画面中没有检测目标时,这个操作会触发“索引越界”——因为Results对象本身不是可索引的数组,没有元素可供访问。
另外你的代码还缺少对目标类别的过滤,会把YOLOv8检测到的所有类别都纳入处理,不符合你只检测车辆的需求。
修正后的完整代码
import cv2 import argparse import pandas as pd from ultralytics import YOLO import supervision as sv import numpy as np from supervision.tools.detections import Detections, BoxAnnotator from supervision.tools.line_counter import LineCounter, LineCounterAnnotator from supervision.draw.color import ColorPalette from supervision import * def parse_arguments() -> argparse.Namespace: parser = argparse.ArgumentParser(description="YOLOv8 live") parser.add_argument( "--webcam-resolution", default=[1280, 720], nargs=2, type=int ) args = parser.parse_args() return args def main(): args = parse_arguments() frame_width, frame_height = args.webcam_resolution cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height) model = YOLO("yolov8l.pt") # dict mapping class_id to class_name CLASS_NAMES_DICT = model.model.names # class_ids of interest - car, motorcycle, bus, truck, bicycle CLASS_ID = [2, 3, 5, 7, 9] box_annotator = BoxAnnotator( color= ColorPalette(), thickness=2, text_thickness=2, text_scale=1 ) while True: ret, frame = cap.read() if not ret: break # 处理摄像头读取失败的情况 results = model(frame, agnostic_nms=True)[0] # 直接使用results,不再做二次索引 detections = Detections( xyxy=results.boxes.xyxy.cpu().numpy(), confidence=results.boxes.conf.cpu().numpy(), class_id=results.boxes.cls.cpu().numpy().astype(int) ) # 过滤出感兴趣的车辆类别 detections = detections[np.isin(detections.class_id, CLASS_ID)] labels = [ f"{CLASS_NAMES_DICT[class_id]} {confidence:0.2f}" for _, confidence, class_id, _ in detections ] frame = box_annotator.annotate( frame=frame, detections=detections, labels=labels ) cv2.imshow("yolov8", frame) if (cv2.waitKey(20) & 0xFF == ord('d')): break cap.release() cv2.destroyAllWindows() # 程序结束时释放资源 if __name__ == "__main__": main()
关键修改点
- 移除错误的二次索引:将
results[0].boxes改为results.boxes,避免无检测目标时的索引越界。 - 添加类别过滤:用
np.isin筛选出你需要的车辆类别(car、motorcycle等),只处理目标类别。 - 添加摄像头读取失败处理:当
cap.read()返回False时直接跳出循环,避免后续处理空帧。 - 释放资源:程序结束时调用
cap.release()和cv2.destroyAllWindows(),避免资源泄漏。
内容的提问来源于stack exchange,提问作者Surya
相关产品推荐
相关产品推荐

