mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-05 10:45:21 +03:00
update default motion config
This commit is contained in:
parent
a1dce08bfc
commit
59e5ed6a89
@ -261,33 +261,29 @@ motion:
|
|||||||
# Optional: The threshold passed to cv2.threshold to determine if a pixel is different enough to be counted as motion. (default: shown below)
|
# Optional: The threshold passed to cv2.threshold to determine if a pixel is different enough to be counted as motion. (default: shown below)
|
||||||
# Increasing this value will make motion detection less sensitive and decreasing it will make motion detection more sensitive.
|
# Increasing this value will make motion detection less sensitive and decreasing it will make motion detection more sensitive.
|
||||||
# The value should be between 1 and 255.
|
# The value should be between 1 and 255.
|
||||||
threshold: 25
|
threshold: 40
|
||||||
# Optional: The percentage of the image used to detect lightning or other substantial changes where motion detection
|
# Optional: The percentage of the image used to detect lightning or other substantial changes where motion detection
|
||||||
# needs to recalibrate. (default: shown below)
|
# needs to recalibrate. (default: shown below)
|
||||||
# Increasing this value will make motion detection more likely to consider lightning or ir mode changes as valid motion.
|
# Increasing this value will make motion detection more likely to consider lightning or ir mode changes as valid motion.
|
||||||
# Decreasing this value will make motion detection more likely to ignore large amounts of motion such as a person approaching
|
# Decreasing this value will make motion detection more likely to ignore large amounts of motion such as a person approaching
|
||||||
# a doorbell camera.
|
# a doorbell camera.
|
||||||
lightning_threshold: 0.8
|
lightning_threshold: 0.8
|
||||||
# Optional: Minimum size in pixels in the resized motion image that counts as motion (default: 30)
|
# Optional: Minimum size in pixels in the resized motion image that counts as motion (default: shown below)
|
||||||
# Increasing this value will prevent smaller areas of motion from being detected. Decreasing will
|
# Increasing this value will prevent smaller areas of motion from being detected. Decreasing will
|
||||||
# make motion detection more sensitive to smaller moving objects.
|
# make motion detection more sensitive to smaller moving objects.
|
||||||
# As a rule of thumb:
|
# As a rule of thumb:
|
||||||
# - 15 - high sensitivity
|
# - 15 - high sensitivity
|
||||||
# - 30 - medium sensitivity
|
# - 30 - medium sensitivity
|
||||||
# - 50 - low sensitivity
|
# - 50 - low sensitivity
|
||||||
contour_area: 30
|
contour_area: 15
|
||||||
# Optional: Alpha value passed to cv2.accumulateWeighted when averaging the motion delta across multiple frames (default: shown below)
|
|
||||||
# Higher values mean the current frame impacts the delta a lot, and a single raindrop may register as motion.
|
|
||||||
# Too low and a fast moving person wont be detected as motion.
|
|
||||||
delta_alpha: 0.2
|
|
||||||
# Optional: Alpha value passed to cv2.accumulateWeighted when averaging frames to determine the background (default: shown below)
|
# Optional: Alpha value passed to cv2.accumulateWeighted when averaging frames to determine the background (default: shown below)
|
||||||
# Higher values mean the current frame impacts the average a lot, and a new object will be averaged into the background faster.
|
# Higher values mean the current frame impacts the average a lot, and a new object will be averaged into the background faster.
|
||||||
# Low values will cause things like moving shadows to be detected as motion for longer.
|
# Low values will cause things like moving shadows to be detected as motion for longer.
|
||||||
# https://www.geeksforgeeks.org/background-subtraction-in-an-image-using-concept-of-running-average/
|
# https://www.geeksforgeeks.org/background-subtraction-in-an-image-using-concept-of-running-average/
|
||||||
frame_alpha: 0.2
|
frame_alpha: 0.02
|
||||||
# Optional: Height of the resized motion frame (default: 50)
|
# Optional: Height of the resized motion frame (default: 50)
|
||||||
# This operates as an efficient blur alternative. Higher values will result in more granular motion detection at the expense
|
# Higher values will result in more granular motion detection at the expense of higher CPU usage.
|
||||||
# of higher CPU usage. Lower values result in less CPU, but small changes may not register as motion.
|
# Lower values result in less CPU, but small changes may not register as motion.
|
||||||
frame_height: 50
|
frame_height: 50
|
||||||
# Optional: motion mask
|
# Optional: motion mask
|
||||||
# NOTE: see docs for more detailed info on creating masks
|
# NOTE: see docs for more detailed info on creating masks
|
||||||
@ -295,7 +291,7 @@ motion:
|
|||||||
# Optional: improve contrast (default: shown below)
|
# Optional: improve contrast (default: shown below)
|
||||||
# Enables dynamic contrast improvement. This should help improve night detections at the cost of making motion detection more sensitive
|
# Enables dynamic contrast improvement. This should help improve night detections at the cost of making motion detection more sensitive
|
||||||
# for daytime.
|
# for daytime.
|
||||||
improve_contrast: False
|
improve_contrast: True
|
||||||
# Optional: Delay when updating camera motion through MQTT from ON -> OFF (default: shown below).
|
# Optional: Delay when updating camera motion through MQTT from ON -> OFF (default: shown below).
|
||||||
mqtt_off_delay: 30
|
mqtt_off_delay: 30
|
||||||
|
|
||||||
|
|||||||
@ -191,7 +191,7 @@ class RecordConfig(FrigateBaseModel):
|
|||||||
|
|
||||||
class MotionConfig(FrigateBaseModel):
|
class MotionConfig(FrigateBaseModel):
|
||||||
threshold: int = Field(
|
threshold: int = Field(
|
||||||
default=25,
|
default=40,
|
||||||
title="Motion detection threshold (1-255).",
|
title="Motion detection threshold (1-255).",
|
||||||
ge=1,
|
ge=1,
|
||||||
le=255,
|
le=255,
|
||||||
@ -199,10 +199,10 @@ class MotionConfig(FrigateBaseModel):
|
|||||||
lightning_threshold: float = Field(
|
lightning_threshold: float = Field(
|
||||||
default=0.8, title="Lightning detection threshold (0.3-1.0).", ge=0.3, le=1.0
|
default=0.8, title="Lightning detection threshold (0.3-1.0).", ge=0.3, le=1.0
|
||||||
)
|
)
|
||||||
improve_contrast: bool = Field(default=False, title="Improve Contrast")
|
improve_contrast: bool = Field(default=True, title="Improve Contrast")
|
||||||
contour_area: Optional[int] = Field(default=30, title="Contour Area")
|
contour_area: Optional[int] = Field(default=15, title="Contour Area")
|
||||||
delta_alpha: float = Field(default=0.2, title="Delta Alpha")
|
delta_alpha: float = Field(default=0.2, title="Delta Alpha")
|
||||||
frame_alpha: float = Field(default=0.2, title="Frame Alpha")
|
frame_alpha: float = Field(default=0.02, title="Frame Alpha")
|
||||||
frame_height: Optional[int] = Field(default=50, title="Frame Height")
|
frame_height: Optional[int] = Field(default=50, title="Frame Height")
|
||||||
mask: Union[str, List[str]] = Field(
|
mask: Union[str, List[str]] = Field(
|
||||||
default="", title="Coordinates polygon for the motion mask."
|
default="", title="Coordinates polygon for the motion mask."
|
||||||
|
|||||||
@ -1,120 +0,0 @@
|
|||||||
from typing import Tuple
|
|
||||||
|
|
||||||
import cv2
|
|
||||||
import imutils
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from frigate.config import MotionConfig
|
|
||||||
from frigate.motion import MotionDetector
|
|
||||||
|
|
||||||
|
|
||||||
class CNTMotionDetector(MotionDetector):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
frame_shape: Tuple[int, int, int],
|
|
||||||
config: MotionConfig,
|
|
||||||
fps: int,
|
|
||||||
improve_contrast,
|
|
||||||
threshold,
|
|
||||||
contour_area,
|
|
||||||
):
|
|
||||||
self.frame_shape = frame_shape
|
|
||||||
self.threshold = threshold
|
|
||||||
self.contour_area = contour_area
|
|
||||||
self.improve_contrast = improve_contrast
|
|
||||||
self.resize_factor = frame_shape[0] / config.frame_height
|
|
||||||
self.motion_frame_size = (
|
|
||||||
config.frame_height,
|
|
||||||
config.frame_height * frame_shape[1] // frame_shape[0],
|
|
||||||
)
|
|
||||||
resized_mask = cv2.resize(
|
|
||||||
config.mask,
|
|
||||||
dsize=(self.motion_frame_size[1], self.motion_frame_size[0]),
|
|
||||||
interpolation=cv2.INTER_LINEAR,
|
|
||||||
)
|
|
||||||
self.blur_kernel = (
|
|
||||||
3, # int(0.05 * self.motion_frame_size[0]),
|
|
||||||
3, # int(0.05 * self.motion_frame_size[0]),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.mask = np.where(resized_mask == [0])
|
|
||||||
# createBackgroundSubtractorCNT(int minPixelStability = 15,
|
|
||||||
# bool useHistory = true,
|
|
||||||
# int maxPixelStability = 15*60,
|
|
||||||
# bool isParallel = true);
|
|
||||||
self.bg_subtractor = cv2.bgsegm.createBackgroundSubtractorCNT(
|
|
||||||
fps, True, fps * 60, True
|
|
||||||
)
|
|
||||||
self.save_images = False
|
|
||||||
self.frame_counter = 0
|
|
||||||
|
|
||||||
def detect(self, frame):
|
|
||||||
motion_boxes = []
|
|
||||||
gray = frame[0 : self.frame_shape[0], 0 : self.frame_shape[1]]
|
|
||||||
# resize frame
|
|
||||||
resized_frame = cv2.resize(
|
|
||||||
gray,
|
|
||||||
dsize=(self.motion_frame_size[1], self.motion_frame_size[0]),
|
|
||||||
interpolation=cv2.INTER_LINEAR,
|
|
||||||
)
|
|
||||||
if self.improve_contrast.value:
|
|
||||||
resized_frame = cv2.equalizeHist(resized_frame)
|
|
||||||
blurred_frame = cv2.GaussianBlur(
|
|
||||||
resized_frame, self.blur_kernel, cv2.BORDER_DEFAULT
|
|
||||||
)
|
|
||||||
# mask frame
|
|
||||||
blurred_frame[self.mask] = [255]
|
|
||||||
fg = self.bg_subtractor.apply(blurred_frame)
|
|
||||||
thresh = cv2.threshold(fg, self.threshold.value, 255, cv2.THRESH_BINARY)[1]
|
|
||||||
|
|
||||||
# dilate the thresholded image to fill in holes, then find contours
|
|
||||||
# on thresholded image
|
|
||||||
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
|
||||||
cnts = imutils.grab_contours(cnts)
|
|
||||||
|
|
||||||
# loop over the contours
|
|
||||||
for c in cnts:
|
|
||||||
# if the contour is big enough, count it as motion
|
|
||||||
contour_area = cv2.contourArea(c)
|
|
||||||
if contour_area > self.contour_area.value:
|
|
||||||
x, y, w, h = cv2.boundingRect(c)
|
|
||||||
motion_boxes.append(
|
|
||||||
(
|
|
||||||
int(x * self.resize_factor),
|
|
||||||
int(y * self.resize_factor),
|
|
||||||
int((x + w) * self.resize_factor),
|
|
||||||
int((y + h) * self.resize_factor),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.save_images:
|
|
||||||
self.frame_counter += 1
|
|
||||||
# print("--------")
|
|
||||||
# print(self.frame_counter)
|
|
||||||
thresh_boxes = cv2.cvtColor(fg, cv2.COLOR_GRAY2BGR)
|
|
||||||
for c in cnts:
|
|
||||||
contour_area = cv2.contourArea(c)
|
|
||||||
if contour_area > self.contour_area.value:
|
|
||||||
x, y, w, h = cv2.boundingRect(c)
|
|
||||||
cv2.rectangle(
|
|
||||||
thresh_boxes,
|
|
||||||
(x, y),
|
|
||||||
(x + w, y + h),
|
|
||||||
(0, 0, 255),
|
|
||||||
2,
|
|
||||||
)
|
|
||||||
# print("--------")
|
|
||||||
image_row_1 = cv2.hconcat(
|
|
||||||
[
|
|
||||||
cv2.cvtColor(fg, cv2.COLOR_GRAY2BGR),
|
|
||||||
cv2.cvtColor(
|
|
||||||
self.bg_subtractor.getBackgroundImage(), cv2.COLOR_GRAY2BGR
|
|
||||||
),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
image_row_2 = cv2.hconcat(
|
|
||||||
[cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR), thresh_boxes]
|
|
||||||
)
|
|
||||||
combined_image = cv2.vconcat([image_row_1, image_row_2])
|
|
||||||
cv2.imwrite(f"debug/frames/motion-{self.frame_counter}.jpg", combined_image)
|
|
||||||
return motion_boxes
|
|
||||||
Loading…
Reference in New Issue
Block a user