mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
feat: facial recognition (#2180)
This commit is contained in:
parent
115a47d4c6
commit
93863b0629
107 changed files with 3943 additions and 133 deletions
|
|
@ -1,9 +1,13 @@
|
|||
import os
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import uvicorn
|
||||
|
||||
from insightface.app import FaceAnalysis
|
||||
from transformers import pipeline
|
||||
from sentence_transformers import SentenceTransformer, util
|
||||
from PIL import Image
|
||||
from fastapi import FastAPI
|
||||
import uvicorn
|
||||
import os
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
|
|
@ -15,15 +19,6 @@ class ClipRequestBody(BaseModel):
|
|||
text: str
|
||||
|
||||
|
||||
is_dev = os.getenv('NODE_ENV') == 'development'
|
||||
server_port = os.getenv('MACHINE_LEARNING_PORT', 3003)
|
||||
server_host = os.getenv('MACHINE_LEARNING_HOST', '0.0.0.0')
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
"""
|
||||
Model Initialization
|
||||
"""
|
||||
classification_model = os.getenv(
|
||||
'MACHINE_LEARNING_CLASSIFICATION_MODEL', 'microsoft/resnet-50')
|
||||
object_model = os.getenv('MACHINE_LEARNING_OBJECT_MODEL', 'hustvl/yolos-tiny')
|
||||
|
|
@ -31,9 +26,15 @@ clip_image_model = os.getenv(
|
|||
'MACHINE_LEARNING_CLIP_IMAGE_MODEL', 'clip-ViT-B-32')
|
||||
clip_text_model = os.getenv(
|
||||
'MACHINE_LEARNING_CLIP_TEXT_MODEL', 'clip-ViT-B-32')
|
||||
facial_recognition_model = os.getenv(
|
||||
'MACHINE_LEARNING_FACIAL_RECOGNITION_MODEL', 'buffalo_l')
|
||||
|
||||
cache_folder = os.getenv('MACHINE_LEARNING_CACHE_FOLDER', '/cache')
|
||||
|
||||
_model_cache = {}
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
|
|
@ -73,6 +74,36 @@ def clip_encode_text(payload: ClipRequestBody):
|
|||
return model.encode(text).tolist()
|
||||
|
||||
|
||||
@app.post("/facial-recognition/detect-faces", status_code=200)
|
||||
def facial_recognition(payload: MlRequestBody):
|
||||
model = _get_model(facial_recognition_model, 'facial-recognition')
|
||||
assetPath = payload.thumbnailPath
|
||||
img = cv.imread(assetPath)
|
||||
height, width, _ = img.shape
|
||||
results = []
|
||||
faces = model.get(img)
|
||||
for face in faces:
|
||||
if face.det_score < 0.7:
|
||||
continue
|
||||
x1, y1, x2, y2 = face.bbox
|
||||
# min face size as percent of original image
|
||||
# if (x2 - x1) / width < 0.03 or (y2 - y1) / height < 0.05:
|
||||
# continue
|
||||
results.append({
|
||||
"imageWidth": width,
|
||||
"imageHeight": height,
|
||||
"boundingBox": {
|
||||
"x1": round(x1),
|
||||
"y1": round(y1),
|
||||
"x2": round(x2),
|
||||
"y2": round(y2),
|
||||
},
|
||||
"score": face.det_score.item(),
|
||||
"embedding": face.normed_embedding.tolist()
|
||||
})
|
||||
return results
|
||||
|
||||
|
||||
def run_engine(engine, path):
|
||||
result = []
|
||||
predictions = engine(path)
|
||||
|
|
@ -93,12 +124,22 @@ def _get_model(model, task=None):
|
|||
key = '|'.join([model, str(task)])
|
||||
if key not in _model_cache:
|
||||
if task:
|
||||
_model_cache[key] = pipeline(model=model, task=task)
|
||||
if task == 'facial-recognition':
|
||||
face_model = FaceAnalysis(
|
||||
name=model, root=cache_folder, allowed_modules=["detection", "recognition"])
|
||||
face_model.prepare(ctx_id=0, det_size=(640, 640))
|
||||
_model_cache[key] = face_model
|
||||
else:
|
||||
_model_cache[key] = pipeline(model=model, task=task)
|
||||
else:
|
||||
_model_cache[key] = SentenceTransformer(model)
|
||||
_model_cache[key] = SentenceTransformer(
|
||||
model, cache_folder=cache_folder)
|
||||
return _model_cache[key]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run("main:app", host=server_host,
|
||||
port=int(server_port), reload=is_dev, workers=1)
|
||||
host = os.getenv('MACHINE_LEARNING_HOST', '0.0.0.0')
|
||||
port = int(os.getenv('MACHINE_LEARNING_PORT', 3003))
|
||||
is_dev = os.getenv('NODE_ENV') == 'development'
|
||||
|
||||
uvicorn.run("main:app", host=host, port=port, reload=is_dev, workers=1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue