mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-11-02 11:50:31 +03:00
Autotracking improvements and fixes (#24633)
CI / AMD64 Build (push) Canceled after 0s
CI / AMD64 Smoke Test (push) Canceled after 0s
CI / ARM Build (push) Canceled after 0s
CI / Jetson Jetpack 6 (push) Canceled after 0s
CI / AMD64 Extra Build (push) Canceled after 0s
CI / ARM Extra Build (push) Canceled after 0s
CI / Synaptics Build (push) Canceled after 0s
CI / Assemble and push default build (push) Canceled after 0s
CI / AMD64 Build (push) Canceled after 0s
CI / AMD64 Smoke Test (push) Canceled after 0s
CI / ARM Build (push) Canceled after 0s
CI / Jetson Jetpack 6 (push) Canceled after 0s
CI / AMD64 Extra Build (push) Canceled after 0s
CI / ARM Extra Build (push) Canceled after 0s
CI / Synaptics Build (push) Canceled after 0s
CI / Assemble and push default build (push) Canceled after 0s
* fix autotracking tracker selection and crop before histogram conversion - Rebuild the norfair trackers when an onvif save changes autotracking enabled_in_config or the PTZ-tracked labels. The trackers were only built at startup, so disabling autotracking or removing person from its track list in the UI made get_tracker pick a tracker that didn't exist, and the KeyError killed the camera process until restart. Saves that leave the selection alone, and runtime MQTT toggles, don't touch tracking. - get_tracker now returns the default tracker that match_and_update actually feeds. On autotracking cameras it returned the static default for labels without their own tracker, so register missed the norfair object and lost the pre-initialization score history, and deregister pruned the wrong tracker. - get_histogram crops the box out of each I420 plane before converting to BGR instead of converting the whole frame. It runs per detection per frame on autotracking cameras and now costs about 0.2 ms at any resolution, down from 1 ms at 1080p and 5 ms at 4K. * don't rebuild trackers for track list edits while autotracking is disabled
This commit is contained in:
+36
-3
@@ -1241,9 +1241,42 @@ def get_image_from_recording(
|
||||
return image_data
|
||||
|
||||
|
||||
def get_histogram(image, x_min, y_min, x_max, y_max):
|
||||
image_bgr = cv2.cvtColor(image, cv2.COLOR_YUV2BGR_I420)
|
||||
image_bgr = image_bgr[y_min:y_max, x_min:x_max]
|
||||
def get_histogram(
|
||||
image: np.ndarray, x_min: int, y_min: int, x_max: int, y_max: int
|
||||
) -> np.ndarray:
|
||||
"""Return a normalized 8x8x8 BGR histogram of a box in an I420 frame.
|
||||
|
||||
The box is cropped from each YUV plane before color conversion, so the
|
||||
cost depends on the box size rather than the frame size. Box edges are
|
||||
widened to even coordinates to keep chroma alignment.
|
||||
"""
|
||||
height = image.shape[0] * 2 // 3
|
||||
width = image.shape[1]
|
||||
x_min = max(0, x_min // 2 * 2)
|
||||
y_min = max(0, y_min // 2 * 2)
|
||||
x_max = min(width, (x_max + 1) // 2 * 2)
|
||||
y_max = min(height, (y_max + 1) // 2 * 2)
|
||||
|
||||
if x_max - x_min < 2 or y_max - y_min < 2:
|
||||
return np.zeros(512, np.float32)
|
||||
|
||||
flat = image.reshape(-1)
|
||||
y_size = height * width
|
||||
uv_size = y_size // 4
|
||||
y_plane = flat[:y_size].reshape(height, width)
|
||||
u_plane = flat[y_size : y_size + uv_size].reshape(height // 2, width // 2)
|
||||
v_plane = flat[y_size + uv_size : y_size + 2 * uv_size].reshape(
|
||||
height // 2, width // 2
|
||||
)
|
||||
|
||||
crop = np.concatenate(
|
||||
(
|
||||
y_plane[y_min:y_max, x_min:x_max].ravel(),
|
||||
u_plane[y_min // 2 : y_max // 2, x_min // 2 : x_max // 2].ravel(),
|
||||
v_plane[y_min // 2 : y_max // 2, x_min // 2 : x_max // 2].ravel(),
|
||||
)
|
||||
).reshape((y_max - y_min) * 3 // 2, x_max - x_min)
|
||||
image_bgr = cv2.cvtColor(crop, cv2.COLOR_YUV2BGR_I420)
|
||||
|
||||
hist = cv2.calcHist(
|
||||
[image_bgr], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256]
|
||||
|
||||
Reference in New Issue
Block a user