from fastapi import FastAPI from pydantic import BaseModel from deepface import DeepFace import cv2 import numpy as np import requests import base64 app = FastAPI() MODEL_NAME = "ArcFace" DETECTOR_BACKEND = "opencv" DISTANCE_METRIC = "euclidean_l2" STRICT_THRESHOLD = 0.85 class VerifyRequest(BaseModel): url_goc: str live_base64: str # THỦ THUẬT: HÀM TỰ ĐỘNG BÓP NHỎ ẢNH ĐỂ AI CHẠY NHANH X10 def resize_image(img, max_width=600): h, w = img.shape[:2] if w > max_width: ratio = max_width / float(w) dim = (max_width, int(h * ratio)) img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA) return img def url_to_image(url): resp = requests.get(url) image = np.asarray(bytearray(resp.content), dtype="uint8") img = cv2.imdecode(image, cv2.IMREAD_COLOR) return resize_image(img) # <--- Bóp nhỏ ảnh gốc def base64_to_image(base64_string): if "," in base64_string: base64_string = base64_string.split(",")[1] img_data = base64.b64decode(base64_string) nparr = np.frombuffer(img_data, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) return resize_image(img) # <--- Bóp nhỏ ảnh selfie @app.post("/api/ai/verify-face") def verify_face(req: VerifyRequest): try: img_goc = url_to_image(req.url_goc) img_live = base64_to_image(req.live_base64) # CHẠY AI (Đã đổi sang opencv cho tốc độ bàn thờ) ket_qua = DeepFace.verify( img1_path=img_goc, img2_path=img_live, model_name=MODEL_NAME, detector_backend=DETECTOR_BACKEND, distance_metric=DISTANCE_METRIC, enforce_detection=True ) distance = float(ket_qua['distance']) # Ngưỡng khắt khe (Cố định ở 0.85) is_verified = True if distance <= STRICT_THRESHOLD else False print(f"\n[AI REPORT] Khoảng cách: {distance:.4f} (Ngưỡng: {STRICT_THRESHOLD}) -> PASS: {is_verified}\n") return { "verified": is_verified, "distance": distance, "message": "Quét thành công" } except Exception as e: return {"verified": False, "message": f"Lỗi AI: {str(e)}"} @app.get("/") def root(): return { "status": "AI server is running", "docs": "/docs", "health": "/api/ai/health" } @app.get("/api/ai/health") def health_check(): return { "status": "OK", "model": MODEL_NAME, "detector": DETECTOR_BACKEND, "metric": DISTANCE_METRIC, "threshold": STRICT_THRESHOLD }