mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-01 19:17:41 +03:00
Convert camera tracking to process
This commit is contained in:
parent
bd2cc18260
commit
4b913953a1
@ -22,7 +22,7 @@ from frigate.util import Process as FrigateProcess
|
|||||||
from frigate.util.builtin import empty_and_close_queue
|
from frigate.util.builtin import empty_and_close_queue
|
||||||
from frigate.util.image import SharedMemoryFrameManager, UntrackedSharedMemory
|
from frigate.util.image import SharedMemoryFrameManager, UntrackedSharedMemory
|
||||||
from frigate.util.object import get_camera_regions_grid
|
from frigate.util.object import get_camera_regions_grid
|
||||||
from frigate.video import capture_camera, track_camera
|
from frigate.video import CameraTracker, capture_camera
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -155,11 +155,7 @@ class CameraMaintainer(threading.Thread):
|
|||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
camera_process = FrigateProcess(
|
camera_process = CameraTracker(
|
||||||
target=track_camera,
|
|
||||||
name=f"camera_processor:{name}",
|
|
||||||
args=(
|
|
||||||
config.name,
|
|
||||||
config,
|
config,
|
||||||
self.config.model,
|
self.config.model,
|
||||||
self.config.model.merged_labelmap,
|
self.config.model.merged_labelmap,
|
||||||
@ -168,8 +164,6 @@ class CameraMaintainer(threading.Thread):
|
|||||||
self.camera_metrics[name],
|
self.camera_metrics[name],
|
||||||
self.ptz_metrics[name],
|
self.ptz_metrics[name],
|
||||||
self.region_grids[name],
|
self.region_grids[name],
|
||||||
),
|
|
||||||
daemon=True,
|
|
||||||
)
|
)
|
||||||
self.camera_processes[config.name] = camera_process
|
self.camera_processes[config.name] = camera_process
|
||||||
camera_process.start()
|
camera_process.start()
|
||||||
|
|||||||
@ -12,8 +12,6 @@ from typing import Any, Tuple
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
import frigate.util as util
|
import frigate.util as util
|
||||||
from frigate.camera import CameraMetrics
|
|
||||||
from logging.handlers import QueueHandler
|
|
||||||
from frigate.comms.detections_updater import DetectionPublisher, DetectionTypeEnum
|
from frigate.comms.detections_updater import DetectionPublisher, DetectionTypeEnum
|
||||||
from frigate.comms.event_metadata_updater import (
|
from frigate.comms.event_metadata_updater import (
|
||||||
EventMetadataPublisher,
|
EventMetadataPublisher,
|
||||||
|
|||||||
@ -14,6 +14,7 @@ from typing import Any
|
|||||||
import cv2
|
import cv2
|
||||||
from setproctitle import setproctitle
|
from setproctitle import setproctitle
|
||||||
|
|
||||||
|
import frigate.util as util
|
||||||
from frigate.camera import CameraMetrics, PTZMetrics
|
from frigate.camera import CameraMetrics, PTZMetrics
|
||||||
from frigate.comms.inter_process import InterProcessRequestor
|
from frigate.comms.inter_process import InterProcessRequestor
|
||||||
from frigate.config import CameraConfig, DetectConfig, ModelConfig
|
from frigate.config import CameraConfig, DetectConfig, ModelConfig
|
||||||
@ -53,7 +54,6 @@ from frigate.util.object import (
|
|||||||
is_object_filtered,
|
is_object_filtered,
|
||||||
reduce_detections,
|
reduce_detections,
|
||||||
)
|
)
|
||||||
from frigate.util.services import listen
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -467,8 +467,9 @@ def capture_camera(
|
|||||||
camera_watchdog.join()
|
camera_watchdog.join()
|
||||||
|
|
||||||
|
|
||||||
def track_camera(
|
class CameraTracker(util.Process):
|
||||||
name,
|
def __init__(
|
||||||
|
self,
|
||||||
config: CameraConfig,
|
config: CameraConfig,
|
||||||
model_config: ModelConfig,
|
model_config: ModelConfig,
|
||||||
labelmap: dict[int, str],
|
labelmap: dict[int, str],
|
||||||
@ -477,35 +478,38 @@ def track_camera(
|
|||||||
camera_metrics: CameraMetrics,
|
camera_metrics: CameraMetrics,
|
||||||
ptz_metrics: PTZMetrics,
|
ptz_metrics: PTZMetrics,
|
||||||
region_grid: list[list[dict[str, Any]]],
|
region_grid: list[list[dict[str, Any]]],
|
||||||
):
|
) -> None:
|
||||||
stop_event = mp.Event()
|
super().__init__(name=f"camera_processor:{config.name}", daemon=True)
|
||||||
|
self.config = config
|
||||||
|
self.model_config = model_config
|
||||||
|
self.labelmap = labelmap
|
||||||
|
self.detection_queue = detection_queue
|
||||||
|
self.detected_objects_queue = detected_objects_queue
|
||||||
|
self.camera_metrics = camera_metrics
|
||||||
|
self.ptz_metrics = ptz_metrics
|
||||||
|
self.region_grid = region_grid
|
||||||
|
|
||||||
def receiveSignal(signalNumber, frame):
|
def run(self) -> None:
|
||||||
stop_event.set()
|
self.pre_run_setup()
|
||||||
|
frame_queue = self.camera_metrics.frame_queue
|
||||||
signal.signal(signal.SIGTERM, receiveSignal)
|
frame_shape = self.config.frame_shape
|
||||||
signal.signal(signal.SIGINT, receiveSignal)
|
|
||||||
|
|
||||||
threading.current_thread().name = f"process:{name}"
|
|
||||||
setproctitle(f"frigate.process:{name}")
|
|
||||||
listen()
|
|
||||||
|
|
||||||
frame_queue = camera_metrics.frame_queue
|
|
||||||
|
|
||||||
frame_shape = config.frame_shape
|
|
||||||
|
|
||||||
motion_detector = ImprovedMotionDetector(
|
motion_detector = ImprovedMotionDetector(
|
||||||
frame_shape,
|
frame_shape,
|
||||||
config.motion,
|
self.config.motion,
|
||||||
config.detect.fps,
|
self.config.detect.fps,
|
||||||
name=config.name,
|
name=self.config.name,
|
||||||
ptz_metrics=ptz_metrics,
|
ptz_metrics=self.ptz_metrics,
|
||||||
)
|
)
|
||||||
object_detector = RemoteObjectDetector(
|
object_detector = RemoteObjectDetector(
|
||||||
name, labelmap, detection_queue, model_config, stop_event
|
self.config.name,
|
||||||
|
self.labelmap,
|
||||||
|
self.detection_queue,
|
||||||
|
self.model_config,
|
||||||
|
self.stop_event,
|
||||||
)
|
)
|
||||||
|
|
||||||
object_tracker = NorfairTracker(config, ptz_metrics)
|
object_tracker = NorfairTracker(self.config, self.ptz_metrics)
|
||||||
|
|
||||||
frame_manager = SharedMemoryFrameManager()
|
frame_manager = SharedMemoryFrameManager()
|
||||||
|
|
||||||
@ -513,30 +517,29 @@ def track_camera(
|
|||||||
requestor = InterProcessRequestor()
|
requestor = InterProcessRequestor()
|
||||||
|
|
||||||
process_frames(
|
process_frames(
|
||||||
name,
|
|
||||||
requestor,
|
requestor,
|
||||||
frame_queue,
|
frame_queue,
|
||||||
frame_shape,
|
frame_shape,
|
||||||
model_config,
|
self.model_config,
|
||||||
config,
|
self.config,
|
||||||
frame_manager,
|
frame_manager,
|
||||||
motion_detector,
|
motion_detector,
|
||||||
object_detector,
|
object_detector,
|
||||||
object_tracker,
|
object_tracker,
|
||||||
detected_objects_queue,
|
self.detected_objects_queue,
|
||||||
camera_metrics,
|
self.camera_metrics,
|
||||||
stop_event,
|
self.stop_event,
|
||||||
ptz_metrics,
|
self.ptz_metrics,
|
||||||
region_grid,
|
self.region_grid,
|
||||||
)
|
)
|
||||||
|
|
||||||
# empty the frame queue
|
# empty the frame queue
|
||||||
logger.info(f"{name}: emptying frame queue")
|
logger.info(f"{self.config.name}: emptying frame queue")
|
||||||
while not frame_queue.empty():
|
while not frame_queue.empty():
|
||||||
(frame_name, _) = frame_queue.get(False)
|
(frame_name, _) = frame_queue.get(False)
|
||||||
frame_manager.delete(frame_name)
|
frame_manager.delete(frame_name)
|
||||||
|
|
||||||
logger.info(f"{name}: exiting subprocess")
|
logger.info(f"{self.config.name}: exiting subprocess")
|
||||||
|
|
||||||
|
|
||||||
def detect(
|
def detect(
|
||||||
@ -577,7 +580,6 @@ def detect(
|
|||||||
|
|
||||||
|
|
||||||
def process_frames(
|
def process_frames(
|
||||||
camera_name: str,
|
|
||||||
requestor: InterProcessRequestor,
|
requestor: InterProcessRequestor,
|
||||||
frame_queue: Queue,
|
frame_queue: Queue,
|
||||||
frame_shape: tuple[int, int],
|
frame_shape: tuple[int, int],
|
||||||
@ -597,7 +599,7 @@ def process_frames(
|
|||||||
next_region_update = get_tomorrow_at_time(2)
|
next_region_update = get_tomorrow_at_time(2)
|
||||||
config_subscriber = CameraConfigUpdateSubscriber(
|
config_subscriber = CameraConfigUpdateSubscriber(
|
||||||
None,
|
None,
|
||||||
{camera_name: camera_config},
|
{camera_config.name: camera_config},
|
||||||
[
|
[
|
||||||
CameraConfigUpdateEnum.detect,
|
CameraConfigUpdateEnum.detect,
|
||||||
CameraConfigUpdateEnum.enabled,
|
CameraConfigUpdateEnum.enabled,
|
||||||
@ -653,7 +655,9 @@ def process_frames(
|
|||||||
and prev_enabled != camera_enabled
|
and prev_enabled != camera_enabled
|
||||||
and camera_metrics.frame_queue.empty()
|
and camera_metrics.frame_queue.empty()
|
||||||
):
|
):
|
||||||
logger.debug(f"Camera {camera_name} disabled, clearing tracked objects")
|
logger.debug(
|
||||||
|
f"Camera {camera_config.name} disabled, clearing tracked objects"
|
||||||
|
)
|
||||||
prev_enabled = camera_enabled
|
prev_enabled = camera_enabled
|
||||||
|
|
||||||
# Clear norfair's dictionaries
|
# Clear norfair's dictionaries
|
||||||
@ -678,7 +682,7 @@ def process_frames(
|
|||||||
datetime.datetime.now().astimezone(datetime.timezone.utc)
|
datetime.datetime.now().astimezone(datetime.timezone.utc)
|
||||||
> next_region_update
|
> next_region_update
|
||||||
):
|
):
|
||||||
region_grid = requestor.send_data(REQUEST_REGION_GRID, camera_name)
|
region_grid = requestor.send_data(REQUEST_REGION_GRID, camera_config.name)
|
||||||
next_region_update = get_tomorrow_at_time(2)
|
next_region_update = get_tomorrow_at_time(2)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -698,7 +702,9 @@ def process_frames(
|
|||||||
frame = frame_manager.get(frame_name, (frame_shape[0] * 3 // 2, frame_shape[1]))
|
frame = frame_manager.get(frame_name, (frame_shape[0] * 3 // 2, frame_shape[1]))
|
||||||
|
|
||||||
if frame is None:
|
if frame is None:
|
||||||
logger.debug(f"{camera_name}: frame {frame_time} is not in memory store.")
|
logger.debug(
|
||||||
|
f"{camera_config.name}: frame {frame_time} is not in memory store."
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# look for motion if enabled
|
# look for motion if enabled
|
||||||
@ -937,7 +943,7 @@ def process_frames(
|
|||||||
)
|
)
|
||||||
|
|
||||||
cv2.imwrite(
|
cv2.imwrite(
|
||||||
f"debug/frames/{camera_name}-{'{:.6f}'.format(frame_time)}.jpg",
|
f"debug/frames/{camera_config.name}-{'{:.6f}'.format(frame_time)}.jpg",
|
||||||
bgr_frame,
|
bgr_frame,
|
||||||
)
|
)
|
||||||
# add to the queue if not full
|
# add to the queue if not full
|
||||||
@ -949,7 +955,7 @@ def process_frames(
|
|||||||
camera_metrics.process_fps.value = fps_tracker.eps()
|
camera_metrics.process_fps.value = fps_tracker.eps()
|
||||||
detected_objects_queue.put(
|
detected_objects_queue.put(
|
||||||
(
|
(
|
||||||
camera_name,
|
camera_config.name,
|
||||||
frame_name,
|
frame_name,
|
||||||
frame_time,
|
frame_time,
|
||||||
detections,
|
detections,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user