MASSJ77 commited on
Commit
798befd
·
verified ·
1 Parent(s): 35561dd

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -0
app.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import base64
3
+ from fastapi import FastAPI, UploadFile, File
4
+ from fastapi.responses import JSONResponse
5
+ import cv2
6
+ import numpy as np
7
+ from huggingface_hub import hf_hub_download
8
+ from realesrgan import RealESRGAN
9
+ from mediapipe import solutions as mp_solutions
10
+
11
+ # ✅ Cache dir for Hugging Face
12
+ CACHE_DIR = "/tmp/hf_cache"
13
+ os.environ["HF_HOME"] = CACHE_DIR
14
+ os.makedirs(CACHE_DIR, exist_ok=True)
15
+
16
+ app = FastAPI(title="Face Beautification API")
17
+
18
+ # ✅ Load Mediapipe face detector
19
+ mp_face = mp_solutions.face_detection.FaceDetection(
20
+ model_selection=1, min_detection_confidence=0.5
21
+ )
22
+
23
+ # ✅ Download ESRGAN weights from Hugging Face (free)
24
+ model_path = hf_hub_download(
25
+ repo_id="eugenesiow/real-esrgan",
26
+ filename="RealESRGAN_x4plus.pth",
27
+ cache_dir=CACHE_DIR
28
+ )
29
+
30
+ # ✅ Load ESRGAN model
31
+ device = "cuda" if cv2.cuda.getCudaEnabledDeviceCount() > 0 else "cpu"
32
+ model = RealESRGAN(device, scale=4)
33
+ model.load_weights(model_path)
34
+
35
+ @app.get("/")
36
+ async def root():
37
+ return {"message": "Free Face Beautification API is running!"}
38
+
39
+ @app.post("/beautify")
40
+ async def beautify(image: UploadFile = File(...)):
41
+ try:
42
+ # Read image
43
+ contents = await image.read()
44
+ npimg = np.frombuffer(contents, np.uint8)
45
+ img = cv2.imdecode(npimg, cv2.IMREAD_COLOR)
46
+
47
+ # Detect faces
48
+ results = mp_face.process(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
49
+ if not results.detections:
50
+ return JSONResponse({"error": "No face detected"}, status_code=400)
51
+
52
+ for detection in results.detections:
53
+ bbox = detection.location_data.relative_bounding_box
54
+ h, w, _ = img.shape
55
+ x1 = int(bbox.xmin * w)
56
+ y1 = int(bbox.ymin * h)
57
+ x2 = int((bbox.xmin + bbox.width) * w)
58
+ y2 = int((bbox.ymin + bbox.height) * h)
59
+ face = img[y1:y2, x1:x2]
60
+
61
+ # Beautify (enhance + smooth)
62
+ face_upscaled = model.predict(face)
63
+ face_smooth = cv2.bilateralFilter(face_upscaled, 9, 75, 75)
64
+
65
+ # Blend face back
66
+ face_smooth = cv2.resize(face_smooth, (x2 - x1, y2 - y1))
67
+ img[y1:y2, x1:x2] = face_smooth
68
+
69
+ # Encode final image as Base64
70
+ _, buffer = cv2.imencode(".jpg", img)
71
+ img_base64 = base64.b64encode(buffer).decode("utf-8")
72
+
73
+ return JSONResponse({
74
+ "status": "success",
75
+ "message": "Beautification complete!",
76
+ "image_base64": img_base64
77
+ })
78
+ except Exception as e:
79
+ return JSONResponse({"error": str(e)}, status_code=500)
80
+
81
+ @app.get("/health")
82
+ async def health():
83
+ return {"ready": True}