make max target box a function of zoom factor

This commit is contained in:
Josh Hawkins
2026-10-04 07:29:14 -05:00
parent ed8367e51e
commit 920e8a1c9f
3 changed files with 15 additions and 23 deletions
+3 -3
View File
@@ -16,7 +16,7 @@ from frigate.config import (
ZoomingModeEnum,
)
from frigate.const import CLIPS_DIR, THUMB_DIR
from frigate.ptz.autotrack import PtzAutoTracker
from frigate.ptz.autotrack import PtzAutoTracker, calculate_max_target_box
from frigate.track.tracked_object import TrackedObject
from frigate.util.image import (
SharedMemoryFrameManager,
@@ -134,8 +134,8 @@ class CameraState:
and self.camera_config.detect.width is not None
and self.camera_config.detect.height is not None
):
max_target_box = self.ptz_autotracker_thread.max_target_box(
self.name
max_target_box = calculate_max_target_box(
self.camera_config.onvif.autotracking.zoom_factor
)
side_length = max_target_box * (
max(
+7 -7
View File
@@ -43,6 +43,11 @@ from frigate.util.image import SharedMemoryFrameManager, intersection_over_union
logger = logging.getLogger(__name__)
def calculate_max_target_box(zoom_factor: float) -> float:
"""Return the largest target box ratio allowed for a zoom factor."""
return AUTOTRACKING_MAX_AREA_RATIO ** (1 / zoom_factor)
def ptz_moving_at_frame_time(frame_time, ptz_start_time, ptz_stop_time):
# Determine if the PTZ was in motion at the set frame time
# for non ptz/autotracking cameras, this will always return False
@@ -332,11 +337,6 @@ class PtzAutoTracker(threading.Thread):
def _reset_tracked_object_metrics(self, camera: str) -> None:
self.tracked_object_metrics[camera] = {}
def max_target_box(self, camera: str) -> float:
"""Return the largest target box ratio allowed for the zoom factor."""
zoom_factor = self.config.cameras[camera].onvif.autotracking.zoom_factor
return AUTOTRACKING_MAX_AREA_RATIO ** (1 / zoom_factor)
async def _wait_until_stopped(
self, camera: str, metrics: PTZMetrics | None = None
) -> None:
@@ -945,7 +945,7 @@ class PtzAutoTracker(threading.Thread):
camera_config = self.config.cameras[camera]
tom = self.tracked_object_metrics[camera]
zoom_factor = camera_config.onvif.autotracking.zoom_factor
max_target_box = self.max_target_box(camera)
max_target_box = calculate_max_target_box(zoom_factor)
camera_width = camera_config.frame_shape[1]
camera_height = camera_config.frame_shape[0]
camera_fps = camera_config.detect.fps
@@ -1179,7 +1179,7 @@ class PtzAutoTracker(threading.Thread):
camera_config = self.config.cameras[camera]
tom = self.tracked_object_metrics[camera]
zoom_factor = camera_config.onvif.autotracking.zoom_factor
max_target_box = self.max_target_box(camera)
max_target_box = calculate_max_target_box(zoom_factor)
# frame width and height
camera_width = camera_config.frame_shape[1]
+5 -13
View File
@@ -17,7 +17,7 @@ from unittest.mock import MagicMock
from frigate.camera import PTZMetrics
from frigate.config import FrigateConfig
from frigate.config.camera.updater import CameraConfigUpdateEnum
from frigate.ptz.autotrack import PtzAutoTracker
from frigate.ptz.autotrack import PtzAutoTracker, calculate_max_target_box
CAMERA = "ptz_cam"
@@ -123,18 +123,10 @@ class TestAutotrackerDisable(unittest.TestCase):
self.assertIs(payload, autotracking)
class TestAutotrackerMaxTargetBox(unittest.TestCase):
def test_follows_live_zoom_factor(self) -> None:
# the debug overlay and the zoom decisions both read this, so it has to
# track a zoom_factor changed while an object is being followed
tracker = _make_tracker()
autotracking = tracker.config.cameras[CAMERA].onvif.autotracking
autotracking.zoom_factor = 0.5
self.assertAlmostEqual(tracker.max_target_box(CAMERA), 0.6**2)
autotracking.zoom_factor = 0.25
self.assertAlmostEqual(tracker.max_target_box(CAMERA), 0.6**4)
class TestMaxTargetBox(unittest.TestCase):
def test_follows_zoom_factor(self) -> None:
self.assertAlmostEqual(calculate_max_target_box(0.5), 0.6**2)
self.assertAlmostEqual(calculate_max_target_box(0.25), 0.6**4)
if __name__ == "__main__":