faceprocessing / app.py
JANGALA SAKETH
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)