Move zone testing logic to util def and test for specific point

This commit is contained in:
Nick Mowen 2022-05-27 13:03:40 -06:00
parent 4cfbda8f92
commit 9d05e86847
3 changed files with 30 additions and 15 deletions

View File

@ -8,7 +8,6 @@ from typing import Dict, List, Optional, Tuple, Union
import matplotlib.pyplot as plt
import numpy as np
import yaml
from pydantic import BaseModel, Extra, Field, validator, parse_obj_as
from pydantic.fields import PrivateAttr
@ -19,12 +18,12 @@ from frigate.const import (
YAML_EXT,
)
from frigate.util import (
BoundingBoxTriggerEnum,
create_mask,
deep_merge,
get_ffmpeg_arg_list,
escape_special_characters,
load_config_with_no_duplicates,
load_labels,
)
from frigate.ffmpeg_presets import (
parse_preset_hardware_acceleration,
@ -33,14 +32,11 @@ from frigate.ffmpeg_presets import (
parse_preset_output_rtmp,
)
from frigate.detectors import (
PixelFormatEnum,
InputTensorEnum,
ModelConfig,
DetectorConfig,
)
from frigate.version import VERSION
logger = logging.getLogger(__name__)
# TODO: Identify what the default format to display timestamps is
@ -277,13 +273,6 @@ class RuntimeFilterConfig(FilterConfig):
extra = Extra.ignore
class BoundingBoxTriggerEnum(str, Enum):
bottom_center = "bottom-center"
left_center = "left-center"
top_center = "top-center"
right_center = "right-center"
# this uses the base model because the color is an extra attribute
class ZoneConfig(BaseModel):
filters: Dict[str, FilterConfig] = Field(

View File

@ -136,15 +136,19 @@ class TrackedObject:
# check zones
current_zones = []
bottom_center = (obj_data["centroid"][0], obj_data["box"][3])
# check each zone
for name, zone in self.camera_config.zones.items():
# if the zone is not for this object type, skip
if len(zone.objects) > 0 and not obj_data["label"] in zone.objects:
continue
contour = zone.contour
# check if the object is in the zone
if cv2.pointPolygonTest(contour, bottom_center, False) >= 0:
if zone.bounding_box_trigger.is_in_zone(
obj_data["centroid"],
obj_data["box"],
zone.contour,
):
# if the object passed the filters once, dont apply again
if name in self.current_zones or not zone_filtered(self, zone.filters):
current_zones.append(name)

View File

@ -5,6 +5,7 @@ import shlex
import subprocess as sp
import json
import re
from enum import Enum
import signal
import traceback
import urllib.parse
@ -972,3 +973,24 @@ class SharedMemoryFrameManager(FrameManager):
self.shm_store[name].close()
self.shm_store[name].unlink()
del self.shm_store[name]
class BoundingBoxTriggerEnum(str, Enum):
bottom_center = "bottom-center"
left_center = "left-center"
right_center = "right-center"
top_center = "top-center"
def is_in_zone(self, centroid, box, contour) -> bool:
"""Tests a zone based on the bounding box
trigger and the objects bounding box."""
if self.value is self.bottom_center:
point = (centroid[0], box[3])
elif self.value is self.left_center:
point = (box[0], centroid[1])
elif self.value is self.right_center:
point = (box[2], centroid[1])
elif self.value is self.top_center:
point = (centroid[0], box[1])
return cv2.pointPolygonTest(contour, point, False) >= 0