基于OpenCV与YOLOv5的行人检测计数程序报错求助
解决实时行人检测中的张量索引错误
错误原因分析
你遇到的IndexError是因为output的结构和预期不符——output[0]是一维张量,不存在'boxes'这个键。这种情况通常是模型推理输出格式匹配错误导致的,比如误用了不同检测模型的输出解析逻辑,或是推理时未正确处理模型返回值。
针对性解决方案
1. 匹配模型类型调整解析逻辑
若使用PyTorch官方检测模型(Faster RCNN/SSD等)
这类模型要求输入是列表格式的张量(单张图也要包装成列表),输出才会是包含'boxes'、'labels'键的字典列表。检查你的推理代码:
# 错误写法:直接传入单张量 output = model(img_tensor) # 正确写法:将单张量包装为列表 output = model([img_tensor])
修正后output[0]['boxes']即可正常访问。
若使用YOLO系列模型(YOLOv5/YOLOv8等)
YOLO输出是纯张量,没有'boxes'键,需用模型自带的解析方式。以YOLOv8为例:
results = model(frame) # 过滤出行人类别(COCO数据集行人ID为0),统计数量 person_boxes = results.xyxy[0][results.xyxy[0][:, 5] == 0] person_count = len(person_boxes)
2. 调试输出结构
若不确定模型输出格式,先打印结构信息明确解析方式:
print(type(output)) # 列表格式则打印键,张量格式打印形状 if isinstance(output, list): print(output[0].keys()) else: print(output.shape)
3. 可运行的实时检测示例(Faster RCNN版)
import torch import torchvision from torchvision.models.detection.faster_rcnn import FastRCNNPredictor import cv2 # 加载预训练Faster RCNN模型,适配COCO分类(含行人) model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True) num_classes = 90 in_features = model.roi_heads.box_predictor.cls_score.in_features model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes) model.eval() # 初始化摄像头(本地传0,网络摄像头传对应URL) cap = cv2.VideoCapture(0) # 图像预处理 def preprocess(frame): img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) img_tensor = torch.tensor(img).permute(2, 0, 1).float() / 255.0 return [img_tensor] # 必须包装为列表 while cap.isOpened(): ret, frame = cap.read() if not ret: break # 推理(关闭梯度计算节省资源) with torch.no_grad(): outputs = model(preprocess(frame)) # 过滤行人(COCO中行人label为1,置信度>0.5) boxes = outputs[0]['boxes'] scores = outputs[0]['scores'] labels = outputs[0]['labels'] person_indices = torch.where((labels == 1) & (scores > 0.5))[0] person_count = len(person_indices) # 绘制检测框和人数 for idx in person_indices: box = boxes[idx].numpy().astype(int) cv2.rectangle(frame, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2) cv2.putText(frame, f"Person Count: {person_count}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow('Pedestrian Detection', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
关键注意点
- 不同模型输出格式差异极大,需严格对应官方文档解析。
- 实时检测必须用
torch.no_grad()关闭梯度计算,避免内存泄漏。 - 添加置信度过滤可有效减少误检。
内容的提问来源于stack exchange,提问作者hal0cline
相关产品推荐
相关产品推荐

