From 2615ee669caa0df844fcf55963766c96f4967dae Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Wed, 29 Jan 2025 06:48:14 -0700 Subject: [PATCH] Add API for reprocessing face --- frigate/api/classification.py | 33 +++++++++++++++++++ .../real_time/face_processor.py | 2 +- frigate/embeddings/__init__.py | 5 +++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/frigate/api/classification.py b/frigate/api/classification.py index 63f037ec2..497209036 100644 --- a/frigate/api/classification.py +++ b/frigate/api/classification.py @@ -100,6 +100,39 @@ def train_face(request: Request, name: str, body: dict = None): ) +@router.post("/faces/train/{name}/reprocess") +def reclassify_face(request: Request, name: str, body: dict = None): + if not request.app.frigate_config.face_recognition.enabled: + return JSONResponse( + status_code=400, + content={"message": "Face recognition is not enabled.", "success": False}, + ) + + json: dict[str, any] = body or {} + training_file = os.path.join( + FACE_DIR, f"train/{sanitize_filename(json.get('training_file', ''))}" + ) + + if not training_file or not os.path.isfile(training_file): + return JSONResponse( + content=( + { + "success": False, + "message": f"Invalid filename or no file exists: {training_file}", + } + ), + status_code=404, + ) + + context: EmbeddingsContext = request.app.embeddings + response = context.reprocess_face() + + return JSONResponse( + content=response, + status_code=200, + ) + + @router.post("/faces/{name}/delete") def deregister_faces(request: Request, name: str, body: dict = None): if not request.app.frigate_config.face_recognition.enabled: diff --git a/frigate/data_processing/real_time/face_processor.py b/frigate/data_processing/real_time/face_processor.py index 7e0b3ed4b..452ce0e3b 100644 --- a/frigate/data_processing/real_time/face_processor.py +++ b/frigate/data_processing/real_time/face_processor.py @@ -401,7 +401,7 @@ class FaceProcessor(RealTimeProcessorApi): "message": "Successfully registered face.", "success": True, } - elif topic == EmbeddingsRequestEnum.reprocess_face: + elif topic == EmbeddingsRequestEnum.reprocess_face.value: current_file = request_data["image_file"] face_score = current_file[current_file.rfind("-") : current_file.rfind(".")] img = None diff --git a/frigate/embeddings/__init__.py b/frigate/embeddings/__init__.py index 4a3f898e7..185d5436b 100644 --- a/frigate/embeddings/__init__.py +++ b/frigate/embeddings/__init__.py @@ -211,6 +211,11 @@ class EmbeddingsContext: return self.db.execute_sql(sql_query).fetchall() + def reprocess_face(self, face_file: str) -> dict[str, any]: + return self.requestor.send_data( + EmbeddingsRequestEnum.reprocess_face.value, {"image_file": face_file} + ) + def clear_face_classifier(self) -> None: self.requestor.send_data( EmbeddingsRequestEnum.clear_face_classifier.value, None