Move tracked object logic to own function

This commit is contained in:
Nick Mowen 2023-04-29 12:46:46 -06:00
parent f295305a06
commit f23d133387

View File

@ -3,7 +3,10 @@ import logging
import os import os
import queue import queue
import threading import threading
from pathlib import Path from pathlib import Path
from typing import Any
from peewee import fn from peewee import fn
@ -58,6 +61,98 @@ class EventProcessor(threading.Thread):
self.events_in_process: Dict[str, Event] = {} self.events_in_process: Dict[str, Event] = {}
self.stop_event = stop_event self.stop_event = stop_event
def handle_object_detection(
self, event_type: str, camera: str, event_data: dict[str, Any]
) -> None:
"""handle tracked object event updates."""
# if this is the first message, just store it and continue, its not time to insert it in the db
if should_update_db(self.events_in_process[event_data["id"]], event_data):
camera_config = self.config.cameras[camera]
event_config: EventsConfig = camera_config.record.events
width = camera_config.detect.width
height = camera_config.detect.height
first_detector = list(self.config.detectors.values())[0]
start_time = event_data["start_time"] - event_config.pre_capture
end_time = (
None
if event_data["end_time"] is None
else event_data["end_time"] + event_config.post_capture
)
# score of the snapshot
score = (
None
if event_data["snapshot"] is None
else event_data["snapshot"]["score"]
)
# detection region in the snapshot
region = (
None
if event_data["snapshot"] is None
else to_relative_box(
width,
height,
event_data["snapshot"]["region"],
)
)
# bounding box for the snapshot
box = (
None
if event_data["snapshot"] is None
else to_relative_box(
width,
height,
event_data["snapshot"]["box"],
)
)
# keep these from being set back to false because the event
# may have started while recordings and snapshots were enabled
# this would be an issue for long running events
if self.events_in_process[event_data["id"]]["has_clip"]:
event_data["has_clip"] = True
if self.events_in_process[event_data["id"]]["has_snapshot"]:
event_data["has_snapshot"] = True
event = {
Event.id: event_data["id"],
Event.label: event_data["label"],
Event.camera: camera,
Event.start_time: start_time,
Event.end_time: end_time,
Event.zones: list(event_data["entered_zones"]),
Event.thumbnail: event_data["thumbnail"],
Event.has_clip: event_data["has_clip"],
Event.has_snapshot: event_data["has_snapshot"],
Event.model_hash: first_detector.model.model_hash,
Event.model_type: first_detector.model.model_type,
Event.detector_type: first_detector.type,
Event.data: {
"area": event_data.get("area", 0),
"box": box,
"ratio": event_data.get("ratio", width / height),
"region": region,
"score": score,
"top_score": event_data["top_score"],
},
}
(
Event.insert(event)
.on_conflict(
conflict_target=[Event.id],
update=event,
)
.execute()
)
# update the stored copy for comparison on future update messages
self.events_in_process[event_data["id"]] = event_data
if event_type == "end":
del self.events_in_process[event_data["id"]]
self.event_processed_queue.put((event_data["id"], camera))
def run(self) -> None: def run(self) -> None:
# set an end_time on events without an end_time on startup # set an end_time on events without an end_time on startup
Event.update(end_time=Event.start_time + 30).where( Event.update(end_time=Event.start_time + 30).where(
@ -66,7 +161,9 @@ class EventProcessor(threading.Thread):
while not self.stop_event.is_set(): while not self.stop_event.is_set():
try: try:
event_type, camera, event_data = self.event_queue.get(timeout=1) source_type, event_type, camera, event_data = self.event_queue.get(
timeout=1
)
except queue.Empty: except queue.Empty:
continue continue
@ -75,104 +172,19 @@ class EventProcessor(threading.Thread):
self.timeline_queue.put( self.timeline_queue.put(
( (
camera, camera,
TimelineSourceEnum.tracked_object, source_type,
event_type, event_type,
self.events_in_process.get(event_data["id"]), self.events_in_process.get(event_data["id"]),
event_data, event_data,
) )
) )
# if this is the first message, just store it and continue, its not time to insert it in the db if source_type == TimelineSourceEnum.tracked_object:
if event_type == "start": if event_type == "start":
self.events_in_process[event_data["id"]] = event_data self.events_in_process[event_data["id"]] = event_data
continue continue
if should_update_db(self.events_in_process[event_data["id"]], event_data): self.handle_object_detection(event_type, camera, event_data)
camera_config = self.config.cameras[camera]
event_config: EventsConfig = camera_config.record.events
width = camera_config.detect.width
height = camera_config.detect.height
first_detector = list(self.config.detectors.values())[0]
start_time = event_data["start_time"] - event_config.pre_capture
end_time = (
None
if event_data["end_time"] is None
else event_data["end_time"] + event_config.post_capture
)
# score of the snapshot
score = (
None
if event_data["snapshot"] is None
else event_data["snapshot"]["score"]
)
# detection region in the snapshot
region = (
None
if event_data["snapshot"] is None
else to_relative_box(
width,
height,
event_data["snapshot"]["region"],
)
)
# bounding box for the snapshot
box = (
None
if event_data["snapshot"] is None
else to_relative_box(
width,
height,
event_data["snapshot"]["box"],
)
)
# keep these from being set back to false because the event
# may have started while recordings and snapshots were enabled
# this would be an issue for long running events
if self.events_in_process[event_data["id"]]["has_clip"]:
event_data["has_clip"] = True
if self.events_in_process[event_data["id"]]["has_snapshot"]:
event_data["has_snapshot"] = True
event = {
Event.id: event_data["id"],
Event.label: event_data["label"],
Event.camera: camera,
Event.start_time: start_time,
Event.end_time: end_time,
Event.zones: list(event_data["entered_zones"]),
Event.thumbnail: event_data["thumbnail"],
Event.has_clip: event_data["has_clip"],
Event.has_snapshot: event_data["has_snapshot"],
Event.model_hash: first_detector.model.model_hash,
Event.model_type: first_detector.model.model_type,
Event.detector_type: first_detector.type,
Event.data: {
"area": event_data.get("area", 0),
"box": box,
"ratio": event_data.get("ratio", width / height),
"region": region,
"score": score,
"top_score": event_data["top_score"],
}
}
(
Event.insert(event)
.on_conflict(
conflict_target=[Event.id],
update=event,
)
.execute()
)
# update the stored copy for comparison on future update messages
self.events_in_process[event_data["id"]] = event_data
if event_type == "end":
del self.events_in_process[event_data["id"]]
self.event_processed_queue.put((event_data["id"], camera))
# set an end_time on events without an end_time before exiting # set an end_time on events without an end_time before exiting
Event.update(end_time=datetime.datetime.now().timestamp()).where( Event.update(end_time=datetime.datetime.now().timestamp()).where(