引言
在計算機視覺領域,目標檢測與距離估算的結合是自動駕駛、機器人導航等場景的關鍵技術。本文將以YOLOv8模型為核心,結合單目相機的幾何模型,實現對視頻中目標的實時檢測與距離估算。代碼參考自單目測距原理博客,并通過實踐驗證其可行性。
環境準備
依賴庫安裝
pip install ultralytics opencv-python numpy
模型準備
- YOLOv11模型:下載預訓練模型(如
yolo11l.pt
),可通過YOLO官方文檔獲取。 - 視頻文件:準備測試視頻
1.mp4
,或使用攝像頭實時采集。
核心代碼解析
參數配置
f = 700 # 相機焦距(像素單位)
angle_a = 0 # 相機光軸與水平線的夾角(弧度)
camera_h = 1.7 # 相機離地高度(米)
參數說明:
- 焦距(f):決定圖像縮放比例,需通過相機標定獲取。
- 相機高度(camera_h):直接影響測距精度,需精確測量。
- 夾角(angle_a):若相機安裝存在俯仰角,需校準此值。
YOLOv11目標檢測
model = YOLO("F:/mot/models/YOLO11/yolo11l.pt") # 加載模型
results = model.track(frame, persist=True) # 實時檢測與追蹤
model.track()
啟用追蹤功能,支持多目標持續跟蹤。results
包含檢測框坐標、置信度、類別ID等信息。
距離估算核心邏輯
w, h = np.abs(x1-x2), np.abs(y1-y2) # 計算目標框高度
angle_b = np.arctan(h / f) # 計算像素高度對應的角度
angle_c = angle_b + angle_a # 總夾角# 兩種距離公式對比
dis1 = camera_h / np.tan(angle_c) # 簡化公式
dis2 = (camera_h / np.sin(angle_c)) * np.cos(angle_b) # 參考公式
公式對比:
- 簡化公式(dis1):基于相似三角形原理推導,計算更高效。
- 參考公式(dis2):考慮相機姿態的幾何修正,理論上更精確。
輸出示例
id:5 class: car 0.92 dis1: 12.345m dis2: 12.340m
- ID:目標追蹤ID(若未啟用追蹤則為-1)
- 類別:如car、person等
- 距離:兩種公式計算結果對比
實驗分析與優化建議
誤差來源探討
- 相機標定誤差:焦距(f)和安裝高度(camera_h)的微小偏差會顯著影響結果。
- 目標姿態假設:公式假設目標位于地平面,若目標懸浮(如無人機)會導致錯誤。
- 像素高度測量:目標框高度(h)受檢測框精度影響,建議使用目標底部特征點替代。
改進建議
- 相機標定:使用棋盤格標定工具(如OpenCV的
calibrateCamera
)獲取精準內參。 - 動態角度補償:通過IMU傳感器獲取實時相機姿態(angle_a),提升動態場景精度。
- 深度學習優化:結合目標尺寸先驗知識(如車輛平均高度)校正測距結果。
完整代碼
import cv2
from ultralytics import YOLO
import numpy as np# 相機參數配置
f = 700
angle_a = 0
camera_h = 1.7# 加載YOLO模型
model = YOLO("F:/mot/models/YOLO11/yolo11l.pt")# 視頻捕獲
video_path = "1.mp4"
cap = cv2.VideoCapture(video_path)while cap.isOpened():ret, frame = cap.read()if not ret:breakresults = model.track(frame, persist=True)for result in results:boxes = result.boxes.xyxy.cpu().numpy()confidences = result.boxes.conf.cpu().numpy()class_ids = result.boxes.cls.cpu().numpy()for box, conf, cls_id, d in zip(boxes, confidences, class_ids, result.boxes):idx = int(d.id.item()) if d.is_track else -1x1, y1, x2, y2 = map(int, box)# 距離計算h = np.abs(y1 - y2)angle_b = np.arctan(h / f)angle_c = angle_b + angle_adis1 = camera_h / np.tan(angle_c)dis2 = (camera_h / np.sin(angle_c)) * np.cos(angle_b)# 繪制標注label = f"id:{idx} {model.names[int(cls_id)]} {conf:.2f} dis1:{dis1:.2f}m dis2:{dis2:.2f}m"cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2)cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)cv2.imshow('YOLO Tracking', frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()
結語
本文通過YOLOv11實現了目標檢測與單目測距的融合應用,驗證了基于幾何模型的低成本測距方案可行性。實際部署中需注意:
- 使用專業標定工具提升參數精度;
- 針對特定場景(如車輛測距)優化目標高度先驗;
- 結合濾波算法(如卡爾曼濾波)平滑距離輸出。
后續可探索多傳感器融合(如激光雷達+視覺)進一步提升精度,或嘗試單目深度估計網絡(如MiDaS)替代傳統幾何方法。