faceprocessing / app.py
saketh-005's picture
Update app.py
c26ed98 verified
import gradio as gr
import numpy as np
from ultralytics import YOLO
import insightface
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import cv2
# ----------------------------
# Load models (CPU)
# ----------------------------
yolo = YOLO("yolov8n.pt")
face_model = insightface.app.FaceAnalysis(name="buffalo_l")
face_model.prepare(ctx_id=-1)
def normalize(vec):
vec = np.array(vec, dtype=np.float32)
norm = np.linalg.norm(vec)
if norm == 0:
return vec.tolist()
return (vec / norm).tolist()
def process_image_np(image_np):
results = yolo(image_np)
faces_output = []
for r in results:
boxes = r.boxes
for box, cls, conf in zip(boxes.xyxy, boxes.cls, boxes.conf):
if int(cls) != 0:
continue
if float(conf) < 0.4:
continue
xmin, ymin, xmax, ymax = box.cpu().numpy()
xmin, ymin, xmax, ymax = map(int, [xmin, ymin, xmax, ymax])
h, w, _ = image_np.shape
xmin = max(0, xmin)
ymin = max(0, ymin)
xmax = min(w, xmax)
ymax = min(h, ymax)
person_crop = image_np[ymin:ymax, xmin:xmax]
if person_crop.size == 0:
continue
detected_faces = face_model.get(person_crop)
for face in detected_faces:
embedding = normalize(face.embedding)
fxmin, fymin, fxmax, fymax = face.bbox.astype(int)
faces_output.append({
"cx": float((fxmin + fxmax) / 2 + xmin),
"cy": float((fymin + fymax) / 2 + ymin),
"confidence": float(conf),
"box": {
"xmin": int(fxmin + xmin),
"ymin": int(fymin + ymin),
"xmax": int(fxmax + xmin),
"ymax": int(fymax + ymin)
},
"embedding": embedding
})
return faces_output
# ----------------------------------------
# Create Gradio Blocks
# ----------------------------------------
with gr.Blocks() as demo:
gr.Markdown("Face Processing API Running")
# Get underlying FastAPI app from Gradio
app = demo.app
# ----------------------------------------
# ADD REAL REST ENDPOINT TO SAME APP
# ----------------------------------------
@app.post("/detect")
async def detect(request: Request):
body = await request.body()
np_arr = np.frombuffer(body, np.uint8)
image_np = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
if image_np is None:
return JSONResponse({"error": "Invalid image"}, status_code=400)
result = process_image_np(image_np)
return result
# Launch
demo.queue(False)
demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)