diff --git a/frigate/camera/state.py b/frigate/camera/state.py index 0a070cf48b..c459098f7c 100644 --- a/frigate/camera/state.py +++ b/frigate/camera/state.py @@ -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( diff --git a/frigate/ptz/autotrack.py b/frigate/ptz/autotrack.py index 3997f64551..8049b29434 100644 --- a/frigate/ptz/autotrack.py +++ b/frigate/ptz/autotrack.py @@ -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] diff --git a/frigate/test/test_ptz_autotrack.py b/frigate/test/test_ptz_autotrack.py index f93f9e367c..f06f38c702 100644 --- a/frigate/test/test_ptz_autotrack.py +++ b/frigate/test/test_ptz_autotrack.py @@ -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__":