A lightweight, locally-running image-quality analyzer. It extracts image features with OpenCV, runs a pre-trained scikit-learn Random Forest classifier, persists analyses in SQLite, and serves the results through a FastAPI backend + React/Vite frontend.
No model training is required — a pre-trained model is included in ml/models/.
cd backend
python -m venv venv
# Windows
.\venv\Scripts\activate
# macOS / Linux
# source venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000cd frontend
cp .env.example .env.local # optional
npm install
npm run devhttp://localhost:5173
Upload an image and click Analyze Image.
- Upload JPEG, PNG, or WEBP images from the browser.
- Extract 11 OpenCV image-quality features on the backend.
- Run local Random Forest inference.
- Detect issues such as blur, underexposure, overexposure, and noise.
- Compute a 0–100 quality score and a label (
ACCEPTABLE,DEGRADED,DEFECTIVE). - Persist every analysis in SQLite with statistics and issues.
- View and click through analysis history.
- Live backend connection indicator.
- Responsive, keyboard-accessible UI.
- Frontend: React 18, Vite 5, plain CSS
- Backend: Python 3.11+, FastAPI, Uvicorn
- Computer Vision: OpenCV, Pillow, NumPy
- Machine Learning: scikit-learn Random Forest, joblib
- Database: SQLite, SQLAlchemy
- Testing: pytest
React/Vite (port 5173)
|
| REST / CORS
▼
FastAPI (port 8000)
|
├─ SQLite persistence
├─ OpenCV feature extraction (backend/app/services/image_quality.py)
└─ Random Forest inference (backend/app/services/ml_model.py)
The model was trained on synthetic degradations (blur, underexposure, overexposure, noise, severe degradation) generated from 100 clean DIV2K validation photographs. The source images were split 80/20 before degradation to prevent data leakage.
Included model artifacts:
ml/models/image_quality_model.joblibml/models/feature_names.jsonml/models/evaluation.jsonml/models/confusion_matrix.png
Test-set performance:
| Metric | Value |
|---|---|
| Accuracy | 0.9500 |
| Precision | 0.9519 |
| Recall | 0.9500 |
| F1-score | 0.9499 |
cd backend
.\venv\Scripts\activate # Windows
# source venv/bin/activate # macOS / Linux
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000image_quality.dbis created automatically inbackend/on first startup.- Health:
http://localhost:8000/health - Swagger:
http://localhost:8000/docs
cd frontend
npm install
npm run devVITE_API_BASE_URLdefaults tohttp://localhost:8000.- If Vite uses a different port (e.g.
5174), setCORS_ORIGINSon the backend:
$env:CORS_ORIGINS="http://localhost:5174,http://127.0.0.1:5174"
uvicorn app.main:app --host 0.0.0.0 --port 8000| Variable | Default | Purpose |
|---|---|---|
DATABASE_URL |
sqlite:///./image_quality.db |
SQLite database |
CORS_ORIGINS |
http://localhost:5173,http://127.0.0.1:5173 |
Allowed frontend origins |
VITE_API_BASE_URL |
http://localhost:8000 |
Backend URL for the frontend |
Restart Vite after changing .env.local.
GET /health— Backend health.POST /api/analyze— Upload an image and get analysis.- Accepted: JPEG/JPG, PNG, WEBP
- Max size: 10 MB
GET /api/analyses— List history, newest first. Optional?limit=20.GET /api/analyses/{id}— Get a single analysis.
Example:
curl -X POST 'http://localhost:8000/api/analyze' -F 'file=@image.jpg'Example response:
{
"id": 1,
"filename": "image.jpg",
"quality_score": 70,
"quality_label": "DEGRADED",
"predicted_label": "BLUR",
"confidence": 0.99,
"issues": [
{
"type": "blur",
"severity": "high",
"confidence": 0.94
}
],
"statistics": {
"brightness": 128.4,
"contrast": 52.1,
"sharpness": 421.7,
"noise": 8.2,
"saturation": 91.2,
"entropy": 6.7,
"width": 1920,
"height": 1080,
"dark_pixel_ratio": 0.04,
"bright_pixel_ratio": 0.02,
"edge_density": 0.12
},
"created_at": "2026-08-27T12:34:56.789012"
}If you want to regenerate the dataset and retrain:
python ml/scripts/prepare_dataset.py # download DIV2K clean images
python ml/scripts/generate_dataset.py # create synthetic degradations
python ml/scripts/train_model.py # train and write ml/models/Normal use does not require these steps.
Backend tests:
cd backend
venv\Scripts\python.exe -m pytest tests -v # Windows
# pytest tests -v # macOS / LinuxFrontend build:
cd frontend
npm run build- The model is trained on synthetic degradations; real-world defects may differ.
- Docker files are present but not fully production-ready for this demo.
- SQLite is used for the demo; production deployments may want PostgreSQL.
- Thresholds in
backend/app/services/image_quality.pyare conservative estimates.