Allow birdseye to be overridden at the camera level (#3083)

* Add camera level processing for birdseye

* Add camera level birdseye configruation

* Propogate birdseye from global

* Update docs to show that birdseye is overridable

* Fix incorrect default factory

* Update note to indicate values that can be overridden

* Cleanup config accessing

* Add tests for birdseye config behavior

* Fix mistake on test format

* Update tests
This commit is contained in:
Nicolas Mowen 2022-04-15 05:59:30 -06:00 committed by GitHub
parent 164e9b7eb8
commit d749cf2e6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 5 deletions

View File

@ -110,6 +110,7 @@ environment_vars:
EXAMPLE_VAR: value
# Optional: birdseye configuration
# NOTE: Can (enabled, mode) be overridden at the camera level
birdseye:
# Optional: Enable birdseye view (default: shown below)
enabled: True

View File

@ -324,6 +324,13 @@ class BirdseyeConfig(FrigateBaseModel):
)
class BirdseyeCameraConfig(FrigateBaseModel):
enabled: bool = Field(default=True, title="Enable birdseye view for camera.")
mode: BirdseyeModeEnum = Field(
default=BirdseyeModeEnum.objects, title="Tracking mode for camera."
)
FFMPEG_GLOBAL_ARGS_DEFAULT = ["-hide_banner", "-loglevel", "warning"]
FFMPEG_INPUT_ARGS_DEFAULT = [
"-avoid_negative_ts",
@ -539,6 +546,9 @@ class CameraConfig(FrigateBaseModel):
detect: DetectConfig = Field(
default_factory=DetectConfig, title="Object detection configuration."
)
birdseye: BirdseyeCameraConfig = Field(
default_factory=BirdseyeCameraConfig, title="Birdseye camera configuration."
)
timestamp_style: TimestampStyleConfig = Field(
default_factory=TimestampStyleConfig, title="Timestamp style configuration."
)
@ -775,6 +785,7 @@ class FrigateConfig(FrigateBaseModel):
# Global config to propegate down to camera level
global_config = config.dict(
include={
"birdseye": ...,
"record": ...,
"snapshots": ...,
"live": ...,

View File

@ -190,14 +190,14 @@ class BirdsEyeFrameManager:
channel_dims,
)
def camera_active(self, object_box_count, motion_box_count):
if self.mode == BirdseyeModeEnum.continuous:
def camera_active(self, mode, object_box_count, motion_box_count):
if mode == BirdseyeModeEnum.continuous:
return True
if self.mode == BirdseyeModeEnum.motion and motion_box_count > 0:
if mode == BirdseyeModeEnum.motion and motion_box_count > 0:
return True
if self.mode == BirdseyeModeEnum.objects and object_box_count > 0:
if mode == BirdseyeModeEnum.objects and object_box_count > 0:
return True
def update_frame(self):
@ -311,10 +311,14 @@ class BirdsEyeFrameManager:
return True
def update(self, camera, object_count, motion_count, frame_time, frame) -> bool:
# don't process if birdseye is disabled for this camera
camera_config = self.config.cameras[camera].birdseye
if not camera_config.enabled:
return False
# update the last active frame for the camera
self.cameras[camera]["current_frame"] = frame_time
if self.camera_active(object_count, motion_count):
if self.camera_active(camera_config.mode, object_count, motion_count):
self.cameras[camera]["last_active_frame"] = frame_time
now = datetime.datetime.now().timestamp()

View File

@ -2,6 +2,7 @@ import unittest
import numpy as np
from pydantic import ValidationError
from frigate.config import (
BirdseyeModeEnum,
FrigateConfig,
DetectorTypeEnum,
)
@ -80,6 +81,62 @@ class TestConfig(unittest.TestCase):
runtime_config = frigate_config.runtime_config
assert "dog" in runtime_config.cameras["back"].objects.track
def test_override_birdseye(self):
config = {
"mqtt": {"host": "mqtt"},
"birdseye": { "enabled": True, "mode": "continuous" },
"cameras": {
"back": {
"ffmpeg": {
"inputs": [
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
]
},
"detect": {
"height": 1080,
"width": 1920,
"fps": 5,
},
"birdseye": {
"enabled": False,
"mode": "motion"
},
}
},
}
frigate_config = FrigateConfig(**config)
assert config == frigate_config.dict(exclude_unset=True)
runtime_config = frigate_config.runtime_config
assert not runtime_config.cameras["back"].birdseye.enabled
assert runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.motion
def test_inherit_birdseye(self):
config = {
"mqtt": {"host": "mqtt"},
"birdseye": { "enabled": True, "mode": "continuous" },
"cameras": {
"back": {
"ffmpeg": {
"inputs": [
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
]
},
"detect": {
"height": 1080,
"width": 1920,
"fps": 5,
},
}
},
}
frigate_config = FrigateConfig(**config)
assert config == frigate_config.dict(exclude_unset=True)
runtime_config = frigate_config.runtime_config
assert runtime_config.cameras["back"].birdseye.enabled
assert runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.continuous
def test_override_tracked_objects(self):
config = {
"mqtt": {"host": "mqtt"},