fix: save face crops as unknown when no model is trained yet

classify() returns None when no faces have been trained (mean_embs is
empty).  The early return that followed skipped write_face_attempt(),
leaving the train queue permanently empty.  This made it impossible to
bootstrap face recognition after a fresh install or after deleting all
known faces — there was no way to get crops into the UI for labelling
without restarting Frigate or manually calling the register API.

When classify() returns None, call write_face_attempt() with
sub_label="unknown" and score=0.0 before returning.  write_face_attempt
already respects the save_attempts config flag, so no new config option
is needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
root 2026-04-01 12:55:56 -03:00
parent adc8c2a6e8
commit 6216e84b64

View File

@ -295,7 +295,15 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
res = self.recognizer.classify(face_frame) res = self.recognizer.classify(face_frame)
if not res: if not res:
logger.debug(f"Face recognizer returned no result for {id}") # classify() returns None when no faces have been trained yet (empty
# embeddings). Save the crop as "unknown" so the user can assign it
# from the UI and bootstrap face recognition after a fresh start or
# after deleting all known faces — otherwise the train queue stays
# empty forever and there is no way to add new training data.
self.write_face_attempt(
face_frame, id, datetime.datetime.now().timestamp(), "unknown", 0.0
)
logger.debug(f"Face recognizer returned no result for {id}, saved crop as unknown")
self.__update_metrics(datetime.datetime.now().timestamp() - start) self.__update_metrics(datetime.datetime.now().timestamp() - start)
return return