diff --git a/frigate/config.py b/frigate/config.py index f8256c922..2894fa42a 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -46,6 +46,7 @@ from frigate.util.builtin import ( get_ffmpeg_arg_list, load_config_with_no_duplicates, ) +from frigate.util.config import get_relative_coordinates from frigate.util.image import create_mask from frigate.util.services import auto_detect_hwaccel, get_video_properties @@ -348,35 +349,7 @@ class RuntimeMotionConfig(MotionConfig): def __init__(self, **config): frame_shape = config.get("frame_shape", (1, 1)) - mask = config.get("mask", "") - - # masks and zones are saved as relative coordinates - # we know if any points are > 1 then it is using the - # old native resolution coordinates - if mask: - if isinstance(mask, list) and any(x > "1.0" for x in mask[0].split(",")): - relative_masks = [] - for m in mask: - points = m.split(",") - relative_masks.append( - ",".join( - [ - f"{round(int(points[i]) / frame_shape[1], 3)},{round(int(points[i + 1]) / frame_shape[0], 3)}" - for i in range(0, len(points), 2) - ] - ) - ) - - mask = relative_masks - elif isinstance(mask, str) and any(x > "1.0" for x in mask.split(",")): - points = mask.split(",") - mask = ",".join( - [ - f"{round(int(points[i]) / frame_shape[1], 3)},{round(int(points[i + 1]) / frame_shape[0], 3)}" - for i in range(0, len(points), 2) - ] - ) - + mask = get_relative_coordinates(config.get("mask", ""), frame_shape) config["raw_mask"] = mask if mask: @@ -508,34 +481,7 @@ class RuntimeFilterConfig(FilterConfig): def __init__(self, **config): frame_shape = config.get("frame_shape", (1, 1)) - mask = config.get("mask") - - # masks and zones are saved as relative coordinates - # we know if any points are > 1 then it is using the - # old native resolution coordinates - if mask: - if isinstance(mask, list) and any(x > "1.0" for x in mask[0].split(",")): - relative_masks = [] - for m in mask: - points = m.split(",") - relative_masks.append( - ",".join( - [ - f"{round(int(points[i]) / frame_shape[1], 3)},{round(int(points[i + 1]) / frame_shape[0], 3)}" - for i in range(0, len(points), 2) - ] - ) - ) - - mask = relative_masks - elif isinstance(mask, str) and any(x > "1.0" for x in mask.split(",")): - points = mask.split(",") - mask = ",".join( - [ - f"{round(int(points[i]) / frame_shape[1], 3)},{round(int(points[i + 1]) / frame_shape[0], 3)}" - for i in range(0, len(points), 2) - ] - ) + mask = get_relative_coordinates(config.get("mask"), frame_shape) config["raw_mask"] = mask @@ -1234,11 +1180,15 @@ def verify_zone_objects_are_tracked(camera_config: CameraConfig) -> None: def verify_required_zones_exist(camera_config: CameraConfig) -> None: for det_zone in camera_config.review.detections.required_zones: if det_zone not in camera_config.zones.keys(): - raise ValueError(f"Camera {camera_config.name} has a required zone for detections {det_zone} that is not defined.") + raise ValueError( + f"Camera {camera_config.name} has a required zone for detections {det_zone} that is not defined." + ) for det_zone in camera_config.review.alerts.required_zones: if det_zone not in camera_config.zones.keys(): - raise ValueError(f"Camera {camera_config.name} has a required zone for alerts {det_zone} that is not defined.") + raise ValueError( + f"Camera {camera_config.name} has a required zone for alerts {det_zone} that is not defined." + ) def verify_autotrack_zones(camera_config: CameraConfig) -> ValueError | None: @@ -1466,9 +1416,15 @@ class FrigateConfig(FrigateBaseModel): else [filter.mask] ) object_mask = ( - camera_config.objects.mask - if isinstance(camera_config.objects.mask, list) - else [camera_config.objects.mask] + get_relative_coordinates( + ( + camera_config.objects.mask + if isinstance(camera_config.objects.mask, list) + else [camera_config.objects.mask] + ), + camera_config.frame_shape, + ) + or [] ) filter.mask = filter_mask + object_mask diff --git a/frigate/util/config.py b/frigate/util/config.py index fb7aa3ef5..520a5f975 100644 --- a/frigate/util/config.py +++ b/frigate/util/config.py @@ -3,6 +3,7 @@ import logging import os import shutil +from typing import Optional, Union from ruamel.yaml import YAML @@ -131,3 +132,38 @@ def migrate_014(config: dict[str, dict[str, any]]) -> dict[str, dict[str, any]]: new_config["cameras"][name] = camera_config return new_config + + +def get_relative_coordinates( + mask: Optional[Union[str, list]], frame_shape: tuple[int, int] +) -> Union[str, list]: + # masks and zones are saved as relative coordinates + # we know if any points are > 1 then it is using the + # old native resolution coordinates + if mask: + if isinstance(mask, list) and any(x > "1.0" for x in mask[0].split(",")): + relative_masks = [] + for m in mask: + points = m.split(",") + relative_masks.append( + ",".join( + [ + f"{round(int(points[i]) / frame_shape[1], 3)},{round(int(points[i + 1]) / frame_shape[0], 3)}" + for i in range(0, len(points), 2) + ] + ) + ) + + mask = relative_masks + elif isinstance(mask, str) and any(x > "1.0" for x in mask.split(",")): + points = mask.split(",") + mask = ",".join( + [ + f"{round(int(points[i]) / frame_shape[1], 3)},{round(int(points[i + 1]) / frame_shape[0], 3)}" + for i in range(0, len(points), 2) + ] + ) + + return mask + + return None