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

View File

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

View File

@ -5,6 +5,7 @@ import shlex
import subprocess as sp import subprocess as sp
import json import json
import re import re
from enum import Enum
import signal import signal
import traceback import traceback
import urllib.parse import urllib.parse
@ -972,3 +973,24 @@ class SharedMemoryFrameManager(FrameManager):
self.shm_store[name].close() self.shm_store[name].close()
self.shm_store[name].unlink() self.shm_store[name].unlink()
del self.shm_store[name] 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