mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-04 04:27:42 +03:00
Implement reset of tracked object update for each camera
This commit is contained in:
parent
6376fbe8cb
commit
119ec45c2f
@ -1552,6 +1552,12 @@ class LicensePlateProcessingMixin:
|
|||||||
(base64.b64encode(encoded_img).decode("ASCII"), id, camera),
|
(base64.b64encode(encoded_img).decode("ASCII"), id, camera),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if id not in self.detected_license_plates:
|
||||||
|
if camera not in self.camera_current_cars:
|
||||||
|
self.camera_current_cars[camera] = []
|
||||||
|
|
||||||
|
self.camera_current_cars[camera].append(id)
|
||||||
|
|
||||||
self.detected_license_plates[id] = {
|
self.detected_license_plates[id] = {
|
||||||
"plate": top_plate,
|
"plate": top_plate,
|
||||||
"char_confidences": top_char_confidences,
|
"char_confidences": top_char_confidences,
|
||||||
@ -1564,7 +1570,7 @@ class LicensePlateProcessingMixin:
|
|||||||
def handle_request(self, topic, request_data) -> dict[str, any] | None:
|
def handle_request(self, topic, request_data) -> dict[str, any] | None:
|
||||||
return
|
return
|
||||||
|
|
||||||
def expire_object(self, object_id: str):
|
def expire_object(self, object_id: str, camera: str):
|
||||||
if object_id in self.detected_license_plates:
|
if object_id in self.detected_license_plates:
|
||||||
self.detected_license_plates.pop(object_id)
|
self.detected_license_plates.pop(object_id)
|
||||||
|
|
||||||
|
|||||||
@ -50,10 +50,11 @@ class RealTimeProcessorApi(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def expire_object(self, object_id: str) -> None:
|
def expire_object(self, object_id: str, camera: str) -> None:
|
||||||
"""Handle objects that are no longer detected.
|
"""Handle objects that are no longer detected.
|
||||||
Args:
|
Args:
|
||||||
object_id (str): id of object that is no longer detected.
|
object_id (str): id of object that is no longer detected.
|
||||||
|
camera (str): name of camera that object was detected on.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None.
|
None.
|
||||||
|
|||||||
@ -152,6 +152,6 @@ class BirdRealTimeProcessor(RealTimeProcessorApi):
|
|||||||
def handle_request(self, topic, request_data):
|
def handle_request(self, topic, request_data):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def expire_object(self, object_id):
|
def expire_object(self, object_id, camera):
|
||||||
if object_id in self.detected_birds:
|
if object_id in self.detected_birds:
|
||||||
self.detected_birds.pop(object_id)
|
self.detected_birds.pop(object_id)
|
||||||
|
|||||||
@ -54,6 +54,7 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
|
|||||||
self.face_detector: cv2.FaceDetectorYN = None
|
self.face_detector: cv2.FaceDetectorYN = None
|
||||||
self.requires_face_detection = "face" not in self.config.objects.all_objects
|
self.requires_face_detection = "face" not in self.config.objects.all_objects
|
||||||
self.person_face_history: dict[str, list[tuple[str, float, int]]] = {}
|
self.person_face_history: dict[str, list[tuple[str, float, int]]] = {}
|
||||||
|
self.camera_current_people: dict[str, list[str]] = {}
|
||||||
self.recognizer: FaceRecognizer | None = None
|
self.recognizer: FaceRecognizer | None = None
|
||||||
self.faces_per_second = EventsPerSecond()
|
self.faces_per_second = EventsPerSecond()
|
||||||
self.inference_speed = InferenceSpeed(self.metrics.face_rec_speed)
|
self.inference_speed = InferenceSpeed(self.metrics.face_rec_speed)
|
||||||
@ -282,9 +283,13 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
|
|||||||
if id not in self.person_face_history:
|
if id not in self.person_face_history:
|
||||||
self.person_face_history[id] = []
|
self.person_face_history[id] = []
|
||||||
|
|
||||||
|
if camera not in self.camera_current_people:
|
||||||
|
self.camera_current_people[camera] = []
|
||||||
|
|
||||||
self.person_face_history[id].append(
|
self.person_face_history[id].append(
|
||||||
(sub_label, score, face_frame.shape[0] * face_frame.shape[1])
|
(sub_label, score, face_frame.shape[0] * face_frame.shape[1])
|
||||||
)
|
)
|
||||||
|
self.camera_current_people[camera].append(id)
|
||||||
(weighted_sub_label, weighted_score) = self.weighted_average(
|
(weighted_sub_label, weighted_score) = self.weighted_average(
|
||||||
self.person_face_history[id]
|
self.person_face_history[id]
|
||||||
)
|
)
|
||||||
@ -420,10 +425,26 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
|
|||||||
)
|
)
|
||||||
shutil.move(current_file, new_file)
|
shutil.move(current_file, new_file)
|
||||||
|
|
||||||
def expire_object(self, object_id: str):
|
def expire_object(self, object_id: str, camera: str):
|
||||||
if object_id in self.person_face_history:
|
if object_id in self.person_face_history:
|
||||||
self.person_face_history.pop(object_id)
|
self.person_face_history.pop(object_id)
|
||||||
|
|
||||||
|
if object_id in self.camera_current_people.get(camera, []):
|
||||||
|
self.camera_current_people[camera].remove(object_id)
|
||||||
|
|
||||||
|
if len(self.camera_current_people[camera]) == 0:
|
||||||
|
self.requestor.send_data(
|
||||||
|
"tracked_object_update",
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"type": TrackedObjectUpdateTypesEnum.face,
|
||||||
|
"name": None,
|
||||||
|
"id": id,
|
||||||
|
"camera": camera,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def weighted_average(
|
def weighted_average(
|
||||||
self, results_list: list[tuple[str, float, int]], max_weight: int = 4000
|
self, results_list: list[tuple[str, float, int]], max_weight: int = 4000
|
||||||
):
|
):
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
"""Handle processing images for face detection and recognition."""
|
"""Handle processing images for face detection and recognition."""
|
||||||
|
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -13,6 +14,7 @@ from frigate.data_processing.common.license_plate.mixin import (
|
|||||||
from frigate.data_processing.common.license_plate.model import (
|
from frigate.data_processing.common.license_plate.model import (
|
||||||
LicensePlateModelRunner,
|
LicensePlateModelRunner,
|
||||||
)
|
)
|
||||||
|
from frigate.types import TrackedObjectUpdateTypesEnum
|
||||||
|
|
||||||
from ..types import DataProcessorMetrics
|
from ..types import DataProcessorMetrics
|
||||||
from .api import RealTimeProcessorApi
|
from .api import RealTimeProcessorApi
|
||||||
@ -36,6 +38,7 @@ class LicensePlateRealTimeProcessor(LicensePlateProcessingMixin, RealTimeProcess
|
|||||||
self.lpr_config = config.lpr
|
self.lpr_config = config.lpr
|
||||||
self.config = config
|
self.config = config
|
||||||
self.sub_label_publisher = sub_label_publisher
|
self.sub_label_publisher = sub_label_publisher
|
||||||
|
self.camera_current_cars: dict[str, list[str]] = {}
|
||||||
super().__init__(config, metrics)
|
super().__init__(config, metrics)
|
||||||
|
|
||||||
def process_frame(
|
def process_frame(
|
||||||
@ -50,6 +53,22 @@ class LicensePlateRealTimeProcessor(LicensePlateProcessingMixin, RealTimeProcess
|
|||||||
def handle_request(self, topic, request_data) -> dict[str, any] | None:
|
def handle_request(self, topic, request_data) -> dict[str, any] | None:
|
||||||
return
|
return
|
||||||
|
|
||||||
def expire_object(self, object_id: str):
|
def expire_object(self, object_id: str, camera: str):
|
||||||
if object_id in self.detected_license_plates:
|
if object_id in self.detected_license_plates:
|
||||||
self.detected_license_plates.pop(object_id)
|
self.detected_license_plates.pop(object_id)
|
||||||
|
|
||||||
|
if object_id in self.camera_current_cars.get(camera, []):
|
||||||
|
self.camera_current_cars[camera].remove(object_id)
|
||||||
|
|
||||||
|
if len(self.camera_current_cars[camera]) == 0:
|
||||||
|
self.requestor.send_data(
|
||||||
|
"tracked_object_update",
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"type": TrackedObjectUpdateTypesEnum.face,
|
||||||
|
"name": None,
|
||||||
|
"id": id,
|
||||||
|
"camera": camera,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|||||||
@ -359,7 +359,7 @@ class EmbeddingMaintainer(threading.Thread):
|
|||||||
|
|
||||||
# expire in realtime processors
|
# expire in realtime processors
|
||||||
for processor in self.realtime_processors:
|
for processor in self.realtime_processors:
|
||||||
processor.expire_object(event_id)
|
processor.expire_object(event_id, camera)
|
||||||
|
|
||||||
if updated_db:
|
if updated_db:
|
||||||
try:
|
try:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user