如何解决YOLO v8处理视频时无法绘制车辆检测框的问题
问题:YOLOv8视频检测无框显示,检测输出正常
我使用YOLOv8开展项目,任务是识别车辆轮廓(以矩形框展示),并统计穿过画面中线的对向、同向车道车辆数量,最终汇总总数,需逐帧处理视频。目前检测输出正常,但视频画面未显示车辆轮廓,已尝试多种方法仍未解决。
检测输出示例
0: 384x640 27 cars, 1 truck, 1 tv, 93.0ms Speed: 1.9ms preprocess, 93.0ms inference, 0.4ms postprocess per image at shape (1, 3, 384, 640) 0: 384x640 26 cars, 2 trucks, 88.1ms Speed: 1.7ms preprocess, 88.1ms inference, 0.5ms postprocess per image at shape (1, 3, 384, 640) 0: 384x640 26 cars, 2 trucks, 104.2ms Speed: 1.5ms preprocess, 104.2ms inference, 0.6ms postprocess per image at shape (1, 3, 384, 640)
当前代码
import cv2 from ultralytics import YOLO model = YOLO('yolov8s.pt') video_path = 'output2.avi' video = cv2.VideoCapture(video_path) if not video.isOpened(): print("错误:无法打开视频。") exit() current_frame = 0 while True: ret, frame = video.read() if not ret: break current_frame += 1 results = model(frame) car_results = [detection for detection in results if detection[-1] in [2, 5, 7]] for result in car_results: x1, y1, x2, y2, confidence, class_id = result.xyxy[0] x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break video.release() cv2.destroyAllWindows()
问题分析与修复
核心问题是YOLOv8的results对象结构处理错误:
model(frame)返回的是Results对象列表,每个元素对应单帧检测结果,不能直接遍历results取detection[-1]- 正确做法是先获取单帧的
Results对象,再通过boxes属性提取检测框信息
修复后的代码如下:
import cv2 from ultralytics import YOLO model = YOLO('yolov8s.pt') video_path = 'output2.avi' video = cv2.VideoCapture(video_path) if not video.isOpened(): print("错误:无法打开视频。") exit() current_frame = 0 while True: ret, frame = video.read() if not ret: break current_frame += 1 # 获取当前帧的检测结果对象(YOLOv8返回列表,取第一个元素) results = model(frame)[0] # 过滤车辆类(2=轿车、5=巴士、7=卡车) for box in results.boxes: class_id = int(box.cls[0]) if class_id in [2, 5, 7]: # 提取框坐标并转为整数 x1, y1, x2, y2 = map(int, box.xyxy[0]) # 绘制红色矩形框 cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break video.release() cv2.destroyAllWindows()
关键修改点
- 将
results = model(frame)改为results = model(frame)[0],明确获取当前帧的检测结果对象 - 通过
results.boxes遍历所有检测框,替代原错误的遍历逻辑 - 用
box.cls[0]获取类别ID、box.xyxy[0]获取框坐标,符合YOLOv8的API规范
内容的提问来源于stack exchange,提问作者Kkbehx
相关产品推荐
相关产品推荐

