mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-03 12:07:40 +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/"):
|
if body.update_topic and body.update_topic.startswith("config/cameras/"):
|
||||||
_, _, camera, field = body.update_topic.split("/")
|
_, _, camera, field = body.update_topic.split("/")
|
||||||
settings = config.model_dump(
|
|
||||||
mode="json", warnings="none", exclude_none=True
|
settings = config.get_nested_object(body.update_topic)
|
||||||
)["cameras"][camera][field]
|
|
||||||
request.app.config_publisher.publish_update(
|
request.app.config_publisher.publish_update(
|
||||||
CameraConfigUpdateTopic(CameraConfigUpdateEnum[field], camera),
|
CameraConfigUpdateTopic(CameraConfigUpdateEnum[field], camera),
|
||||||
settings,
|
settings,
|
||||||
|
|||||||
@ -1,5 +1,29 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict
|
from pydantic import BaseModel, ConfigDict
|
||||||
|
|
||||||
|
|
||||||
class FrigateBaseModel(BaseModel):
|
class FrigateBaseModel(BaseModel):
|
||||||
model_config = ConfigDict(extra="forbid", protected_namespaces=())
|
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 abc import ABC, abstractmethod
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
|
from numpy import ndarray
|
||||||
|
|
||||||
from frigate.config import MotionConfig
|
from frigate.config import MotionConfig
|
||||||
|
|
||||||
|
|
||||||
@ -18,13 +20,21 @@ class MotionDetector(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def detect(self, frame):
|
def detect(self, frame: ndarray) -> list:
|
||||||
|
"""Detect motion and return motion boxes."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def is_calibrating(self):
|
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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
"""Stop any ongoing work and processes."""
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -35,12 +35,7 @@ class ImprovedMotionDetector(MotionDetector):
|
|||||||
self.avg_frame = np.zeros(self.motion_frame_size, np.float32)
|
self.avg_frame = np.zeros(self.motion_frame_size, np.float32)
|
||||||
self.motion_frame_count = 0
|
self.motion_frame_count = 0
|
||||||
self.frame_counter = 0
|
self.frame_counter = 0
|
||||||
resized_mask = cv2.resize(
|
self.update_mask()
|
||||||
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.save_images = False
|
self.save_images = False
|
||||||
self.calibrating = True
|
self.calibrating = True
|
||||||
self.blur_radius = blur_radius
|
self.blur_radius = blur_radius
|
||||||
@ -236,6 +231,14 @@ class ImprovedMotionDetector(MotionDetector):
|
|||||||
|
|
||||||
return motion_boxes
|
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:
|
def stop(self) -> None:
|
||||||
"""stop the motion detector."""
|
"""stop the motion detector."""
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -650,6 +650,9 @@ def process_frames(
|
|||||||
prev_enabled = camera_enabled
|
prev_enabled = camera_enabled
|
||||||
camera_enabled = camera_config.enabled
|
camera_enabled = camera_config.enabled
|
||||||
|
|
||||||
|
if "motion" in updated_configs:
|
||||||
|
motion_detector.update_mask()
|
||||||
|
|
||||||
if (
|
if (
|
||||||
not camera_enabled
|
not camera_enabled
|
||||||
and prev_enabled != camera_enabled
|
and prev_enabled != camera_enabled
|
||||||
|
|||||||
@ -161,6 +161,7 @@ export default function MotionMaskEditPane({
|
|||||||
axios
|
axios
|
||||||
.put(`config/set?${queryString}`, {
|
.put(`config/set?${queryString}`, {
|
||||||
requires_restart: 0,
|
requires_restart: 0,
|
||||||
|
update_topic: `config/cameras/${polygon.camera}/motion`,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user