Spaces:
Sleeping
Sleeping
| """NeuroFocus object detection API. | |
| A neuro-inspired SIMULATION of selective attention. It detects objects in an image | |
| and returns labels, confidence scores, and bounding boxes plus simple scene scores. | |
| It does not measure or diagnose attention, ADHD, fatigue, or any condition. | |
| """ | |
| import io | |
| from fastapi import FastAPI, File, HTTPException, Query, UploadFile | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from PIL import Image, UnidentifiedImageError | |
| from detection import DEFAULT_THRESHOLD, DEVICE, MODEL_NAME, detect | |
| from scoring import compute_scores | |
| DISCLAIMER = "This is a neuro-inspired simulation, not a medical diagnosis." | |
| app = FastAPI(title="NeuroFocus Object Detection API", version="0.1.0") | |
| # Permissive CORS for local development / demo. | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| async def _read_image(file: UploadFile) -> Image.Image: | |
| """Read an UploadFile into a PIL image, raising HTTP 400 on bad input.""" | |
| if file.content_type and not file.content_type.startswith("image/"): | |
| raise HTTPException(status_code=400, detail="Uploaded file is not an image.") | |
| data = await file.read() | |
| if not data: | |
| raise HTTPException(status_code=400, detail="Uploaded file is empty.") | |
| try: | |
| return Image.open(io.BytesIO(data)) | |
| except UnidentifiedImageError: | |
| raise HTTPException(status_code=400, detail="Could not read image file.") | |
| def root(): | |
| return {"name": "NeuroFocus Object Detection API", "status": "running"} | |
| def health(): | |
| return {"status": "ok", "device": DEVICE, "model": MODEL_NAME} | |
| async def detect_objects( | |
| file: UploadFile = File(...), | |
| threshold: float = Query(DEFAULT_THRESHOLD, ge=0.0, le=1.0), | |
| ): | |
| image = await _read_image(file) | |
| return detect(image, threshold=threshold) | |
| async def analyze_focus( | |
| file: UploadFile = File(...), | |
| threshold: float = Query(DEFAULT_THRESHOLD, ge=0.0, le=1.0), | |
| ): | |
| image = await _read_image(file) | |
| detection = detect(image, threshold=threshold) | |
| return { | |
| "image_size": detection["image_size"], | |
| "objects": detection["objects"], | |
| "scores": compute_scores(detection), | |
| "note": DISCLAIMER, | |
| } | |