ksumhs commited on
Commit
ea3e859
·
verified ·
1 Parent(s): 9fab985

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -60
app.py CHANGED
@@ -35,68 +35,31 @@ async def process_img(file: UploadFile = File(...)):
35
 
36
  face = faces[0]
37
 
38
- # =============================
39
- # 1. Extract main landmarks
40
- # =============================
41
- pts = face.landmark_2d_106
42
-
43
- left_eye = pts[38]
44
- right_eye = pts[88]
45
- nose = pts[52]
46
-
47
- # =============================
48
- # 2. Compute roll angle
49
- # =============================
50
- dx = right_eye[0] - left_eye[0]
51
- dy = right_eye[1] - left_eye[1]
52
- roll_angle = np.degrees(np.arctan2(dy, dx))
53
-
54
- # =============================
55
- # 3. Rotate image to fix roll
56
- # =============================
57
- rotated = img.rotate(-roll_angle, expand=True)
58
- np_rot = np.array(rotated)
59
-
60
- # =============================
61
- # 4. Detect again after rotation
62
- # =============================
63
- faces2 = face_app.get(np_rot)
64
- if not faces2:
65
- return JSONResponse({"error": "Face lost after rotation"}, status_code=500)
66
-
67
- f = faces2[0]
68
- x1, y1, x2, y2 = f.bbox.astype(int)
69
-
70
- # =============================
71
- # 5. Resize face to Abshir ratio
72
- # Face height should be 70% of image
73
- # =============================
74
- face_h = y2 - y1
75
- target_face_ratio = 0.70
76
- target_h = int(face_h / target_face_ratio)
77
-
78
- center_y = (y1 + y2) // 2
79
- top = center_y - target_h // 2
80
- bottom = center_y + target_h // 2
81
-
82
- top = max(0, top)
83
- bottom = min(rotated.height, bottom)
84
-
85
- crop_img = rotated.crop((0, top, rotated.width, bottom))
86
-
87
- # =============================
88
- # 6. Apply white background
89
- # =============================
90
- white_bg = Image.new("RGB", crop_img.size, (255, 255, 255))
91
- white_bg.paste(crop_img, (0, 0))
92
-
93
- # =============================
94
- # 7. Final export 4x6
95
- # =============================
96
- final_img = white_bg.resize((472, 709), Image.LANCZOS)
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  buf = io.BytesIO()
99
- final_img.save(buf, format="JPEG")
100
  buf.seek(0)
101
  return Response(buf.getvalue(), media_type="image/jpeg")
102
 
 
35
 
36
  face = faces[0]
37
 
38
+ # --- Extract face bounding box ---
39
+ x1, y1, x2, y2 = face.bbox.astype(int)
40
+ cropped = img.crop((x1, y1, x2, y2))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ # --- Resize cropped face with preserved aspect ratio ---
43
+ max_face_height = int(709 * 0.75) # face occupies 75% of final height
44
+ w, h = cropped.size
45
+ scale_factor = max_face_height / h
46
+
47
+ new_w = int(w * scale_factor)
48
+ new_h = int(h * scale_factor)
49
+ resized_face = cropped.resize((new_w, new_h), Image.LANCZOS)
50
+
51
+ # --- Create final white 4x6 canvas ---
52
+ final_w, final_h = 472, 709
53
+ canvas = Image.new("RGB", (final_w, final_h), (255, 255, 255))
54
+
55
+ # --- Center image on canvas ---
56
+ paste_x = (final_w - new_w) // 2
57
+ paste_y = (final_h - new_h) // 2
58
+ canvas.paste(resized_face, (paste_x, paste_y))
59
+
60
+ # --- Output final image ---
61
  buf = io.BytesIO()
62
+ canvas.save(buf, format="JPEG")
63
  buf.seek(0)
64
  return Response(buf.getvalue(), media_type="image/jpeg")
65