本文共 3211 字,大约阅读时间需要 10 分钟。
本文将介绍如何通过 OpenCV 和 YOLOv8 模型结合 BYTETrack 实现车辆速度估计。文章将详细介绍从目标检测到目标跟踪再到速度估计的完整流程,并提供实际代码示例。
您是否想过如何利用计算机视觉技术来估计车辆的速度?本文将引导您完成从目标检测到目标跟踪再到速度估计的完整流程。
目标检测是车辆速度估计的第一步。我们需要对视频中的每一帧运行目标检测模型。在本文中,我们选择使用 YOLOv8 模型。以下是实现代码示例:
import supervision as svfrom inference.models.utils import get_roboflow_modelmodel = get_roboflow_model('yolov8x-640')frame_generator = sv.get_video_frames_generator('vehicles.mp4')bounding_box_annotator = sv.BoundingBoxAnnotator()for frame in frame_generator: results = model.infer(frame)[0] detections = sv.Detections.from_inference(results) annotated_frame = bounding_box_annotator.annotate( scene=frame.copy(), detections=detections) 仅进行目标检测不足以完成速度估计。为了追踪同一辆车在视频中的位置,我们需要使用目标跟踪算法。在本文中,我们选择使用 BYTETrack 这个高效的目标跟踪模型。以下是实现代码示例:
byte_track = sv.ByteTrack()for frame in frame_generator: results = model.infer(frame)[0] detections = sv.Detections.from_inference(results) detections = byte_track.update_with_detections(detections=detections)
车速估计是整个流程的核心。传统的方法是根据目标框的坐标直接计算距离,但由于透视变换的影响,这种方法不够准确。以下是我们使用 OpenCV 和数学实现的透视变换方法。
为了消除透视变换带来的失真,我们需要将图像坐标转换为实际道路坐标。我们通过以下步骤实现这一目标:
定义变换矩阵:使用 OpenCV 的 getPerspectiveTransform 函数创建变换矩阵。该函数需要定义源感兴趣区域和目标感兴趣区域。
变换坐标点:将检测到的目标框坐标通过变换矩阵转换为实际道路坐标。
以下是实现代码示例:
class ViewTransformer: def __init__(self, source: np.ndarray, target: np.ndarray): self.m = cv2.getPerspectiveTransform(source, target) def transform_points(self, points: np.ndarray) -> np.ndarray: if points.size == 0: return points reshaped_points = points.reshape(-1, 1, 2).astype(np.float32) transformed_points = cv2.perspectiveTransform(reshaped_points, self.m) return transformed_points.reshape(-1, 2)view_transformer = ViewTransformer( np.array([[1252, 787], [2298, 803], [5039, 2159], [-550, 2159]]), np.array([[0, 0], [24, 0], [24, 249], [0, 249]]))
为了更准确地估计车速,我们需要:
以下是实现代码示例:
video_info = sv.VideoInfo.from_video_path('vehicles.mp4')coordinates = defaultdict(lambda: deque(maxlen=video_info.fps))for frame in frame_generator: result = model.infer(frame)[0] detections = sv.Detections.from_ultralytics(result) detections = byte_track.update_with_detections(detections=detections) points = detections.get_anchors_coordinates(anchor=sv.Position.BOTTOM_CENTER) points = view_transformer.transform_points(points).astype(int) for tracker_id, [_, y] in zip(detections.tracker_id, points): coordinates[tracker_id].append(y) for tracker_id in detections.tracker_id: if len(coordinates[tracker_id]) > video_info.fps / 2: coordinate_start = coordinates[tracker_id][-1] coordinate_end = coordinates[tracker_id][0] distance = abs(coordinate_start - coordinate_end) time = len(coordinates[tracker_id]) / video_info.fps speed = distance / time * 3.6 # 将速度存储在结果中 在实际应用中,车速估计需要考虑以下因素:
通过 OpenCV 和 YOLOv8 模型结合 BYTETrack,我们成功实现了车辆速度估计。该方法不仅简单易实现,还能够在实际场景中获得较高的准确性。希望本文对您有所帮助,欢迎在评论区留言交流!
转载地址:http://ursfk.baihongyu.com/