mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-05 10:45:21 +03:00
implement and use cnt bgsub
This commit is contained in:
parent
18318fbde0
commit
3b74c79919
117
frigate/motion/cnt_motion.py
Normal file
117
frigate/motion/cnt_motion.py
Normal file
@ -0,0 +1,117 @@
|
||||
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,
|
||||
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()
|
||||
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
|
||||
@ -18,7 +18,7 @@ from frigate.config import CameraConfig, DetectConfig, PixelFormatEnum
|
||||
from frigate.const import CACHE_DIR
|
||||
from frigate.log import LogPipe
|
||||
from frigate.motion import MotionDetector
|
||||
from frigate.motion.frigate_motion import FrigateMotionDetector
|
||||
from frigate.motion.cnt_motion import CNTMotionDetector
|
||||
from frigate.object_detection import RemoteObjectDetector
|
||||
from frigate.track import ObjectTracker
|
||||
from frigate.track.norfair_tracker import NorfairTracker
|
||||
@ -463,7 +463,7 @@ def track_camera(
|
||||
objects_to_track = config.objects.track
|
||||
object_filters = config.objects.filters
|
||||
|
||||
motion_detector = FrigateMotionDetector(
|
||||
motion_detector = CNTMotionDetector(
|
||||
frame_shape,
|
||||
config.motion,
|
||||
improve_contrast_enabled,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user