YOLOv11结合目标检测与测距技术,通过改进YOLO架构实现实时速度与距离测量。其核心技术包括:
- 目标检测优化:采用轻量化Backbone和Neck结构提升检测速度,确保高精度识别车辆、行人等目标。
- 单目测距:基于几何原理(如相似三角形或透视变换),利用目标像素高度/位置估算实际距离,需预标定相机参数(焦距、安装高度等)。
- 速度估算:通过卡尔曼滤波或光流法跟踪目标位移,结合帧间隔时间计算瞬时速度,减少抖动误差。
- 多任务融合:端到端网络同步输出检测框、距离及速度,支持嵌入式部署(如Jetson系列),满足自动驾驶、交通监控等场景需求,帧率可达60+FPS。
该技术平衡精度与效率,适用于动态场景的实时分析。
这个错误表明names[cls]尝试访问names字典时,cls的值(tensor(2))无法直接用作键。这是因为 YOLO 返回的类别索引是 PyTorch 张量,需要先转换为 Python 整数。以下是修复方法:
修复后的代码(关键修改部分)
# 修改这一行:cls=int(box.cls[0])# 确保转换为Python整数class_name=names[cls]重要代码
importcv2importmathimporttimefromultralyticsimportYOLOfromcollectionsimportdeque# 初始化YOLO模型model=YOLO("yolov8n.pt")# 会自动下载模型(如果本地没有)names=model.names# 视频设置cap=cv2.VideoCapture("traffic.mp4")assertcap.isOpened(),"Error reading video file"w,h,fps=(int(cap.get(x))forxin(cv2.CAP_PROP_FRAME_WIDTH,cv2.CAP_PROP_FRAME_HEIGHT,cv2.CAP_PROP_FPS))# 参数配置KNOWN_WIDTH=1.8# 假设车辆宽度为1.8米(可根据实际情况调整)FOCAL_LENGTH=1200# 焦距(像素),需要根据相机标定调整LINE_Y=int(h*0.6)# 速度检测线位置(水平线)MAX_HISTORY=5# 用于速度计算的历史帧数# 存储目标历史位置track_history={}defcalculate_distance(known_width,focal_length,pixel_width):"""计算目标到相机的距离"""return(known_width*focal_length)/pixel_widthdefcalculate_speed(positions,fps,meter_per_pixel=0.05):""" 基于历史位置计算速度 :param positions: 目标的历史位置队列[(x1,y1), (x2,y2)...] :param fps: 视频帧率 :param meter_per_pixel: 像素到米的转换系数(需要标定) :return: 速度(m/s) """iflen(positions)<2:return0total_distance=0foriinrange(1,len(positions)):dx=positions[i][0]-positions[i-1][0]dy=positions[i][1]-positions[i-1][1]total_distance+=math.sqrt(dx**2+dy**2)avg_pixel_distance=total_distance/(len(positions)-1)real_distance=avg_pixel_distance*meter_per_pixel speed=real_distance*fps# m/sreturnspeed# 主处理循环whilecap.isOpened():success,frame=cap.read()ifnotsuccess:break关键修改点
修复类别索引类型:
- 将
class_ids = results[0].boxes.cls.int().cpu()改为class_ids = results[0].boxes.cls.int().cpu().tolist(),确保转换为Python列表。 - 直接使用
names[cls]访问类别名称(cls现在已是Python整数)。
- 将
其他优化:
- 统一使用
//进行整数除法(避免浮点数坐标)。 - 保持代码风格一致性(如缩进和括号对齐)。
- 统一使用
常见问题排查
如果仍然报错:
- 检查
names的内容:print(names)应输出类似{0: 'person', 1: 'car', ...}的字典。 - 确保
cls的值在names的键范围内(如YOLOv8n的默认类别是0-79)。
- 检查
速度计算不准确:
- 调整
meter_per_pixel(需要实际标定)。 - 检查
FOCAL_LENGTH和KNOWN_WIDTH是否合理。
- 调整
跟踪不稳定:
- 增加
MAX_HISTORY的值(如10)。 - 在
model.track()中调整persist=True和conf参数。
- 增加
运行修改后的代码应该能解决KeyError问题。如果还有其他错误,请提供完整的报错信息。