| title | Capstone Backend |
|---|---|
| emoji | π |
| colorFrom | gray |
| colorTo | gray |
| sdk | docker |
| pinned | false |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
A FastAPI backend for detecting and classifying tomato plant flowers by growth stage using ML.
- Image Classification: Upload images of tomato plants to detect flowers and classify their growth stage
- Video Classification: Process entire videos frame-by-frame for comprehensive flower analysis β NEW
- Annotated Media: Automatically generates and stores images/videos with bounding boxes and labels
- GPS Extraction: Automatically extracts location from image EXIF metadata
- Database Storage: Stores all classifications with annotated media for later retrieval (GridFS for large videos)
- Heatmap Data: Returns all location and classification data for frontend heatmap visualization
- Frame-by-Frame Analysis: Detailed statistics for each video frame with aggregated summaries
The API follows a three-tier architecture deployed on the cloud. The presentation layer consists of RESTful endpoints built with FastAPI, handling HTTP requests and responses with automatic OpenAPI documentation. The business logic layer processes images by extracting GPS coordinates from EXIF metadata and running ML classification to detect and classify flowers by growth stage. The data layer uses MongoDB Atlas, a cloud-hosted NoSQL database that stores all classifications and images (as base64) persistently. The entire application is deployed on Render.com as a containerized service, making it scalable and accessible from anywhere. Images flow through the system: uploaded via API, processed for GPS and classification, then stored in MongoDB where they can be retrieved later for heatmap visualization or individual queries.
| Stage | Name | Description |
|---|---|---|
| 0 | Bud | Early flower bud stage |
| 1 | Anthesis | Active flowering stage |
| 2 | Post-Anthesis | After flowering, fruit development |
pip install -r requirements.txtThe .env file is already configured with MongoDB credentials. If you need to update it, edit .env:
# .env file
MONGODB_URL=mongodb+srv://username:password@cluster.mongodb.net/flower_classifications
MONGODB_DATABASE=flower_classifications
PORT=8000Note: The .env file is in .gitignore and won't be committed to git.
# Run all integration tests (recommended)
python test_integration.py
# Run specific tests
python test_integration.py --test model # Test YOLO model only
python test_integration.py --test database # Test MongoDB only
python test_integration.py --test e2e # Test end-to-end flow
python test_integration.py --test api # Test API endpoints (requires running server)
# Run original pytest suite
pytest tests/test_api.py -v
# Test video classification (NEW)
python test_video_api.py
# Test live deployed API
curl https://capstone-077z.onrender.com/# The .env file is automatically loaded
uvicorn app.main:app --reloadThe API will be available at http://localhost:8000
Note: MongoDB URL is loaded from .env file.
Upload an image for flower classification.
Request:
file: Image file (JPEG, PNG, etc.)latitude(optional): Manual GPS latitudelongitude(optional): Manual GPS longitude
Response:
{
"id": "uuid",
"image_path": "/api/images/uuid",
"location": {
"latitude": 37.7749,
"longitude": -122.4194
},
"timestamp": "2025-12-03T10:30:00Z",
"flowers": [
{
"bounding_box": [100, 150, 200, 250],
"stage": 1,
"confidence": 0.95
}
],
"flower_count": 5,
"stage_summary": {"0": 2, "1": 2, "2": 1}
}Get all classification data for heatmap visualization.
Response:
{
"total_records": 10,
"data_points": [
{
"id": "uuid",
"latitude": 37.7749,
"longitude": -122.4194,
"timestamp": "2025-12-03T10:30:00Z",
"flowers": [...],
"total_flowers": 5,
"stage_counts": {"0": 2, "1": 2, "2": 1}
}
]
}Get a specific classification by ID.
Get the annotated image for a classification.
Response: JPEG image with:
- Bounding boxes around each detected flower
- Stage labels (Bud, Anthesis, Post-Anthesis)
- Confidence scores
Note: Only annotated images are stored to save database space.
Delete a classification and its image.
Upload a video for frame-by-frame flower classification.
Request:
file: Video file (MP4, AVI, MOV, etc.)latitude(optional): Manual GPS latitudelongitude(optional): Manual GPS longitudeinclude_frame_details(optional): Include per-frame statistics (default: false)
Response:
{
"id": "uuid",
"video_path": "/api/videos/uuid",
"location": {"latitude": 37.7749, "longitude": -122.4194},
"timestamp": "2025-12-08T10:30:00Z",
"total_frames": 300,
"fps": 30.0,
"duration_seconds": 10.0,
"total_detections": 450,
"average_flowers_per_frame": 1.5,
"stage_summary": {"0": 150, "1": 200, "2": 100},
"frame_statistics": null
}Download the annotated video with bounding boxes and labels on each frame.
Get video classification metadata and statistics.
List all video classifications.
Delete a video classification and its associated video.
π For detailed video API documentation, see VIDEO_API_GUIDE.md
π§ͺ Test video endpoints with: python test_video_api.py
Live API: https://capstone-077z.onrender.com
- Swagger UI: https://capstone-077z.onrender.com/docs
For local development:
- Swagger UI: http://localhost:8000/docs
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β External Clients β
β (Frontend, API Clients, Browser) β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β HTTP/REST
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Hugging Space (FastAPI Application) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β API Routes: β β
β β - POST /api/classify (Images) β β
β β - POST /api/classify-video (Videos - Sync) β β
β β - POST /api/classify-video-async (Videos - Async) β β
β β - GET /api/heatmap-data β β
β β - GET /api/classifications/{id} β β
β β - GET /api/images/{id} β β
β β - GET /api/videos/{id} β β
β β - GET /api/jobs/{id} (Job Status) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Services: β β
β β - ML Model (YOLOv8 - Images & Videos) β β
β β - Image/Video Processing (EXIF GPS, Annotation) β β
β β - ProcessPoolExecutor (Async Video Workers) β β
β β - MongoDB Client (Motor + GridFS) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β MongoDB Connection
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MongoDB Atlas (Cloud Database) β
β - Stores image classifications (base64) β
β - Stores video classifications (GridFS) β
β - Stores job tracking records β
β - Persistent storage β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
capstone/
βββ app/
β βββ __init__.py
β βββ main.py # FastAPI application and routes (images + videos)
β βββ database_mongodb.py # MongoDB + GridFS setup
β βββ config.py # Environment variable configuration
β βββ models.py # Pydantic request/response models
β βββ ml_model.py # YOLO model integration (images + videos)
β βββ utils.py # EXIF GPS extraction utilities
βββ tests/
β βββ __init__.py
β βββ test_api.py # Pytest test suite
βββ ml_model.pt # YOLOv8 trained model
βββ requirements.txt
βββ Dockerfile # Docker configuration for Render
βββ test_integration.py # Integration tests
βββ test_video_api.py # Video API test suite (NEW)
βββ VIDEO_API_GUIDE.md # Video classification documentation (NEW)
βββ README.md
The app/ml_model.py file implements YOLOv8 from Ultralytics for flower detection and classification. The model is automatically downloaded from Hugging Face Hub to ensure you always have the latest version.
def classify_image(image_bytes: bytes, confidence_threshold: float = 0.25) -> List[Dict]:
"""
Returns list of detections:
[
{
"bounding_box": [x_min, y_min, x_max, y_max],
"stage": 0|1|2,
"confidence": 0.0-1.0
}
]
"""- Hugging Face Integration: Automatically downloads latest model from
deenp03/tomato_pollination_stage_classifier - Model Caching: Model is loaded once and cached for subsequent requests
- Automatic Updates: Always uses the latest model version from Hugging Face
- Fallback Support: Falls back to local model if Hugging Face is unavailable
- Confidence Threshold: Adjustable threshold for filtering detections (default: 0.25)
- Automatic RGB Conversion: Handles various image formats (RGBA, grayscale, etc.)
- GPU Support: Automatically uses GPU if available, falls back to CPU
Run the integration test to verify the model downloads and works:
# Test all components including Hugging Face download
python test_integration.py
# Or test just the model
python test_integration.py --test modelThe first run will download the model from Hugging Face (~50MB, takes 5-10 seconds). Subsequent runs use the cached model and are much faster.
Uses MongoDB Atlas for persistent cloud storage. Images are stored as base64 in MongoDB documents.
- Go to https://www.mongodb.com/cloud/atlas/register
- Create a free cluster (M0 tier, 512MB storage)
- Create a database user and get your connection string
- Configure network access to allow connections
- Set environment variable with your connection string
Set the MongoDB connection string as an environment variable:
export MONGODB_URL="mongodb+srv://username:password@cluster.mongodb.net/flower_classifications"Then start the server:
uvicorn app.main:app --reloadThis API is deployed on Render.com with MongoDB Atlas for persistent storage.
API URL: https://capstone-077z.onrender.com
The API is fully deployed and operational. All data is stored in MongoDB Atlas.
-
Set up MongoDB Atlas:
- Create account at https://www.mongodb.com/cloud/atlas
- Create free cluster (M0 tier)
- Get connection string
-
Deploy to Render.com:
- Push code to GitHub
- Create new Web Service on Render
- Set
MONGODB_URLenvironment variable with your connection string - Deploy!
- Everytime your GitHub repo is updated, Render will redeploy
- Frontend: Can be deployed on Vercel or any static hosting
- Backend API: Deployed on Render.com (this repository)
- Database: MongoDB Atlas (cloud-hosted MongoDB)
- Storage: Images stored as base64 in MongoDB documents
# Required - MongoDB connection string
MONGODB_URL=mongodb+srv://username:password@cluster.mongodb.net/flower_classifications?appName=FreeTier
# Optional
MONGODB_DATABASE=flower_classifications # Defaults to this if not specified
PORT=8000 # Server port (auto-set by Render, uses $PORT)
CORS_ORIGINS=* # Allowed frontend origins (comma-separated, * for all)- Go to Render dashboard β Your service
- Click "Environment" tab
- Add
MONGODB_URLwith your connection string - Add any other variables as needed
- Service will auto-redeploy