--- title: Parkinson's Motor Impairment Predictor emoji: 🧠 colorFrom: blue colorTo: indigo sdk: docker app_port: 7860 --- # Parkinson's Motor Impairment Score API This project is a **FastAPI** service that predicts Parkinson's-related motor impairment from patient drawing images. It accepts two drawing styles: - **Wave drawings** - **Spiral drawings** Each image is preprocessed and passed into a deep learning model to produce: - a raw model logit - a sigmoid probability - a normalized motor impairment score from 0 to 100 - a severity label - a human-readable description The project is designed for **local development**, **Docker deployment**, and **Hugging Face Spaces**. The service is intended to: 1. receive an uploaded image 2. preprocess it consistently 3. run inference using a pretrained model 4. return a structured prediction response --- ## Key Features ### 1. FastAPI-based service The API uses FastAPI for fast request handling, automatic validation, and interactive documentation. ### 2. Two prediction routes - Wave drawings use a **VGG19-based** model - Spiral drawings use a **ResNet101-based** model ### 3. Startup model loading Both models are loaded during application startup so the first request is faster. ### 4. Custom preprocessing pipeline The image pipeline reproduces the original training preprocessing using: - OpenCV - NumPy - Pillow ### 5. Hugging Face model download The trained `.h5` models are downloaded from Hugging Face Hub when needed. ### 6. CORS support The API is configured to accept cross-origin requests from browser-based clients. ### 7. Docker-ready deployment The repository includes a Dockerfile for Hugging Face Spaces deployment. --- ## Repository Structure - [main.py](main.py) - FastAPI application entry point and API routes - [services/predictor.py](services/predictor.py) - model loading, preprocessing, and prediction logic - [services/**init**.py](services/__init__.py) - package initializer - [requirements.txt](requirements.txt) - Python dependencies - [Dockerfile](Dockerfile) - container configuration for deployment - [.github/workflows/deploy.yml](.github/workflows/deploy.yml) - GitHub Actions workflow for deployment to Hugging Face - [test/](test/) - sample images for testing and experimentation --- ## How the API Works ### Request flow 1. A client uploads a drawing image using multipart form data 2. The API validates that the file is an image 3. The image is converted into a consistent tensor-like NumPy array 4. The correct model is loaded if not already cached 5. The model returns a raw logit 6. The logit is converted to a sigmoid probability 7. The result is normalized into a motor impairment score 8. A severity label and description are returned ### Preprocessing pipeline The preprocessing logic performs the following steps: 1. load the image 2. convert to grayscale 3. apply Otsu thresholding with inversion 4. resize to 224 × 224 5. replicate grayscale into 3 channels 6. apply normalization logic compatible with the training setup 7. add a batch dimension --- ## API Endpoints ### Health check **GET /** Returns a simple status response. Example response: ```json { "status": "ok", "message": "Welcome to the Motor Impairment Score API" } ``` ### Predict wave drawing **POST /predict/wave** Accepts a wave drawing image and returns a prediction. ### Predict spiral drawing **POST /predict/spiral** Accepts a spiral drawing image and returns a prediction. ### Input format Both prediction endpoints expect: - `multipart/form-data` - a single file field named `file` ### Example response ```json { "drawing_type": "wave", "raw_logit": 8.7809, "sigmoid_probability": 0.9998, "motor_impairment_score": 43.98, "severity_level": "Mild", "description": "Slight motor irregularities observed.", "is_parkinson": true } ``` ### Response fields - `drawing_type` - either `wave` or `spiral` - `raw_logit` - raw model output before sigmoid - `sigmoid_probability` - probability converted from the logit - `motor_impairment_score` - normalized score between 0 and 100 - `severity_level` - severity category - `description` - human-readable interpretation - `is_parkinson` - boolean indicator derived from the severity level --- ## Severity Levels The API classifies the result into one of these labels: - **Normal Pattern** - no motor impairment detected - **Mild** - slight motor irregularities observed - **Moderate** - noticeable motor impairment detected - **High** - significant motor impairment observed - **Severe** - strong Parkinsonian motor patterns detected The exact score thresholds are defined in [services/predictor.py](services/predictor.py). --- ## Local Setup ### 1. Create a virtual environment ```bash python -m venv venv source venv/bin/activate ``` ### 2. Install dependencies ```bash pip install -r requirements.txt ``` If needed, also install the runtime packages used by the API: ```bash pip install fastapi uvicorn python-multipart ``` ### 3. Run the server ```bash uvicorn main:app --reload ``` ### 4. Open the documentation Visit: ```text http://127.0.0.1:8000/docs ``` This opens the interactive Swagger UI for testing the API. --- ## Example Requests ### cURL example ```bash curl -X POST "http://127.0.0.1:8000/predict/wave" \ -F "file=@test/wave.png" ``` ### Spiral example ```bash curl -X POST "http://127.0.0.1:8000/predict/spiral" \ -F "file=@test/spiral.png" ``` ### Python example ```python import requests url = "http://127.0.0.1:8000/predict/wave" with open("test/wave.png", "rb") as f: files = {"file": f} response = requests.post(url, files=files) print(response.json()) ``` --- ## Deployment ### Docker The repository contains a Dockerfile that: - installs system dependencies required by OpenCV - installs the Python dependencies - runs the API on port `7860` ### Hugging Face Spaces The repository is set up for deployment as a Docker Space on Hugging Face. Deployment flow: 1. Push changes to the `main` branch 2. GitHub Actions runs the workflow in [deploy.yml](.github/workflows/deploy.yml) 3. The workflow pushes the repository to the Hugging Face Space repository 4. Hugging Face rebuilds and redeploys the Space Target Hugging Face repository: `https://huggingface.co/spaces/xplorers/MIS_API` ### Required secret The GitHub Actions workflow needs this secret: - `HF_TOKEN` - Hugging Face write token Make sure the token has permission to push to the target Space. --- ## Important Files ### [main.py](main.py) Contains: - the FastAPI app - startup model loading - CORS configuration - image prediction endpoints ### [services/predictor.py](services/predictor.py) Contains: - Hugging Face model download logic - image preprocessing - wave and spiral prediction functions - severity interpretation logic ### [Dockerfile](Dockerfile) Contains: - Python base image - OpenCV system libraries - application startup command ### [.github/workflows/deploy.yml](.github/workflows/deploy.yml) Contains: - GitHub Actions deployment logic - authenticated push to Hugging Face Spaces --- ## License and Usage No explicit license file is currently included in the repository. If you plan to publish or share the project publicly, add a license file and review the Hugging Face model and deployment permissions.