nmnm22 commited on
Commit
e9d9f4a
·
verified ·
1 Parent(s): 5f4c538

first trail

Browse files
Files changed (3) hide show
  1. Dockerfile +11 -0
  2. app.py +93 -0
  3. requirements.txt +7 -0
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12.3
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN apt-get update && apt-get install -y ffmpeg libsm6 libxext6
7
+ RUN pip install --no-cache-dir -r requirements.txt
8
+
9
+ COPY . .
10
+
11
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ import cv2
4
+ from deepface import DeepFace
5
+ import tempfile
6
+ import requests
7
+ import shutil
8
+ import logging
9
+ from typing import Optional
10
+
11
+ # Configure logging
12
+ logging.basicConfig(level=logging.INFO)
13
+ logger = logging.getLogger(__name__)
14
+
15
+ app = FastAPI()
16
+
17
+ # Define the request model
18
+ class FaceVerificationRequest(BaseModel):
19
+ id_url: str
20
+ ref_url: str
21
+
22
+ def download_image(url: str) -> Optional[str]:
23
+ """Downloads an image from a URL and saves it to a temporary file."""
24
+ try:
25
+ response = requests.get(url, stream=True)
26
+ response.raise_for_status()
27
+ temp_path = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg").name
28
+ with open(temp_path, "wb") as f:
29
+ shutil.copyfileobj(response.raw, f)
30
+ logger.info(f"Image downloaded successfully: {url}")
31
+ return temp_path
32
+ except requests.exceptions.RequestException as e:
33
+ logger.error(f"Failed to download image from {url}: {e}")
34
+ return None
35
+
36
+ def detect_and_crop_face(image_path, detector_backend="mtcnn") -> Optional[str]:
37
+ """Detects and crops the face from an image."""
38
+ try:
39
+ faces = DeepFace.extract_faces(img_path=image_path, detector_backend=detector_backend, enforce_detection=False)
40
+ if not faces:
41
+ logger.warning("No faces detected.")
42
+ return None
43
+
44
+ face_info = faces[0]
45
+ facial_area = face_info.get("facial_area", {})
46
+ if not facial_area:
47
+ logger.warning("No valid facial area found.")
48
+ return None
49
+
50
+ x, y, w, h = facial_area["x"], facial_area["y"], facial_area["w"], facial_area["h"]
51
+ image = cv2.imread(image_path)
52
+ if image is None or w <= 0 or h <= 0:
53
+ logger.error("Invalid face cropping dimensions.")
54
+ return None
55
+
56
+ cropped_face = image[y:y+h, x:x+w]
57
+ temp_path = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg").name
58
+ cv2.imwrite(temp_path, cropped_face)
59
+ logger.info(f"Face successfully cropped and saved at {temp_path}")
60
+ return temp_path
61
+ except Exception as e:
62
+ logger.error(f"Error during face detection: {e}")
63
+ return None
64
+
65
+ @app.post("/verify")
66
+ async def verify_face(request: FaceVerificationRequest):
67
+ """Verifies whether two faces belong to the same person."""
68
+ try:
69
+ id_path = download_image(request.id_url)
70
+ ref_path = download_image(request.ref_url)
71
+
72
+ if not id_path or not ref_path:
73
+ return {"error": "Failed to download images."}
74
+
75
+ cropped_face_path = detect_and_crop_face(id_path)
76
+ if cropped_face_path:
77
+ result = DeepFace.verify(
78
+ img1_path=cropped_face_path,
79
+ img2_path=ref_path,
80
+ model_name="Facenet",
81
+ detector_backend="mtcnn"
82
+ )
83
+ threshold = 0.6
84
+ distance = result.get("distance", 1.0)
85
+ is_match = distance < threshold
86
+
87
+ logger.info(f"Face verification result: {result}")
88
+ return {"match": is_match}
89
+ else:
90
+ return {"error": "Face detection failed for ID card image."}
91
+ except Exception as e:
92
+ logger.error(f"Verification failed: {e}")
93
+ return {"error": str(e)}
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ pydantic
3
+ opencv-python
4
+ numpy==2.0.2
5
+ deepface==0.0.93
6
+ requests
7
+ uvicorn