fast_api / app /main.py
harshadsalunkhe1212's picture
Update app/main.py
ce7ee16 verified
Raw
History Blame Contribute Delete
3.21 kB
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse, JSONResponse
from ultralytics import YOLO
from PIL import Image
import numpy as np
import cv2
import io
import mediapipe as mp
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
model = YOLO("app/pigmentnew.pt")
print("✅ YOLO Model Loaded. Classes:", model.names)
def detect_and_zoom_face(image_pil, zoom_scale=3.0):
image_rgb = np.array(image_pil)
image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
with mp.solutions.face_detection.FaceDetection(model_selection=1, min_detection_confidence=0.6) as detector:
results = detector.process(image_bgr)
if not results.detections:
return None, "No face detected"
detection = results.detections[0]
box = detection.location_data.relative_bounding_box
h, w, _ = image_bgr.shape
x = int(box.xmin * w)
y = int(box.ymin * h)
box_w = int(box.width * w)
box_h = int(box.height * h)
pad_x = int(box_w * 0.4)
pad_y_top = int(box_h * 1.0)
pad_y_bottom = int(box_h * 0.15)
x1 = max(0, x - pad_x)
y1 = max(0, y - pad_y_top)
x2 = min(w, x + box_w + pad_x)
y2 = min(h, y + box_h + pad_y_bottom)
face_crop = image_rgb[y1:y2, x1:x2]
zoomed = cv2.resize(face_crop, None, fx=zoom_scale, fy=zoom_scale, interpolation=cv2.INTER_CUBIC)
zoomed_pil = Image.fromarray(zoomed)
return zoomed_pil, None
@app.post("/zoom_face")
async def zoom_face(image: UploadFile = File(...)):
try:
contents = await image.read()
image_pil = Image.open(io.BytesIO(contents)).convert('RGB')
zoomed_face, error = detect_and_zoom_face(image_pil)
if error:
return JSONResponse(content={"error": error}, status_code=400)
buf = io.BytesIO()
zoomed_face.save(buf, format='JPEG')
buf.seek(0)
return StreamingResponse(buf, media_type="image/jpeg")
except Exception as e:
return JSONResponse(content={"error": str(e)}, status_code=500)
@app.post("/predict")
async def predict(image: UploadFile = File(...)):
if not image:
raise HTTPException(status_code=400, detail="No image provided")
try:
contents = await image.read()
img = Image.open(io.BytesIO(contents)).convert("RGB")
except Exception as e:
raise HTTPException(status_code=400, detail=f"Invalid image: {str(e)}")
results = model.predict(img, conf=0.09, imgsz=1024)
result = results[0]
detections = []
if result.boxes is not None:
for box in result.boxes:
cls_id = int(box.cls[0].item())
label = result.names[cls_id]
confidence = round(float(box.conf[0].item()), 2)
coords = box.xyxy[0].tolist()
box_coords = [round(c, 2) for c in coords]
detections.append({"label": label, "confidence": confidence, "box": box_coords})
return {"detections": detections}