diff --git a/frigate/const.py b/frigate/const.py index 9b7e177f2..28ce766e4 100644 --- a/frigate/const.py +++ b/frigate/const.py @@ -12,6 +12,16 @@ PLUS_ENV_VAR = "PLUS_API_KEY" PLUS_API_HOST = "https://api.frigate.video" BTBN_PATH = "/usr/lib/btbn-ffmpeg" +# Attributes + +ATTRIBUTE_LABEL_MAP = { + "person": ["face", "amazon"], + "car": ["ups", "fedex", "amazon", "license_plate"], +} +ALL_ATTRIBUTE_LABELS = [ + item for sublist in ATTRIBUTE_LABEL_MAP.values() for item in sublist +] + # Regex Consts REGEX_CAMERA_NAME = r"^[a-zA-Z0-9_-]+$" diff --git a/frigate/http.py b/frigate/http.py index b4813c1f2..655bd2928 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -29,7 +29,7 @@ from playhouse.shortcuts import model_to_dict from tzlocal import get_localzone_name from frigate.config import FrigateConfig -from frigate.const import CLIPS_DIR, MAX_SEGMENT_DURATION, RECORD_DIR +from frigate.const import ALL_ATTRIBUTE_LABELS, CLIPS_DIR, MAX_SEGMENT_DURATION, RECORD_DIR from frigate.events.external import ExternalEventProcessor from frigate.models import Event, Recordings, Timeline from frigate.object_processing import TrackedObject @@ -410,6 +410,19 @@ def set_sub_label(id): ) +@bp.route("/labels") +def get_labels(): + try: + events = Event.select(Event.label).distinct() + except Exception as e: + return jsonify( + {"success": False, "message": f"Failed to get labels: {e}"}, "404" + ) + + labels = sorted([e.label for e in events if e.label not in ALL_ATTRIBUTE_LABELS]) + return jsonify(labels) + + @bp.route("/sub_labels") def get_sub_labels(): split_joined = request.args.get("split_joined", type=int) diff --git a/frigate/video.py b/frigate/video.py index c02ad15c4..562050a20 100755 --- a/frigate/video.py +++ b/frigate/video.py @@ -15,7 +15,7 @@ import numpy as np from setproctitle import setproctitle from frigate.config import CameraConfig, DetectConfig -from frigate.const import CACHE_DIR +from frigate.const import ATTRIBUTE_LABEL_MAP, ALL_ATTRIBUTE_LABELS, CACHE_DIR from frigate.detectors.detector_config import PixelFormatEnum from frigate.log import LogPipe from frigate.motion import MotionDetector @@ -723,14 +723,6 @@ def process_frames( stop_event, exit_on_empty: bool = False, ): - # attribute labels are not tracked and are not assigned regions - attribute_label_map = { - "person": ["face", "amazon"], - "car": ["ups", "fedex", "amazon", "license_plate"], - } - all_attribute_labels = [ - item for sublist in attribute_label_map.values() for item in sublist - ] fps = process_info["process_fps"] detection_fps = process_info["detection_fps"] current_frame_time = process_info["detection_frame"] @@ -906,7 +898,7 @@ def process_frames( tracked_detections = [ d for d in consolidated_detections - if d[0] not in all_attribute_labels + if d[0] not in ALL_ATTRIBUTE_LABELS ] # now that we have refined our detections, we need to track objects object_tracker.match_and_update(frame_time, tracked_detections) @@ -916,7 +908,7 @@ def process_frames( # group the attribute detections based on what label they apply to attribute_detections = {} - for label, attribute_labels in attribute_label_map.items(): + for label, attribute_labels in ATTRIBUTE_LABEL_MAP.items(): attribute_detections[label] = [ d for d in consolidated_detections if d[0] in attribute_labels ] diff --git a/web/src/routes/Events.jsx b/web/src/routes/Events.jsx index 21b282a53..8de35413b 100644 --- a/web/src/routes/Events.jsx +++ b/web/src/routes/Events.jsx @@ -106,6 +106,7 @@ export default function Events({ path, ...props }) { const { data: config } = useSWR('config'); + const { data: allLabels } = useSWR(['labels']); const { data: allSubLabels } = useSWR(['sub_labels', { split_joined: 1 }]); const filterValues = useMemo( @@ -120,15 +121,10 @@ export default function Events({ path, ...props }) { .filter((value, i, self) => self.indexOf(value) === i), 'None', ], - labels: Object.values(config?.cameras || {}) - .reduce((memo, camera) => { - memo = memo.concat(camera?.objects?.track || []); - return memo; - }, config?.objects?.track || []) - .filter((value, i, self) => self.indexOf(value) === i), + labels: Object.values(allLabels || {}), sub_labels: (allSubLabels || []).length > 0 ? [...Object.values(allSubLabels), 'None'] : [], }), - [config, allSubLabels] + [config, allLabels, allSubLabels] ); const onSave = async (e, eventId, save) => {