Object area debugging and improvements (#16432)

* add ability to specify min and max area as percentages

* debug draw area and ratio

* docs

* update for best percentage
This commit is contained in:
Josh Hawkins
2025-02-09 14:48:23 -07:00
committed by GitHub
parent 83beacf84a
commit c8cec63cb9
8 changed files with 352 additions and 21 deletions
+6 -4
View File
@@ -11,11 +11,13 @@ DEFAULT_TRACKED_OBJECTS = ["person"]
class FilterConfig(FrigateBaseModel):
min_area: int = Field(
default=0, title="Minimum area of bounding box for object to be counted."
min_area: Union[int, float] = Field(
default=0,
title="Minimum area of bounding box for object to be counted. Can be pixels (int) or percentage (float between 0.000001 and 0.99).",
)
max_area: int = Field(
default=24000000, title="Maximum area of bounding box for object to be counted."
max_area: Union[int, float] = Field(
default=24000000,
title="Maximum area of bounding box for object to be counted. Can be pixels (int) or percentage (float between 0.000001 and 0.99).",
)
min_ratio: float = Field(
default=0,
+8
View File
@@ -29,6 +29,7 @@ from frigate.util.builtin import (
)
from frigate.util.config import (
StreamInfoRetriever,
convert_area_to_pixels,
find_config_file,
get_relative_coordinates,
migrate_frigate_config,
@@ -148,6 +149,13 @@ class RuntimeFilterConfig(FilterConfig):
if mask is not None:
config["mask"] = create_mask(frame_shape, mask)
# Convert min_area and max_area to pixels if they're percentages
if "min_area" in config:
config["min_area"] = convert_area_to_pixels(config["min_area"], frame_shape)
if "max_area" in config:
config["max_area"] = convert_area_to_pixels(config["max_area"], frame_shape)
super().__init__(**config)
def dict(self, **kwargs):
+30
View File
@@ -347,6 +347,36 @@ def get_relative_coordinates(
return mask
def convert_area_to_pixels(
area_value: Union[int, float], frame_shape: tuple[int, int]
) -> int:
"""
Convert area specification to pixels.
Args:
area_value: Area value (pixels or percentage)
frame_shape: Tuple of (height, width) for the frame
Returns:
Area in pixels
"""
# If already an integer, assume it's in pixels
if isinstance(area_value, int):
return area_value
# Check if it's a percentage
if isinstance(area_value, float):
if 0.000001 <= area_value <= 0.99:
frame_area = frame_shape[0] * frame_shape[1]
return max(1, int(frame_area * area_value))
else:
raise ValueError(
f"Percentage must be between 0.000001 and 0.99, got {area_value}"
)
raise TypeError(f"Unexpected type for area: {type(area_value)}")
class StreamInfoRetriever:
def __init__(self) -> None:
self.stream_cache: dict[str, tuple[int, int]] = {}