From d263026ab4882bbb7fc71d7b1e4608eeefb93082 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sun, 8 Dec 2024 12:01:58 -0600 Subject: [PATCH] remove line sorting --- frigate/util/velocity.py | 51 +++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/frigate/util/velocity.py b/frigate/util/velocity.py index 96f342d17..276c9815c 100644 --- a/frigate/util/velocity.py +++ b/frigate/util/velocity.py @@ -8,35 +8,27 @@ magnitude = "mph" def create_ground_plane(zone_points, distances): """ - Create a ground plane that accounts for perspective distortion using - real-world dimensions for each side of the zone. + Create a ground plane that accounts for perspective distortion using real-world dimensions for each side of the zone. - :param zone_points: Array of zone corner points in pixel coordinates + :param zone_points: Array of zone corner points in pixel coordinates in circular order [[x1, y1], [x2, y2], [x3, y3], [x4, y4]] - :param distances: Real-world dimensions ordered by top, bottom left, right + :param distances: Real-world dimensions ordered by A, B, C, D :return: Function that calculates real-world distance per pixel at any coordinate """ - # Sort points by y coordinate to get top and bottom lines - sorted_points = zone_points[np.argsort(zone_points[:, 1])] - top_width, bottom_width, left_depth, right_depth = map(float, distances) - - top_line = sorted_points[:2] - bottom_line = sorted_points[2:] - - # Sort left to right for consistent indexing - top_line = top_line[np.argsort(top_line[:, 0])] - bottom_line = bottom_line[np.argsort(bottom_line[:, 0])] + A, B, C, D = zone_points # Calculate pixel lengths of each side - top_width_px = np.linalg.norm(top_line[1] - top_line[0]) - bottom_width_px = np.linalg.norm(bottom_line[1] - bottom_line[0]) - left_depth_px = np.linalg.norm(bottom_line[0] - top_line[0]) - right_depth_px = np.linalg.norm(bottom_line[1] - top_line[1]) + AB_px = np.linalg.norm(np.array(B) - np.array(A)) + BC_px = np.linalg.norm(np.array(C) - np.array(B)) + CD_px = np.linalg.norm(np.array(D) - np.array(C)) + DA_px = np.linalg.norm(np.array(A) - np.array(D)) - top_scale = top_width / top_width_px - bottom_scale = bottom_width / bottom_width_px - left_scale = left_depth / left_depth_px - right_scale = right_depth / right_depth_px + AB, BC, CD, DA = map(float, distances) + + AB_scale = AB / AB_px + BC_scale = BC / BC_px + CD_scale = CD / CD_px + DA_scale = DA / DA_px def distance_per_pixel(x, y): """ @@ -47,15 +39,15 @@ def create_ground_plane(zone_points, distances): :return: Real-world distance per pixel at the given (x, y) coordinate """ # Normalize x and y within the zone - x_norm = (x - top_line[0][0]) / (top_line[1][0] - top_line[0][0]) - y_norm = (y - top_line[0][1]) / (bottom_line[0][1] - top_line[0][1]) + x_norm = (x - A[0]) / (B[0] - A[0]) + y_norm = (y - A[1]) / (D[1] - A[1]) # Interpolate scales horizontally and vertically - top_to_bottom_scale = top_scale + (bottom_scale - top_scale) * y_norm - left_to_right_scale = left_scale + (right_scale - left_scale) * x_norm + vertical_scale = AB_scale + (CD_scale - AB_scale) * y_norm + horizontal_scale = DA_scale + (BC_scale - DA_scale) * x_norm # Combine horizontal and vertical scales - return (top_to_bottom_scale + left_to_right_scale) / 2 + return (vertical_scale + horizontal_scale) / 2 return distance_per_pixel @@ -72,11 +64,10 @@ def calculate_real_world_speed( directly from the zone string. :param zone_contour: Array of absolute zone points - :param distances: Comma separated distances of each side, ordered by top, bottom, left, right + :param distances: Comma separated distances of each side, ordered by A, B, C, D :param velocity_pixels: List of tuples representing velocity in pixels/frame :param position: Current position of the object (x, y) in pixels - :param camera_width: Width of the camera frame in pixels - :param camera_height: Height of the camera frame in pixels + :param camera_fps: Frames per second of the camera :return: speed in the specified unit system (m/s for metric, ft/s for imperial) and velocity direction """ ground_plane = create_ground_plane(zone_contour, distances)