mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-01 19:17:41 +03:00
Support zone and mask reset
This commit is contained in:
parent
b3ee79e672
commit
8cf418cf1e
@ -394,9 +394,8 @@ def config_set(request: Request, body: AppConfigSetBody):
|
||||
|
||||
if body.update_topic and body.update_topic.startswith("config/cameras/"):
|
||||
_, _, camera, field = body.update_topic.split("/")
|
||||
settings = config.model_dump(
|
||||
mode="json", warnings="none", exclude_none=True
|
||||
)["cameras"][camera][field]
|
||||
|
||||
settings = config.get_nested_object(body.update_topic)
|
||||
request.app.config_publisher.publish_update(
|
||||
CameraConfigUpdateTopic(CameraConfigUpdateEnum[field], camera),
|
||||
settings,
|
||||
|
||||
@ -1,5 +1,29 @@
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
||||
class FrigateBaseModel(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", protected_namespaces=())
|
||||
|
||||
def get_nested_object(self, path: str) -> Any:
|
||||
parts = path.split("/")
|
||||
obj = self
|
||||
for part in parts:
|
||||
if part == "config":
|
||||
continue
|
||||
|
||||
if isinstance(obj, BaseModel):
|
||||
try:
|
||||
obj = getattr(obj, part)
|
||||
except AttributeError:
|
||||
return None
|
||||
elif isinstance(obj, dict):
|
||||
try:
|
||||
obj = obj[part]
|
||||
except KeyError:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
return obj
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Tuple
|
||||
|
||||
from numpy import ndarray
|
||||
|
||||
from frigate.config import MotionConfig
|
||||
|
||||
|
||||
@ -18,13 +20,21 @@ class MotionDetector(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def detect(self, frame):
|
||||
def detect(self, frame: ndarray) -> list:
|
||||
"""Detect motion and return motion boxes."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def is_calibrating(self):
|
||||
"""Return if motion is recalibrating."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_mask(self) -> None:
|
||||
"""Update the motion mask after a config change."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def stop(self):
|
||||
"""Stop any ongoing work and processes."""
|
||||
pass
|
||||
|
||||
@ -35,12 +35,7 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
self.avg_frame = np.zeros(self.motion_frame_size, np.float32)
|
||||
self.motion_frame_count = 0
|
||||
self.frame_counter = 0
|
||||
resized_mask = cv2.resize(
|
||||
config.mask,
|
||||
dsize=(self.motion_frame_size[1], self.motion_frame_size[0]),
|
||||
interpolation=cv2.INTER_AREA,
|
||||
)
|
||||
self.mask = np.where(resized_mask == [0])
|
||||
self.update_mask()
|
||||
self.save_images = False
|
||||
self.calibrating = True
|
||||
self.blur_radius = blur_radius
|
||||
@ -236,6 +231,14 @@ class ImprovedMotionDetector(MotionDetector):
|
||||
|
||||
return motion_boxes
|
||||
|
||||
def update_mask(self) -> None:
|
||||
resized_mask = cv2.resize(
|
||||
self.config.mask,
|
||||
dsize=(self.motion_frame_size[1], self.motion_frame_size[0]),
|
||||
interpolation=cv2.INTER_AREA,
|
||||
)
|
||||
self.mask = np.where(resized_mask == [0])
|
||||
|
||||
def stop(self) -> None:
|
||||
"""stop the motion detector."""
|
||||
pass
|
||||
|
||||
@ -650,6 +650,9 @@ def process_frames(
|
||||
prev_enabled = camera_enabled
|
||||
camera_enabled = camera_config.enabled
|
||||
|
||||
if "motion" in updated_configs:
|
||||
motion_detector.update_mask()
|
||||
|
||||
if (
|
||||
not camera_enabled
|
||||
and prev_enabled != camera_enabled
|
||||
|
||||
@ -161,6 +161,7 @@ export default function MotionMaskEditPane({
|
||||
axios
|
||||
.put(`config/set?${queryString}`, {
|
||||
requires_restart: 0,
|
||||
update_topic: `config/cameras/${polygon.camera}/motion`,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.status === 200) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user