nmnm22's picture
Rename app.py to main.py
29cd94b verified
raw
history blame
3.44 kB
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)}