Spaces:
Sleeping
Sleeping
File size: 1,989 Bytes
d6ca5c8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# app.py
import base64
import cv2
import numpy as np
import requests
from fastapi import FastAPI
from pydantic import BaseModel
import insightface
# Load Face Detector + Recognition Model (first import may download weights)
model = insightface.app.FaceAnalysis(name="buffalo_l")
model.prepare(ctx_id=0, det_size=(640, 640))
app = FastAPI(title="Face Compare API")
class CompareRequest(BaseModel):
image1: str | None = None # base64
image2: str | None = None # base64
image1_url: str | None = None # URL
image2_url: str | None = None # URL
def b64_to_img(b64_string: str):
try:
img_data = base64.b64decode(b64_string)
arr = np.frombuffer(img_data, np.uint8)
img = cv2.imdecode(arr, cv2.IMREAD_COLOR)
return img
except Exception:
return None
def url_to_img(url: str):
try:
resp = requests.get(url, timeout=10)
arr = np.frombuffer(resp.content, np.uint8)
img = cv2.imdecode(arr, cv2.IMREAD_COLOR)
return img
except Exception:
return None
def get_embedding(img):
faces = model.get(img)
if len(faces) == 0:
return None
return faces[0].embedding
@app.post("/compare")
async def compare_faces(req: CompareRequest):
# Load images (prefer raw base64, else url)
img1 = b64_to_img(req.image1) if req.image1 else (url_to_img(req.image1_url) if req.image1_url else None)
img2 = b64_to_img(req.image2) if req.image2 else (url_to_img(req.image2_url) if req.image2_url else None)
if img1 is None or img2 is None:
return {"error": "Invalid image data or URL."}
emb1 = get_embedding(img1)
emb2 = get_embedding(img2)
if emb1 is None or emb2 is None:
return {"error": "No face detected in one or both images."}
# cosine similarity
similarity = float(np.dot(emb1, emb2) / (np.linalg.norm(emb1) * np.linalg.norm(emb2)))
matched = similarity > 0.55
return {"similarity": similarity, "match": matched} |