mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-08 20:25:26 +03:00
remove motion and detection camera metrics
This commit is contained in:
parent
e95004c211
commit
154a810592
@ -22,7 +22,7 @@ from frigate.comms.dispatcher import Communicator, Dispatcher
|
||||
from frigate.comms.inter_process import InterProcessCommunicator
|
||||
from frigate.comms.mqtt import MqttClient
|
||||
from frigate.comms.ws import WebSocketClient
|
||||
from frigate.config import BirdseyeModeEnum, FrigateConfig
|
||||
from frigate.config import FrigateConfig
|
||||
from frigate.const import (
|
||||
CACHE_DIR,
|
||||
CLIPS_DIR,
|
||||
@ -129,35 +129,6 @@ class FrigateApp:
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
"process_fps": mp.Value("d", 0.0), # type: ignore[typeddict-item]
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
"detection_enabled": mp.Value( # type: ignore[typeddict-item]
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
"i",
|
||||
self.config.cameras[camera_name].detect.enabled,
|
||||
),
|
||||
"motion_enabled": mp.Value("i", True), # type: ignore[typeddict-item]
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
"improve_contrast_enabled": mp.Value( # type: ignore[typeddict-item]
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
"i",
|
||||
self.config.cameras[camera_name].motion.improve_contrast,
|
||||
),
|
||||
"motion_threshold": mp.Value( # type: ignore[typeddict-item]
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
"i",
|
||||
self.config.cameras[camera_name].motion.threshold,
|
||||
),
|
||||
"motion_contour_area": mp.Value( # type: ignore[typeddict-item]
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
"i",
|
||||
self.config.cameras[camera_name].motion.contour_area,
|
||||
),
|
||||
"detection_fps": mp.Value("d", 0.0), # type: ignore[typeddict-item]
|
||||
# issue https://github.com/python/typeshed/issues/8799
|
||||
# from mypy 0.981 onwards
|
||||
@ -387,7 +358,6 @@ class FrigateApp:
|
||||
self.config,
|
||||
self.inter_config_updater,
|
||||
self.onvif_controller,
|
||||
self.camera_metrics,
|
||||
self.ptz_metrics,
|
||||
comms,
|
||||
)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import multiprocessing as mp
|
||||
import os
|
||||
from multiprocessing.synchronize import Event as MpEvent
|
||||
from typing import Callable, Optional
|
||||
from typing import Optional
|
||||
|
||||
import zmq
|
||||
|
||||
@ -46,9 +46,7 @@ class ConfigSubscriber:
|
||||
def check_for_update(self) -> Optional[tuple[str, any]]:
|
||||
"""Returns updated config or None if no update."""
|
||||
try:
|
||||
topic = self.socket.recv_string(
|
||||
flags=zmq.NOBLOCK
|
||||
)
|
||||
topic = self.socket.recv_string(flags=zmq.NOBLOCK)
|
||||
return (topic, self.socket.recv_pyobj())
|
||||
except zmq.ZMQError:
|
||||
return (None, None)
|
||||
|
||||
@ -9,7 +9,7 @@ from frigate.config import BirdseyeModeEnum, FrigateConfig
|
||||
from frigate.const import INSERT_MANY_RECORDINGS, INSERT_PREVIEW, REQUEST_REGION_GRID
|
||||
from frigate.models import Previews, Recordings
|
||||
from frigate.ptz.onvif import OnvifCommandEnum, OnvifController
|
||||
from frigate.types import CameraMetricsTypes, PTZMetricsTypes
|
||||
from frigate.types import PTZMetricsTypes
|
||||
from frigate.util.object import get_camera_regions_grid
|
||||
from frigate.util.services import restart_frigate
|
||||
|
||||
@ -43,14 +43,12 @@ class Dispatcher:
|
||||
config: FrigateConfig,
|
||||
config_updater: ConfigPublisher,
|
||||
onvif: OnvifController,
|
||||
camera_metrics: dict[str, CameraMetricsTypes],
|
||||
ptz_metrics: dict[str, PTZMetricsTypes],
|
||||
communicators: list[Communicator],
|
||||
) -> None:
|
||||
self.config = config
|
||||
self.config_updater = config_updater
|
||||
self.onvif = onvif
|
||||
self.camera_metrics = camera_metrics
|
||||
self.ptz_metrics = ptz_metrics
|
||||
self.comms = communicators
|
||||
|
||||
@ -119,44 +117,51 @@ class Dispatcher:
|
||||
def _on_detect_command(self, camera_name: str, payload: str) -> None:
|
||||
"""Callback for detect topic."""
|
||||
detect_settings = self.config.cameras[camera_name].detect
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
|
||||
if payload == "ON":
|
||||
if not self.camera_metrics[camera_name]["detection_enabled"].value:
|
||||
if not detect_settings.enabled:
|
||||
logger.info(f"Turning on detection for {camera_name}")
|
||||
self.camera_metrics[camera_name]["detection_enabled"].value = True
|
||||
detect_settings.enabled = True
|
||||
|
||||
if not self.camera_metrics[camera_name]["motion_enabled"].value:
|
||||
if not motion_settings.enabled:
|
||||
logger.info(
|
||||
f"Turning on motion for {camera_name} due to detection being enabled."
|
||||
)
|
||||
self.camera_metrics[camera_name]["motion_enabled"].value = True
|
||||
motion_settings.enabled = True
|
||||
self.config_updater.publish(
|
||||
f"config/motion/{camera_name}", motion_settings
|
||||
)
|
||||
self.publish(f"{camera_name}/motion/state", payload, retain=True)
|
||||
elif payload == "OFF":
|
||||
if self.camera_metrics[camera_name]["detection_enabled"].value:
|
||||
if detect_settings.enabled:
|
||||
logger.info(f"Turning off detection for {camera_name}")
|
||||
self.camera_metrics[camera_name]["detection_enabled"].value = False
|
||||
detect_settings.enabled = False
|
||||
|
||||
self.config_updater.publish(f"config/detect/{camera_name}", detect_settings)
|
||||
self.publish(f"{camera_name}/detect/state", payload, retain=True)
|
||||
|
||||
def _on_motion_command(self, camera_name: str, payload: str) -> None:
|
||||
"""Callback for motion topic."""
|
||||
detect_settings = self.config.cameras[camera_name].detect
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
|
||||
if payload == "ON":
|
||||
if not self.camera_metrics[camera_name]["motion_enabled"].value:
|
||||
if not motion_settings.enabled:
|
||||
logger.info(f"Turning on motion for {camera_name}")
|
||||
self.camera_metrics[camera_name]["motion_enabled"].value = True
|
||||
motion_settings.enabled = True
|
||||
elif payload == "OFF":
|
||||
if self.camera_metrics[camera_name]["detection_enabled"].value:
|
||||
if detect_settings.enabled:
|
||||
logger.error(
|
||||
"Turning off motion is not allowed when detection is enabled."
|
||||
)
|
||||
return
|
||||
|
||||
if self.camera_metrics[camera_name]["motion_enabled"].value:
|
||||
if motion_settings.enabled:
|
||||
logger.info(f"Turning off motion for {camera_name}")
|
||||
self.camera_metrics[camera_name]["motion_enabled"].value = False
|
||||
motion_settings.enabled = False
|
||||
|
||||
self.config_updater.publish(f"config/motion/{camera_name}", motion_settings)
|
||||
self.publish(f"{camera_name}/motion/state", payload, retain=True)
|
||||
|
||||
def _on_motion_improve_contrast_command(
|
||||
@ -166,20 +171,15 @@ class Dispatcher:
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
|
||||
if payload == "ON":
|
||||
if not self.camera_metrics[camera_name]["improve_contrast_enabled"].value:
|
||||
if not motion_settings.improve_contrast:
|
||||
logger.info(f"Turning on improve contrast for {camera_name}")
|
||||
self.camera_metrics[camera_name][
|
||||
"improve_contrast_enabled"
|
||||
].value = True
|
||||
motion_settings.improve_contrast = True # type: ignore[union-attr]
|
||||
elif payload == "OFF":
|
||||
if self.camera_metrics[camera_name]["improve_contrast_enabled"].value:
|
||||
if motion_settings.improve_contrast:
|
||||
logger.info(f"Turning off improve contrast for {camera_name}")
|
||||
self.camera_metrics[camera_name][
|
||||
"improve_contrast_enabled"
|
||||
].value = False
|
||||
motion_settings.improve_contrast = False # type: ignore[union-attr]
|
||||
|
||||
self.config_updater.publish(f"config/motion/{camera_name}", motion_settings)
|
||||
self.publish(f"{camera_name}/improve_contrast/state", payload, retain=True)
|
||||
|
||||
def _on_ptz_autotracker_command(self, camera_name: str, payload: str) -> None:
|
||||
@ -218,8 +218,8 @@ class Dispatcher:
|
||||
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
logger.info(f"Setting motion contour area for {camera_name}: {payload}")
|
||||
self.camera_metrics[camera_name]["motion_contour_area"].value = payload
|
||||
motion_settings.contour_area = payload # type: ignore[union-attr]
|
||||
self.config_updater.publish(f"config/motion/{camera_name}", motion_settings)
|
||||
self.publish(f"{camera_name}/motion_contour_area/state", payload, retain=True)
|
||||
|
||||
def _on_motion_threshold_command(self, camera_name: str, payload: int) -> None:
|
||||
@ -232,8 +232,8 @@ class Dispatcher:
|
||||
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
logger.info(f"Setting motion threshold for {camera_name}: {payload}")
|
||||
self.camera_metrics[camera_name]["motion_threshold"].value = payload
|
||||
motion_settings.threshold = payload # type: ignore[union-attr]
|
||||
self.config_updater.publish(f"config/motion/{camera_name}", motion_settings)
|
||||
self.publish(f"{camera_name}/motion_threshold/state", payload, retain=True)
|
||||
|
||||
def _on_audio_command(self, camera_name: str, payload: str) -> None:
|
||||
@ -255,9 +255,7 @@ class Dispatcher:
|
||||
logger.info(f"Turning off audio detection for {camera_name}")
|
||||
audio_settings.enabled = False
|
||||
|
||||
self.config_updater.publish(
|
||||
f"config/audio/{camera_name}", self.config.cameras[camera_name].audio
|
||||
)
|
||||
self.config_updater.publish(f"config/audio/{camera_name}", audio_settings)
|
||||
self.publish(f"{camera_name}/audio/state", payload, retain=True)
|
||||
|
||||
def _on_recordings_command(self, camera_name: str, payload: str) -> None:
|
||||
@ -279,9 +277,7 @@ class Dispatcher:
|
||||
logger.info(f"Turning off recordings for {camera_name}")
|
||||
record_settings.enabled = False
|
||||
|
||||
self.config_updater.publish(
|
||||
f"config/record/{camera_name}", self.config.cameras[camera_name].record
|
||||
)
|
||||
self.config_updater.publish(f"config/record/{camera_name}", record_settings)
|
||||
self.publish(f"{camera_name}/recordings/state", payload, retain=True)
|
||||
|
||||
def _on_snapshots_command(self, camera_name: str, payload: str) -> None:
|
||||
@ -328,9 +324,7 @@ class Dispatcher:
|
||||
logger.info(f"Turning off birdseye for {camera_name}")
|
||||
birdseye_settings.enabled = False
|
||||
|
||||
self.config_updater.publish(
|
||||
f"config/birdseye/{camera_name}", self.config.cameras[camera_name].birdseye
|
||||
)
|
||||
self.config_updater.publish(f"config/birdseye/{camera_name}", birdseye_settings)
|
||||
self.publish(f"{camera_name}/birdseye/state", payload, retain=True)
|
||||
|
||||
def _on_birdseye_mode_command(self, camera_name: str, payload: str) -> None:
|
||||
@ -340,18 +334,16 @@ class Dispatcher:
|
||||
logger.info(f"Invalid birdseye_mode command: {payload}")
|
||||
return
|
||||
|
||||
birdseye_config = self.config.cameras[camera_name].birdseye
|
||||
birdseye_settings = self.config.cameras[camera_name].birdseye
|
||||
|
||||
if not birdseye_config.enabled:
|
||||
if not birdseye_settings.enabled:
|
||||
logger.info(f"Birdseye mode not enabled for {camera_name}")
|
||||
return
|
||||
|
||||
birdseye_config.mode = BirdseyeModeEnum(payload.lower())
|
||||
birdseye_settings.mode = BirdseyeModeEnum(payload.lower())
|
||||
logger.info(
|
||||
f"Setting birdseye mode for {camera_name} to {birdseye_config.mode}"
|
||||
f"Setting birdseye mode for {camera_name} to {birdseye_settings.mode}"
|
||||
)
|
||||
|
||||
self.config_updater.publish(
|
||||
f"config/birdseye/{camera_name}", self.config.cameras[camera_name].birdseye
|
||||
)
|
||||
self.config_updater.publish(f"config/birdseye/{camera_name}", birdseye_settings)
|
||||
self.publish(f"{camera_name}/birdseye_mode/state", payload, retain=True)
|
||||
|
||||
@ -32,7 +32,7 @@ class InterProcessCommunicator(Communicator):
|
||||
self.reader_thread.start()
|
||||
|
||||
def read(self) -> None:
|
||||
while not self.stop_event.wait(0.5):
|
||||
while not self.stop_event.wait(0.1):
|
||||
while True: # load all messages that are queued
|
||||
try:
|
||||
(topic, value) = self.socket.recv_pyobj(flags=zmq.NOBLOCK)
|
||||
|
||||
@ -300,6 +300,7 @@ class RecordConfig(FrigateBaseModel):
|
||||
|
||||
|
||||
class MotionConfig(FrigateBaseModel):
|
||||
enabled: bool = Field(default=True, title="Enable motion on all cameras.")
|
||||
threshold: int = Field(
|
||||
default=30,
|
||||
title="Motion detection threshold (1-255).",
|
||||
@ -321,6 +322,9 @@ class MotionConfig(FrigateBaseModel):
|
||||
default=30,
|
||||
title="Delay for updating MQTT with no motion detected.",
|
||||
)
|
||||
enabled_in_config: Optional[bool] = Field(
|
||||
title="Keep track of original state of motion detection."
|
||||
)
|
||||
|
||||
|
||||
class RuntimeMotionConfig(MotionConfig):
|
||||
@ -1041,6 +1045,14 @@ def verify_autotrack_zones(camera_config: CameraConfig) -> ValueError | None:
|
||||
)
|
||||
|
||||
|
||||
def verify_motion_and_detect(camera_config: CameraConfig) -> ValueError | None:
|
||||
"""Verify that required_zones are specified when autotracking is enabled."""
|
||||
if camera_config.detect.enabled and not camera_config.motion.enabled:
|
||||
raise ValueError(
|
||||
f"Camera {camera_config.name} has motion detection disabled and object detection enabled but object detection requires motion detection ."
|
||||
)
|
||||
|
||||
|
||||
class FrigateConfig(FrigateBaseModel):
|
||||
mqtt: MqttConfig = Field(title="MQTT Configuration.")
|
||||
database: DatabaseConfig = Field(
|
||||
@ -1202,8 +1214,8 @@ class FrigateConfig(FrigateBaseModel):
|
||||
**FRIGATE_ENV_VARS
|
||||
)
|
||||
# set config pre-value
|
||||
camera_config.record.enabled_in_config = camera_config.record.enabled
|
||||
camera_config.audio.enabled_in_config = camera_config.audio.enabled
|
||||
camera_config.record.enabled_in_config = camera_config.record.enabled
|
||||
camera_config.onvif.autotracking.enabled_in_config = (
|
||||
camera_config.onvif.autotracking.enabled
|
||||
)
|
||||
@ -1250,6 +1262,7 @@ class FrigateConfig(FrigateBaseModel):
|
||||
raw_mask=camera_config.motion.mask,
|
||||
**camera_config.motion.dict(exclude_unset=True),
|
||||
)
|
||||
camera_config.motion.enabled_in_config = camera_config.motion.enabled
|
||||
|
||||
# Set live view stream if none is set
|
||||
if not camera_config.live.stream_name:
|
||||
@ -1261,6 +1274,7 @@ class FrigateConfig(FrigateBaseModel):
|
||||
verify_recording_segments_setup_with_reasonable_time(camera_config)
|
||||
verify_zone_objects_are_tracked(camera_config)
|
||||
verify_autotrack_zones(camera_config)
|
||||
verify_motion_and_detect(camera_config)
|
||||
|
||||
# generate the ffmpeg commands
|
||||
camera_config.create_ffmpeg_cmds()
|
||||
|
||||
@ -338,9 +338,10 @@ class AudioEventMaintainer(threading.Thread):
|
||||
|
||||
while not self.stop_event.is_set():
|
||||
# check if there is an updated config
|
||||
updated_topic, updated_audio_config = (
|
||||
self.config_subscriber.check_for_update()
|
||||
)
|
||||
(
|
||||
updated_topic,
|
||||
updated_audio_config,
|
||||
) = self.config_subscriber.check_for_update()
|
||||
|
||||
if updated_topic:
|
||||
self.config.audio = updated_audio_config
|
||||
|
||||
@ -5,6 +5,7 @@ import imutils
|
||||
import numpy as np
|
||||
from scipy.ndimage import gaussian_filter
|
||||
|
||||
from frigate.comms.config_updater import ConfigSubscriber
|
||||
from frigate.config import MotionConfig
|
||||
from frigate.motion import MotionDetector
|
||||
|
||||
@ -17,9 +18,6 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
frame_shape,
|
||||
config: MotionConfig,
|
||||
fps: int,
|
||||
improve_contrast,
|
||||
threshold,
|
||||
contour_area,
|
||||
name="improved",
|
||||
blur_radius=1,
|
||||
interpolation=cv2.INTER_NEAREST,
|
||||
@ -44,14 +42,12 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
self.mask = np.where(resized_mask == [0])
|
||||
self.save_images = False
|
||||
self.calibrating = True
|
||||
self.improve_contrast = improve_contrast
|
||||
self.threshold = threshold
|
||||
self.contour_area = contour_area
|
||||
self.blur_radius = blur_radius
|
||||
self.interpolation = interpolation
|
||||
self.contrast_values = np.zeros((contrast_frame_history, 2), np.uint8)
|
||||
self.contrast_values[:, 1:2] = 255
|
||||
self.contrast_values_index = 0
|
||||
self.config_subscriber = ConfigSubscriber(f"config/motion/{name}")
|
||||
|
||||
def is_calibrating(self):
|
||||
return self.calibrating
|
||||
@ -59,6 +55,15 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
def detect(self, frame):
|
||||
motion_boxes = []
|
||||
|
||||
# check for updated motion config
|
||||
_, updated_motion_config = self.config_subscriber.check_for_update()
|
||||
|
||||
if updated_motion_config:
|
||||
self.config = updated_motion_config
|
||||
|
||||
if not self.config.enabled:
|
||||
return motion_boxes
|
||||
|
||||
gray = frame[0 : self.frame_shape[0], 0 : self.frame_shape[1]]
|
||||
|
||||
# resize frame
|
||||
@ -72,7 +77,7 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
resized_saved = resized_frame.copy()
|
||||
|
||||
# Improve contrast
|
||||
if self.improve_contrast.value:
|
||||
if self.config.improve_contrast:
|
||||
# TODO tracking moving average of min/max to avoid sudden contrast changes
|
||||
minval = np.percentile(resized_frame, 4).astype(np.uint8)
|
||||
maxval = np.percentile(resized_frame, 96).astype(np.uint8)
|
||||
@ -110,7 +115,7 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
|
||||
# compute the threshold image for the current frame
|
||||
thresh = cv2.threshold(
|
||||
frameDelta, self.threshold.value, 255, cv2.THRESH_BINARY
|
||||
frameDelta, self.config.threshold, 255, cv2.THRESH_BINARY
|
||||
)[1]
|
||||
|
||||
# dilate the thresholded image to fill in holes, then find contours
|
||||
@ -127,7 +132,7 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
# if the contour is big enough, count it as motion
|
||||
contour_area = cv2.contourArea(c)
|
||||
total_contour_area += contour_area
|
||||
if contour_area > self.contour_area.value:
|
||||
if contour_area > self.config.contour_area:
|
||||
x, y, w, h = cv2.boundingRect(c)
|
||||
motion_boxes.append(
|
||||
(
|
||||
@ -170,9 +175,11 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
]
|
||||
cv2.imwrite(
|
||||
f"debug/frames/{self.name}-{self.frame_counter}.jpg",
|
||||
cv2.hconcat(frames)
|
||||
if self.frame_shape[0] > self.frame_shape[1]
|
||||
else cv2.vconcat(frames),
|
||||
(
|
||||
cv2.hconcat(frames)
|
||||
if self.frame_shape[0] > self.frame_shape[1]
|
||||
else cv2.vconcat(frames)
|
||||
),
|
||||
)
|
||||
|
||||
if len(motion_boxes) > 0:
|
||||
|
||||
@ -433,10 +433,7 @@ class BirdsEyeFrameManager:
|
||||
|
||||
# check if we need to reset the layout because there is a different number of cameras
|
||||
if len(self.active_cameras) - len(active_cameras) == 0:
|
||||
if (
|
||||
len(self.active_cameras) == 1
|
||||
and self.active_cameras[0] == active_cameras[0]
|
||||
):
|
||||
if len(self.active_cameras) == 1 and self.active_cameras != active_cameras:
|
||||
reset_layout = True
|
||||
elif max_camera_refresh:
|
||||
reset_layout = True
|
||||
@ -758,9 +755,10 @@ class Birdseye:
|
||||
) -> None:
|
||||
# check if there is an updated config
|
||||
while True:
|
||||
updated_topic, updated_birdseye_config = (
|
||||
self.config_subscriber.check_for_update()
|
||||
)
|
||||
(
|
||||
updated_topic,
|
||||
updated_birdseye_config,
|
||||
) = self.config_subscriber.check_for_update()
|
||||
|
||||
if not updated_topic:
|
||||
break
|
||||
|
||||
@ -444,9 +444,10 @@ class RecordingMaintainer(threading.Thread):
|
||||
|
||||
# check if there is an updated config
|
||||
while True:
|
||||
updated_topic, updated_record_config = (
|
||||
self.config_subscriber.check_for_update()
|
||||
)
|
||||
(
|
||||
updated_topic,
|
||||
updated_record_config,
|
||||
) = self.config_subscriber.check_for_update()
|
||||
|
||||
if not updated_topic:
|
||||
break
|
||||
|
||||
@ -265,7 +265,7 @@ def stats_snapshot(
|
||||
"process_fps": round(camera_stats["process_fps"].value, 2),
|
||||
"skipped_fps": round(camera_stats["skipped_fps"].value, 2),
|
||||
"detection_fps": round(camera_stats["detection_fps"].value, 2),
|
||||
"detection_enabled": camera_stats["detection_enabled"].value,
|
||||
"detection_enabled": config.cameras[name].detect.enabled,
|
||||
"pid": pid,
|
||||
"capture_pid": cpid,
|
||||
"ffmpeg_pid": ffmpeg_pid,
|
||||
|
||||
@ -10,23 +10,16 @@ from frigate.object_detection import ObjectDetectProcess
|
||||
class CameraMetricsTypes(TypedDict):
|
||||
camera_fps: Synchronized
|
||||
capture_process: Optional[Process]
|
||||
detection_enabled: Synchronized
|
||||
detection_fps: Synchronized
|
||||
detection_frame: Synchronized
|
||||
ffmpeg_pid: Synchronized
|
||||
frame_queue: Queue
|
||||
motion_enabled: Synchronized
|
||||
improve_contrast_enabled: Synchronized
|
||||
motion_threshold: Synchronized
|
||||
motion_contour_area: Synchronized
|
||||
process: Optional[Process]
|
||||
process_fps: Synchronized
|
||||
read_start: Synchronized
|
||||
skipped_fps: Synchronized
|
||||
audio_rms: Synchronized
|
||||
audio_dBFS: Synchronized
|
||||
birdseye_enabled: Synchronized
|
||||
birdseye_mode: Synchronized
|
||||
|
||||
|
||||
class PTZMetricsTypes(TypedDict):
|
||||
|
||||
@ -11,6 +11,7 @@ import time
|
||||
import cv2
|
||||
from setproctitle import setproctitle
|
||||
|
||||
from frigate.comms.config_updater import ConfigSubscriber
|
||||
from frigate.comms.inter_process import InterProcessRequestor
|
||||
from frigate.config import CameraConfig, DetectConfig, ModelConfig
|
||||
from frigate.const import (
|
||||
@ -406,11 +407,6 @@ def track_camera(
|
||||
listen()
|
||||
|
||||
frame_queue = process_info["frame_queue"]
|
||||
detection_enabled = process_info["detection_enabled"]
|
||||
motion_enabled = process_info["motion_enabled"]
|
||||
improve_contrast_enabled = process_info["improve_contrast_enabled"]
|
||||
motion_threshold = process_info["motion_threshold"]
|
||||
motion_contour_area = process_info["motion_contour_area"]
|
||||
|
||||
frame_shape = config.frame_shape
|
||||
objects_to_track = config.objects.track
|
||||
@ -420,9 +416,6 @@ def track_camera(
|
||||
frame_shape,
|
||||
config.motion,
|
||||
config.detect.fps,
|
||||
improve_contrast_enabled,
|
||||
motion_threshold,
|
||||
motion_contour_area,
|
||||
)
|
||||
object_detector = RemoteObjectDetector(
|
||||
name, labelmap, detection_queue, result_connection, model_config, stop_event
|
||||
@ -450,8 +443,6 @@ def track_camera(
|
||||
process_info,
|
||||
objects_to_track,
|
||||
object_filters,
|
||||
detection_enabled,
|
||||
motion_enabled,
|
||||
stop_event,
|
||||
ptz_metrics,
|
||||
region_grid,
|
||||
@ -519,8 +510,6 @@ def process_frames(
|
||||
process_info: dict,
|
||||
objects_to_track: list[str],
|
||||
object_filters,
|
||||
detection_enabled: mp.Value,
|
||||
motion_enabled: mp.Value,
|
||||
stop_event,
|
||||
ptz_metrics: PTZMetricsTypes,
|
||||
region_grid,
|
||||
@ -530,6 +519,7 @@ def process_frames(
|
||||
detection_fps = process_info["detection_fps"]
|
||||
current_frame_time = process_info["detection_frame"]
|
||||
next_region_update = get_tomorrow_at_time(2)
|
||||
config_subscriber = ConfigSubscriber(f"config/detect/{camera_name}")
|
||||
|
||||
fps_tracker = EventsPerSecond()
|
||||
fps_tracker.start()
|
||||
@ -540,6 +530,12 @@ def process_frames(
|
||||
region_min_size = get_min_region_size(model_config)
|
||||
|
||||
while not stop_event.is_set():
|
||||
# check for updated detect config
|
||||
_, updated_detect_config = config_subscriber.check_for_update()
|
||||
|
||||
if updated_detect_config:
|
||||
detect_config = updated_detect_config
|
||||
|
||||
if (
|
||||
datetime.datetime.now().astimezone(datetime.timezone.utc)
|
||||
> next_region_update
|
||||
@ -570,13 +566,13 @@ def process_frames(
|
||||
continue
|
||||
|
||||
# look for motion if enabled
|
||||
motion_boxes = motion_detector.detect(frame) if motion_enabled.value else []
|
||||
motion_boxes = motion_detector.detect(frame)
|
||||
|
||||
regions = []
|
||||
consolidated_detections = []
|
||||
|
||||
# if detection is disabled
|
||||
if not detection_enabled.value:
|
||||
if not detect_config.enabled:
|
||||
object_tracker.match_and_update(frame_time, [])
|
||||
else:
|
||||
# get stationary object ids
|
||||
|
||||
Loading…
Reference in New Issue
Block a user