mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-05 18:55:23 +03:00
Add ability to set bounding box locations in snapshot
This commit is contained in:
parent
c65b149483
commit
9ba7f5c2ae
@ -306,7 +306,12 @@ Create a manual API with a given `label` (ex: doorbell press) to capture a speci
|
|||||||
{
|
{
|
||||||
"subLabel": "some_string", // add sub label to event
|
"subLabel": "some_string", // add sub label to event
|
||||||
"duration": 30, // predetermined length of event (default: 30 seconds) or can be to null for indeterminate length event
|
"duration": 30, // predetermined length of event (default: 30 seconds) or can be to null for indeterminate length event
|
||||||
"include_recording": true // whether the event should save recordings along with the snapshot that is taken
|
"include_recording": true, // whether the event should save recordings along with the snapshot that is taken
|
||||||
|
"draw": { // optional bounding box that will be drawn on the snapshot
|
||||||
|
"box": [0.5, 0.5, 0.25, 0.25], // box consists of x, 1, width, height which are on a scale between 0 - 1
|
||||||
|
"color": [255, 0, 0], // color of the box, default is red
|
||||||
|
"score": 100, // optional score of the object
|
||||||
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ from multiprocessing.queues import Queue
|
|||||||
from frigate.config import CameraConfig, FrigateConfig
|
from frigate.config import CameraConfig, FrigateConfig
|
||||||
from frigate.const import CLIPS_DIR
|
from frigate.const import CLIPS_DIR
|
||||||
from frigate.events.maintainer import EventTypeEnum
|
from frigate.events.maintainer import EventTypeEnum
|
||||||
|
from frigate.util import draw_box_with_label
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ class ExternalEventProcessor:
|
|||||||
rand_id = "".join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
rand_id = "".join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
||||||
event_id = f"{now}-{rand_id}"
|
event_id = f"{now}-{rand_id}"
|
||||||
|
|
||||||
self._write_snapshots(camera_config, event_id, snapshot_frame)
|
self._write_snapshots(camera_config, label, event_id, snapshot_frame)
|
||||||
|
|
||||||
if not self.default_thumbnail:
|
if not self.default_thumbnail:
|
||||||
self._calculate_thumbnail_bytes()
|
self._calculate_thumbnail_bytes()
|
||||||
@ -76,24 +77,21 @@ class ExternalEventProcessor:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _calculate_thumbnail_bytes(self) -> None:
|
def _calculate_thumbnail_bytes(self) -> None:
|
||||||
error_image = glob.glob("/opt/frigate/frigate/images/external-event.png")
|
thumbnail = glob.glob("/opt/frigate/frigate/images/external-event.png")
|
||||||
|
|
||||||
if len(error_image) > 0:
|
if len(thumbnail) > 0:
|
||||||
with open("/opt/frigate/frigate/images/external-event.png", "rb") as img:
|
with open("/opt/frigate/frigate/images/external-event.png", "rb") as img:
|
||||||
img_bytes = img.read()
|
img_bytes = img.read()
|
||||||
self.default_thumbnail = base64.b64encode(img_bytes).decode("utf-8")
|
self.default_thumbnail = base64.b64encode(img_bytes).decode("utf-8")
|
||||||
|
|
||||||
def _write_snapshots(
|
def _write_snapshots(
|
||||||
self, camera_config: CameraConfig, event_id: str, img_bytes: any
|
self,
|
||||||
|
camera_config: CameraConfig,
|
||||||
|
label: str,
|
||||||
|
event_id: str,
|
||||||
|
draw: dict[str, any],
|
||||||
|
img_bytes: any,
|
||||||
) -> None:
|
) -> None:
|
||||||
# write jpg snapshot
|
|
||||||
ret, jpg = cv2.imencode(".jpg", img_bytes)
|
|
||||||
with open(
|
|
||||||
os.path.join(CLIPS_DIR, f"{camera_config.name}-{event_id}.jpg"),
|
|
||||||
"wb",
|
|
||||||
) as j:
|
|
||||||
j.write(jpg.tobytes())
|
|
||||||
|
|
||||||
# write clean snapshot if enabled
|
# write clean snapshot if enabled
|
||||||
if camera_config.snapshots.clean_copy:
|
if camera_config.snapshots.clean_copy:
|
||||||
ret, png = cv2.imencode(".png", img_bytes)
|
ret, png = cv2.imencode(".png", img_bytes)
|
||||||
@ -107,3 +105,29 @@ class ExternalEventProcessor:
|
|||||||
"wb",
|
"wb",
|
||||||
) as p:
|
) as p:
|
||||||
p.write(png.tobytes())
|
p.write(png.tobytes())
|
||||||
|
|
||||||
|
# write jpg snapshot with optional annotations
|
||||||
|
if draw.get("box"):
|
||||||
|
x = draw["box"][0] * camera_config.detect.width
|
||||||
|
y = draw["box"][1] * camera_config.detect.height
|
||||||
|
width = draw["box"][2] * camera_config.detect.width
|
||||||
|
height = draw["box"][3] * camera_config.detect.height
|
||||||
|
|
||||||
|
draw_box_with_label(
|
||||||
|
img_bytes,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
x + width,
|
||||||
|
y + height,
|
||||||
|
label,
|
||||||
|
f"{draw.get('score', '-')}% {int(width * height)}",
|
||||||
|
thickness=2,
|
||||||
|
color=draw.get("color", (255, 0, 0)),
|
||||||
|
)
|
||||||
|
|
||||||
|
ret, jpg = cv2.imencode(".jpg", img_bytes)
|
||||||
|
with open(
|
||||||
|
os.path.join(CLIPS_DIR, f"{camera_config.name}-{event_id}.jpg"),
|
||||||
|
"wb",
|
||||||
|
) as j:
|
||||||
|
j.write(jpg.tobytes())
|
||||||
|
|||||||
@ -867,6 +867,7 @@ def create_event(camera_name, label):
|
|||||||
json.get("sub_label", None),
|
json.get("sub_label", None),
|
||||||
json.get("duration", 30),
|
json.get("duration", 30),
|
||||||
json.get("include_recording", True),
|
json.get("include_recording", True),
|
||||||
|
json.get("draw", {}),
|
||||||
frame,
|
frame,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user