Skip to content

Commit

Permalink
GenAI: add ability to save JPGs sent to provider (#15643)
Browse files Browse the repository at this point in the history
* GenAI: add ability to save JPGs sent to provider

* Remove mention from GenAI docs

* Change config name to debug_save_thumbnails

* Change  folder structure to clips/genai-requests/{event_id}/{1.jpg}
  • Loading branch information
leccelecce authored Dec 23, 2024
1 parent 87e7b62 commit 0037154
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
2 changes: 2 additions & 0 deletions docs/docs/configuration/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,8 @@ cameras:
- cat
# Optional: Restrict generation to objects that entered any of the listed zones (default: none, all zones qualify)
required_zones: []
# Optional: Save thumbnails sent to generative AI for review/debugging purposes (default: shown below)
debug_save_thumbnails: False

# Optional
ui:
Expand Down
4 changes: 4 additions & 0 deletions frigate/config/camera/genai.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class GenAICameraConfig(BaseModel):
default_factory=list,
title="List of required zones to be entered in order to run generative AI.",
)
debug_save_thumbnails: bool = Field(
default=False,
title="Save thumbnails sent to generative AI for debugging purposes.",
)

@field_validator("required_zones", mode="before")
@classmethod
Expand Down
31 changes: 30 additions & 1 deletion frigate/embeddings/maintainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import threading
from multiprocessing.synchronize import Event as MpEvent
from pathlib import Path
from typing import Optional

import cv2
Expand Down Expand Up @@ -217,6 +218,8 @@ def _process_finalized(self) -> None:
_, buffer = cv2.imencode(".jpg", cropped_image)
snapshot_image = buffer.tobytes()

num_thumbnails = len(self.tracked_events.get(event_id, []))

embed_image = (
[snapshot_image]
if event.has_snapshot and camera_config.genai.use_snapshot
Expand All @@ -225,11 +228,37 @@ def _process_finalized(self) -> None:
data["thumbnail"]
for data in self.tracked_events[event_id]
]
if len(self.tracked_events.get(event_id, [])) > 0
if num_thumbnails > 0
else [thumbnail]
)
)

if camera_config.genai.debug_save_thumbnails and num_thumbnails > 0:
logger.debug(
f"Saving {num_thumbnails} thumbnails for event {event.id}"
)

Path(
os.path.join(CLIPS_DIR, f"genai-requests/{event.id}")
).mkdir(parents=True, exist_ok=True)

for idx, data in enumerate(self.tracked_events[event_id], 1):
jpg_bytes: bytes = data["thumbnail"]

if jpg_bytes is None:
logger.warning(
f"Unable to save thumbnail {idx} for {event.id}."
)
else:
with open(
os.path.join(
CLIPS_DIR,
f"genai-requests/{event.id}/{idx}.jpg",
),
"wb",
) as j:
j.write(jpg_bytes)

# Generate the description. Call happens in a thread since it is network bound.
threading.Thread(
target=self._embed_description,
Expand Down

0 comments on commit 0037154

Please sign in to comment.