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..44706f2c2 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -410,6 +410,24 @@ def set_sub_label(id): ) +@bp.route("/labels") +def get_labels(): + camera = request.args.get("camera", type=str, default="") + + try: + if camera: + events = Event.select(Event.label).where(Event.camera == camera).distinct() + else: + 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]) + 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..f60bce1d9 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 ALL_ATTRIBUTE_LABELS, ATTRIBUTE_LABEL_MAP, 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/Camera.jsx b/web/src/routes/Camera.jsx index 7f5e3ca77..11ae2cdea 100644 --- a/web/src/routes/Camera.jsx +++ b/web/src/routes/Camera.jsx @@ -22,6 +22,7 @@ const emptyObject = Object.freeze({}); export default function Camera({ camera }) { const { data: config } = useSWR('config'); + const { data: trackedLabels } = useSWR(['labels', { camera }]); const apiHost = useApiHost(); const [showSettings, setShowSettings] = useState(false); const [viewMode, setViewMode] = useState('live'); @@ -121,7 +122,9 @@ export default function Camera({ camera }) {
@@ -203,7 +206,7 @@ export default function Camera({ camera }) {
Tracked objects
- {cameraConfig.objects.track.map((objectType) => ( + {(trackedLabels || []).map((objectType) => ( 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) => {