Cleanup motion mypy

This commit is contained in:
Nicolas Mowen 2026-03-25 11:10:08 -06:00
parent 80c4ce2b5d
commit 706ba0c9c7
3 changed files with 41 additions and 34 deletions

View File

@ -1,7 +1,9 @@
from typing import Any
import cv2
import numpy as np
from frigate.config import MotionConfig
from frigate.config.config import RuntimeMotionConfig
from frigate.motion import MotionDetector
from frigate.util.image import grab_cv2_contours
@ -9,19 +11,20 @@ from frigate.util.image import grab_cv2_contours
class FrigateMotionDetector(MotionDetector):
def __init__(
self,
frame_shape,
config: MotionConfig,
frame_shape: tuple[int, ...],
config: RuntimeMotionConfig,
fps: int,
improve_contrast,
threshold,
contour_area,
):
improve_contrast: Any,
threshold: Any,
contour_area: Any,
) -> None:
self.config = config
self.frame_shape = frame_shape
self.resize_factor = frame_shape[0] / config.frame_height
frame_height = config.frame_height or frame_shape[0]
self.resize_factor = frame_shape[0] / frame_height
self.motion_frame_size = (
config.frame_height,
config.frame_height * frame_shape[1] // frame_shape[0],
frame_height,
frame_height * frame_shape[1] // frame_shape[0],
)
self.avg_frame = np.zeros(self.motion_frame_size, np.float32)
self.avg_delta = np.zeros(self.motion_frame_size, np.float32)
@ -38,10 +41,10 @@ class FrigateMotionDetector(MotionDetector):
self.threshold = threshold
self.contour_area = contour_area
def is_calibrating(self):
def is_calibrating(self) -> bool:
return False
def detect(self, frame):
def detect(self, frame: np.ndarray) -> list:
motion_boxes = []
gray = frame[0 : self.frame_shape[0], 0 : self.frame_shape[1]]
@ -99,7 +102,7 @@ class FrigateMotionDetector(MotionDetector):
# dilate the thresholded image to fill in holes, then find contours
# on thresholded image
thresh_dilated = cv2.dilate(thresh, None, iterations=2)
thresh_dilated = cv2.dilate(thresh, None, iterations=2) # type: ignore[call-overload]
contours = cv2.findContours(
thresh_dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)

View File

@ -4,8 +4,11 @@ import cv2
import numpy as np
from scipy.ndimage import gaussian_filter
from typing import Any, Optional
from frigate.camera import PTZMetrics
from frigate.config import MotionConfig
from frigate.config.config import RuntimeMotionConfig
from frigate.motion import MotionDetector
from frigate.util.image import grab_cv2_contours
@ -15,22 +18,23 @@ logger = logging.getLogger(__name__)
class ImprovedMotionDetector(MotionDetector):
def __init__(
self,
frame_shape,
config: MotionConfig,
frame_shape: tuple[int, ...],
config: RuntimeMotionConfig,
fps: int,
ptz_metrics: PTZMetrics = None,
name="improved",
blur_radius=1,
interpolation=cv2.INTER_NEAREST,
contrast_frame_history=50,
):
ptz_metrics: Optional[PTZMetrics] = None,
name: str = "improved",
blur_radius: int = 1,
interpolation: int = cv2.INTER_NEAREST,
contrast_frame_history: int = 50,
) -> None:
self.name = name
self.config = config
self.frame_shape = frame_shape
self.resize_factor = frame_shape[0] / config.frame_height
frame_height = config.frame_height or frame_shape[0]
self.resize_factor = frame_shape[0] / frame_height
self.motion_frame_size = (
config.frame_height,
config.frame_height * frame_shape[1] // frame_shape[0],
frame_height,
frame_height * frame_shape[1] // frame_shape[0],
)
self.avg_frame = np.zeros(self.motion_frame_size, np.float32)
self.motion_frame_count = 0
@ -44,20 +48,20 @@ class ImprovedMotionDetector(MotionDetector):
self.contrast_values[:, 1:2] = 255
self.contrast_values_index = 0
self.ptz_metrics = ptz_metrics
self.last_stop_time = None
self.last_stop_time: float | None = None
def is_calibrating(self):
def is_calibrating(self) -> bool:
return self.calibrating
def detect(self, frame):
motion_boxes = []
def detect(self, frame: np.ndarray) -> list[tuple[int, int, int, int]]:
motion_boxes: list[tuple[int, int, int, int]] = []
if not self.config.enabled:
return motion_boxes
# if ptz motor is moving from autotracking, quickly return
# a single box that is 80% of the frame
if (
if self.ptz_metrics is not None and (
self.ptz_metrics.autotracker_enabled.value
and not self.ptz_metrics.motor_stopped.is_set()
):
@ -130,19 +134,19 @@ class ImprovedMotionDetector(MotionDetector):
# dilate the thresholded image to fill in holes, then find contours
# on thresholded image
thresh_dilated = cv2.dilate(thresh, None, iterations=1)
thresh_dilated = cv2.dilate(thresh, None, iterations=1) # type: ignore[call-overload]
contours = cv2.findContours(
thresh_dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
contours = grab_cv2_contours(contours)
# loop over the contours
total_contour_area = 0
total_contour_area: float = 0
for c in contours:
# if the contour is big enough, count it as motion
contour_area = cv2.contourArea(c)
total_contour_area += contour_area
if contour_area > self.config.contour_area:
if contour_area > (self.config.contour_area or 0):
x, y, w, h = cv2.boundingRect(c)
motion_boxes.append(
(
@ -159,7 +163,7 @@ class ImprovedMotionDetector(MotionDetector):
# check if the motor has just stopped from autotracking
# if so, reassign the average to the current frame so we begin with a new baseline
if (
if self.ptz_metrics is not None and (
# ensure we only do this for cameras with autotracking enabled
self.ptz_metrics.autotracker_enabled.value
and self.ptz_metrics.motor_stopped.is_set()

View File

@ -47,7 +47,7 @@ ignore_errors = false
[mypy-frigate.jobs.*]
ignore_errors = false
[mypy-frigate.motion]
[mypy-frigate.motion.*]
ignore_errors = false
[mypy-frigate.object_detection]