diff --git a/docs/docs/integrations/mqtt.md b/docs/docs/integrations/mqtt.md index 814656258..cde760559 100644 --- a/docs/docs/integrations/mqtt.md +++ b/docs/docs/integrations/mqtt.md @@ -62,7 +62,9 @@ Message published for each changed event. The first message is published when th "has_clip": false, "stationary": false, // whether or not the object is considered stationary "motionless_count": 0, // number of frames the object has been motionless - "position_changes": 2 // number of times the object has moved from a stationary position + "position_changes": 2, // number of times the object has moved from a stationary position + "attributes": [], // set of unique attributes that have been identified on the object + "current_attributes": [] // detailed data about the current attributes in this frame }, "after": { "id": "1607123955.475377-mxklsc", @@ -87,7 +89,16 @@ Message published for each changed event. The first message is published when th "has_clip": false, "stationary": false, // whether or not the object is considered stationary "motionless_count": 0, // number of frames the object has been motionless - "position_changes": 2 // number of times the object has changed position + "position_changes": 2, // number of times the object has changed position + "attributes": ["face"], // set of unique attributes that have been identified on the object + "current_attributes": [ + // detailed data about the current attributes in this frame + { + "label": "face", + "box": [442, 506, 534, 524], + "score": 0.64 + } + ] } } ``` @@ -163,9 +174,9 @@ Topic with current motion contour area for a camera. Published value is an integ Topic to send PTZ commands to camera. -| Command | Description | -| ---------------------- | --------------------------------------------------------------------------------------- | +| Command | Description | +| ---------------------- | ----------------------------------------------------------------------------------------- | | `preset-` | send command to move to preset with name `` | | `MOVE_` | send command to continuously move in ``, possible values are [UP, DOWN, LEFT, RIGHT] | | `ZOOM_` | send command to continuously zoom ``, possible values are [IN, OUT] | -| `STOP` | send command to stop moving | +| `STOP` | send command to stop moving | diff --git a/frigate/events/maintainer.py b/frigate/events/maintainer.py index 8ae6aee07..0ac73f4f4 100644 --- a/frigate/events/maintainer.py +++ b/frigate/events/maintainer.py @@ -147,6 +147,23 @@ class EventProcessor(threading.Thread): ) ) + attributes = [ + ( + None + if event_data["snapshot"] is None + else { + "box": to_relative_box( + width, + height, + a["box"], + ), + "label": a["label"], + "score": a["score"], + } + ) + for a in event_data["snapshot"]["attributes"] + ] + # 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 @@ -173,6 +190,7 @@ class EventProcessor(threading.Thread): "region": region, "score": score, "top_score": event_data["top_score"], + "attributes": attributes, }, } diff --git a/frigate/object_processing.py b/frigate/object_processing.py index 923e111ab..eb8474c57 100644 --- a/frigate/object_processing.py +++ b/frigate/object_processing.py @@ -76,6 +76,7 @@ class TrackedObject: self.zone_presence = {} self.current_zones = [] self.entered_zones = [] + self.attributes = set() self.false_positive = True self.has_clip = False self.has_snapshot = False @@ -133,6 +134,7 @@ class TrackedObject: "area": obj_data["area"], "region": obj_data["region"], "score": obj_data["score"], + "attributes": obj_data["attributes"], } thumb_update = True @@ -184,6 +186,9 @@ class TrackedObject: if self.obj_data["frame_time"] - self.previous["frame_time"] > 60: significant_change = True + for attr in obj_data["attributes"]: + self.attributes.add(attr["label"]) + self.obj_data.update(obj_data) self.current_zones = current_zones return (thumb_update, significant_change) @@ -214,7 +219,8 @@ class TrackedObject: "entered_zones": self.entered_zones.copy(), "has_clip": self.has_clip, "has_snapshot": self.has_snapshot, - "attributes": self.obj_data["attributes"], + "attributes": list(self.attributes), + "current_attributes": self.obj_data["attributes"], } if include_thumbnail: @@ -295,6 +301,21 @@ class TrackedObject: color=color, ) + # draw any attributes + for attribute in self.thumbnail_data["attributes"]: + box = attribute["box"] + draw_box_with_label( + best_frame, + box[0], + box[1], + box[2], + box[3], + attribute["label"], + f"{attribute['score']:.0%}", + thickness=thickness, + color=color, + ) + if crop: box = self.thumbnail_data["box"] box_size = 300 @@ -423,7 +444,7 @@ class CameraState: ) # draw any attributes - for attribute in obj["attributes"]: + for attribute in obj["current_attributes"]: box = attribute["box"] draw_box_with_label( frame_copy,