Spaces:
Running
Running
File size: 4,514 Bytes
a4d01ce 5eab736 4611e20 1490129 5d7bc4a ecfc393 4611e20 eadc82d ecfc393 4611e20 eadc82d ecfc393 eadc82d 4611e20 eadc82d 4611e20 eadc82d 4611e20 eadc82d 4611e20 eadc82d 4611e20 eadc82d ecfc393 eadc82d 4611e20 c052030 4611e20 eadc82d 4611e20 a4d01ce eadc82d 4611e20 eadc82d ecfc393 eadc82d ac1b201 dc2c7e9 eadc82d 4611e20 eadc82d 4611e20 eadc82d 4611e20 eadc82d 4611e20 eadc82d afbf135 eadc82d 4611e20 1490129 a4d01ce 06db179 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# Final, API-only app.py for Hugging Face Space
import os
import cv2
import tempfile
import numpy as np
import uvicorn
from PIL import Image
from inference_sdk import InferenceHTTPClient
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import JSONResponse
import tensorflow as tf
from huggingface_hub import hf_hub_download
# --- 1. Configuration and Model Loading ---
ROBOFLOW_API_KEY = os.environ.get("ROBOFLOW_API_KEY")
CLIENT_FACE = InferenceHTTPClient(api_url="https://detect.roboflow.com", api_key=ROBOFLOW_API_KEY)
CLIENT_EYES = InferenceHTTPClient(api_url="https://detect.roboflow.com", api_key=ROBOFLOW_API_KEY)
CLIENT_IRIS = InferenceHTTPClient(api_url="https://detect.roboflow.com", api_key=ROBOFLOW_API_KEY)
leuko_model = None
try:
model_path = hf_hub_download("skibi11/leukolook-eye-detector", "MobileNetV1_best.keras")
leuko_model = tf.keras.models.load_model(model_path)
print("--- LEUKOCORIA MODEL LOADED SUCCESSFULLY! ---")
except Exception as e:
print(f"--- FATAL ERROR: COULD NOT LOAD LEUKOCORIA MODEL: {e} ---")
raise RuntimeError(f"Could not load leukocoria model: {e}")
# --- 2. All Helper Functions ---
def enhance_image_unsharp_mask(image, strength=0.5, radius=5):
blur = cv2.GaussianBlur(image, (radius, radius), 0)
return cv2.addWeighted(image, 1.0 + strength, blur, -strength, 0)
def detect_faces_roboflow(image_path):
return CLIENT_FACE.infer(image_path, model_id="face-detector-v4liw/2").get("predictions", [])
def detect_eyes_roboflow(image_path, raw_image):
resp = CLIENT_EYES.infer(image_path, model_id="eye-detection-kso3d/3")
crops = []
for p in resp.get("predictions", []):
x1 = int(p['x'] - p['width'] / 2)
y1 = int(p['y'] - p['height'] / 2)
x2 = int(p['x'] + p['width'] / 2)
y2 = int(p['y'] + p['height'] / 2)
crop = raw_image[y1:y2, x1:x2]
if crop.size > 0:
crops.append(crop)
return crops
def get_largest_iris_prediction(eye_crop):
is_success, buffer = cv2.imencode(".jpg", eye_crop)
if not is_success: return None
resp = CLIENT_IRIS.infer(buffer, model_id="iris_120_set/7")
preds = resp.get("predictions", [])
return max(preds, key=lambda p: p["width"] * p["height"]) if preds else None
def run_leukocoria_prediction(iris_crop):
if leuko_model is None: return {"error": "Leukocoria model not loaded"}, 0.0
img_pil = Image.fromarray(cv2.cvtColor(iris_crop, cv2.COLOR_BGR2RGB))
enh = enhance_image_unsharp_mask(np.array(img_pil))
enh_rs = cv2.resize(enh, (224, 224))
img_array = np.array(enh_rs) / 255.0
img_array = np.expand_dims(img_array, axis=0)
prediction = leuko_model.predict(img_array)
confidence = float(prediction[0][0])
has_leuko = confidence > 0.5
return has_leuko, confidence
# --- 3. FastAPI Application ---
app = FastAPI()
@app.post("/detect/")
async def full_detection_pipeline(image: UploadFile = File(...)):
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as tmp:
contents = await image.read()
tmp.write(contents)
temp_image_path = tmp.name
try:
if not detect_faces_roboflow(temp_image_path):
return JSONResponse(status_code=400, content={"error": "No face detected."})
raw_image = cv2.imread(temp_image_path)
eye_crops = detect_eyes_roboflow(temp_image_path, raw_image)
if len(eye_crops) != 2:
return JSONResponse(status_code=400, content={"error": "Exactly two eyes not detected."})
eye_crops.sort(key=lambda c: cv2.boundingRect(cv2.cvtColor(c, cv2.COLOR_BGR2GRAY))[0])
flags = {}
for i, eye_crop in enumerate(eye_crops):
side = "left" if i == 0 else "right"
pred = get_largest_iris_prediction(eye_crop)
if pred:
x1, y1 = int(pred['x'] - pred['width'] / 2), int(pred['y'] - pred['height'] / 2)
x2, y2 = int(pred['x'] + pred['width'] / 2), int(pred['y'] + pred['height'] / 2)
iris_crop = eye_crop[y1:y2, x1:x2]
has_leuko, confidence = run_leukocoria_prediction(iris_crop)
flags[side] = has_leuko
else:
flags[side] = None
return JSONResponse(content={"leukocoria": flags, "warnings": []})
finally:
os.remove(temp_image_path)
# --- 4. Run the Server ---
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860) |