Spaces:
No application file
No application file
File size: 3,444 Bytes
e9d9f4a |
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
from fastapi import FastAPI
from pydantic import BaseModel
import cv2
from deepface import DeepFace
import tempfile
import requests
import shutil
import logging
from typing import Optional
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI()
# Define the request model
class FaceVerificationRequest(BaseModel):
id_url: str
ref_url: str
def download_image(url: str) -> Optional[str]:
"""Downloads an image from a URL and saves it to a temporary file."""
try:
response = requests.get(url, stream=True)
response.raise_for_status()
temp_path = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg").name
with open(temp_path, "wb") as f:
shutil.copyfileobj(response.raw, f)
logger.info(f"Image downloaded successfully: {url}")
return temp_path
except requests.exceptions.RequestException as e:
logger.error(f"Failed to download image from {url}: {e}")
return None
def detect_and_crop_face(image_path, detector_backend="mtcnn") -> Optional[str]:
"""Detects and crops the face from an image."""
try:
faces = DeepFace.extract_faces(img_path=image_path, detector_backend=detector_backend, enforce_detection=False)
if not faces:
logger.warning("No faces detected.")
return None
face_info = faces[0]
facial_area = face_info.get("facial_area", {})
if not facial_area:
logger.warning("No valid facial area found.")
return None
x, y, w, h = facial_area["x"], facial_area["y"], facial_area["w"], facial_area["h"]
image = cv2.imread(image_path)
if image is None or w <= 0 or h <= 0:
logger.error("Invalid face cropping dimensions.")
return None
cropped_face = image[y:y+h, x:x+w]
temp_path = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg").name
cv2.imwrite(temp_path, cropped_face)
logger.info(f"Face successfully cropped and saved at {temp_path}")
return temp_path
except Exception as e:
logger.error(f"Error during face detection: {e}")
return None
@app.post("/verify")
async def verify_face(request: FaceVerificationRequest):
"""Verifies whether two faces belong to the same person."""
try:
id_path = download_image(request.id_url)
ref_path = download_image(request.ref_url)
if not id_path or not ref_path:
return {"error": "Failed to download images."}
cropped_face_path = detect_and_crop_face(id_path)
if cropped_face_path:
result = DeepFace.verify(
img1_path=cropped_face_path,
img2_path=ref_path,
model_name="Facenet",
detector_backend="mtcnn"
)
threshold = 0.6
distance = result.get("distance", 1.0)
is_match = distance < threshold
logger.info(f"Face verification result: {result}")
return {"match": is_match}
else:
return {"error": "Face detection failed for ID card image."}
except Exception as e:
logger.error(f"Verification failed: {e}")
return {"error": str(e)}
|