A machine learning-powered web API for identifying different types of house plants from images. This project uses a Convolutional Neural Network (CNN) based on ResNet50 architecture trained on TensorFlow to classify plant images into 10 different categories.
The model can identify the following plant types:
- Aloe Vera (Aloe vera)
- Areca Palm (Dypsis lutescens)
- Chinese evergreen (Aglaonema)
- English Ivy (Hedera helix)
- Jade plant (Crassula ovata)
- Money Tree (Pachira aquatica)
- Parlor Palm (Chamaedorea elegans)
- Rubber Plant (Ficus elastica)
- Snake plant (Sanseviera)
- ZZ Plant (Zamioculcas zamiifolia)
- FastAPI-based REST API with automatic documentation
- Real-time image classification with confidence scores
- Multiple input formats - file uploads and base64 encoded images
- CORS support for web applications
- Health check endpoint for monitoring
- Comprehensive error handling and logging
- Railway deployment ready with Procfile
Your API is now deployed and ready to use!
- API Base URL:
http://web-production-f233.up.railway.app - Interactive Documentation:
http://web-production-f233.up.railway.app/docs - Health Check:
http://web-production-f233.up.railway.app/health
- Google Drive Link: Download plant_species_Model.h5
- File Size: ~295MB
- Required for: Local development and testing
- Python 3.9.5
- TensorFlow 2.10.0
- FastAPI 0.109.0+
- Other dependencies (see
requirements.txt)
-
Clone the repository
git clone <your-repo-url> cd Plant_CNN
-
Install dependencies
pip install -r requirements.txt
-
Model File Setup
- For Local Development: Download the model file from Google Drive and place
plant_species_Model.h5in the root directory - For Deployment: The model is automatically downloaded from Google Drive during deployment
- This is a trained ResNet50 model for plant classification (~295MB)
- For Local Development: Download the model file from Google Drive and place
-
Start the FastAPI server
python app.py
-
Access the API
Local Development:
- API will be available at:
http://localhost:8000 - Interactive documentation:
http://localhost:8000/docs - Alternative docs:
http://localhost:8000/redoc - Health check:
http://localhost:8000/health
Live Deployment:
- API is available at:
http://web-production-f233.up.railway.app - Interactive documentation:
http://web-production-f233.up.railway.app/docs - Health check:
http://web-production-f233.up.railway.app/health
- API will be available at:
Returns API information and available classes.
{
"message": "Plant Species Classification API",
"classes": ["Aloe Vera", "Areca Palm", ...],
"total_classes": 10
}Returns the status of the API and model.
{
"status": "healthy",
"model_loaded": true,
"classes_loaded": true,
"total_classes": 10
}Returns list of supported plant classes.
{
"classes": ["Aloe Vera", "Areca Palm", ...],
"count": 10
}Upload an image file to get plant classification.
Request:
- Method:
POST - Content-Type:
multipart/form-data - Body: Image file
Response:
{
"predicted_class": "Aloe Vera",
"confidence": 0.95
}Send base64 encoded image for plant classification.
Request:
- Method:
POST - Content-Type:
application/json - Body:
{"image": "base64_encoded_string"}
Response:
{
"predicted_class": "Aloe Vera",
"confidence": 0.95
}# File upload
curl -X POST "http://web-production-f233.up.railway.app/predict" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-F "file=@your_image.jpg"
# Base64 image
curl -X POST "http://web-production-f233.up.railway.app/predict-base64" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d '{"image": "base64_encoded_image_string"}'import requests
# File upload
with open('your_image.jpg', 'rb') as f:
files = {'file': f}
response = requests.post('http://web-production-f233.up.railway.app/predict', files=files)
result = response.json()
print(f"Predicted: {result['predicted_class']}")
print(f"Confidence: {result['confidence']}")
# Base64 image
import base64
with open('your_image.jpg', 'rb') as f:
image_data = base64.b64encode(f.read()).decode('utf-8')
response = requests.post('http://web-production-f233.up.railway.app/predict-base64',
json={'image': image_data})
result = response.json()
print(f"Predicted: {result['predicted_class']}")
print(f"Confidence: {result['confidence']}")# File upload
curl -X POST "http://localhost:8000/predict" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-F "file=@your_image.jpg"
# Base64 image
curl -X POST "http://localhost:8000/predict-base64" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d '{"image": "base64_encoded_image_string"}'import requests
# File upload
with open('your_image.jpg', 'rb') as f:
files = {'file': f}
response = requests.post('http://localhost:8000/predict', files=files)
result = response.json()
print(f"Predicted: {result['predicted_class']}")
print(f"Confidence: {result['confidence']}")
# Base64 image
import base64
with open('your_image.jpg', 'rb') as f:
image_data = base64.b64encode(f.read()).decode('utf-8')
response = requests.post('http://localhost:8000/predict-base64',
json={'image': image_data})
result = response.json()
print(f"Predicted: {result['predicted_class']}")
print(f"Confidence: {result['confidence']}")// File upload
const formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('http://web-production-f233.up.railway.app/predict', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(`Predicted: ${data.predicted_class}`);
console.log(`Confidence: ${data.confidence}`);
});
// Base64 image
const reader = new FileReader();
reader.onload = function() {
const base64Image = reader.result.split(',')[1];
fetch('http://web-production-f233.up.railway.app/predict-base64', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({image: base64Image})
})
.then(response => response.json())
.then(data => {
console.log(`Predicted: ${data.predicted_class}`);
console.log(`Confidence: ${data.confidence}`);
});
};
reader.readAsDataURL(fileInput.files[0]);Use the included test_api.py script for quick local testing:
# Test with a specific image
python test_api.py path/to/your/image.jpg
# Or modify the IMAGE_PATH variable in test_api.pyYou can test the API with any plant image. Here are some suggestions:
- Aloe Vera: Images of aloe vera plants
- Snake Plant: Sansevieria trifasciata images
- Jade Plant: Crassula ovata images
- Money Tree: Pachira aquatica images
Note: For best results, use clear, well-lit images of the plant's leaves and overall structure.
This project is configured for Railway deployment with automatic model download:
- Connect your GitHub repository to Railway
- Railway will automatically detect the Python project
- The model file is automatically downloaded from Google Drive during deployment
- Deploy with one click
Due to the large size of the trained model (~295MB), it's not included in the repository. Instead:
- Local Development: Download
plant_species_Model.h5from Google Drive and place it in the root directory - Deployment: The FastAPI app automatically downloads the model from Google Drive during startup
- Model Source: The model is hosted on Google Drive for easy access and deployment
The API uses the following environment variables:
PORT: Port number (automatically set by Railway)MODEL_PATH: Path to the model file (default:plant_species_Model.h5)CLASSES_PATH: Path to classes JSON file (default:plant_classes.json)GOOGLE_DRIVE_MODEL_ID: Google Drive file ID for model download (default:1rKl_jRCbTixMHIOct95pLyta1Q5tPgrk)
Plant_CNN/
βββ app.py # FastAPI application with CORS support
βββ requirements.txt # Python dependencies and versions
βββ Procfile # Railway deployment config
βββ runtime.txt # Python runtime version (3.9.5)
βββ plant_classes.json # Class mapping configuration
βββ plant-species-classification-resnet50-eda.ipynb # Jupyter notebook for EDA
βββ README.md # Project documentation
βββ DATA/ # Training data directory
βββ plant_species_Model.h5 # Trained ResNet50 model (download from Google Drive)
Note: The plant_species_Model.h5 model file (~295MB) is not included in the repository due to size constraints. Download it from Google Drive for local development.
- Architecture: ResNet50 (Convolutional Neural Network)
- Framework: TensorFlow 2.10.0
- Input Size: 224x224 pixels
- Classes: 10 house plant types
- Training: Custom dataset with train/validation/test splits
- Python Version: 3.9.5 (specifically configured)
- Update the
plant_classes.jsonfile - Retrain the model with new data
- Update the model file
plant_species_Model.h5 - Upload the new model to Google Drive and update the file ID
The training process is documented in plant-species-classification-resnet50-eda.ipynb. To retrain:
- Prepare your dataset in the
DATA/directory - Run the Jupyter notebook
- Replace
plant_species_Model.h5with the new model - Update the Google Drive link in the code and documentation
app.py: Main FastAPI application with endpoints and model loadingplant_classes.json: Class mapping configurationrequirements.txt: Python dependenciesProcfile: Railway deployment configurationruntime.txt: Python version specification
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- ResNet50 architecture for image classification
- FastAPI team for the excellent web framework
- Railway for seamless deployment
- The plant dataset contributors
If you encounter compatibility issues, ensure you're using Python 3.9.5:
python --versionIf you need to install Python 3.9.5:
- Windows: Download from python.org
- macOS: Use
pyenv install 3.9.5 - Linux: Use your package manager or
pyenv install 3.9.5
If you encounter dependency conflicts:
- Create a fresh virtual environment:
python -m venv venv - Activate it:
source venv/bin/activate(Linux/macOS) orvenv\Scripts\activate(Windows) - Install dependencies:
pip install -r requirements.txt
If the model fails to download during deployment:
- Check your internet connection
- Verify the Google Drive link is accessible
- Ensure the file ID is correct:
1rKl_jRCbTixMHIOct95pLyta1Q5tPgrk - Check Railway logs for download errors
- Model Loading: The model takes ~30-60 seconds to load on first startup
- Prediction Time: Each prediction takes 1-3 seconds depending on image size
- Memory Usage: The model requires ~500MB RAM when loaded
For issues and questions:
- Create an issue in the repository
- Check the API documentation at
/docswhen running locally - Review the health endpoint at
/healthfor system status - Check Railway deployment logs for troubleshooting
| Issue | Solution |
|---|---|
| Model not loading | Check Google Drive link accessibility |
| Slow predictions | Normal for first few requests (model warming up) |
| Memory errors | Ensure sufficient RAM (500MB+ recommended) |
| CORS errors | API supports CORS for web applications |
| File upload errors | Check image format (JPEG, PNG supported) |
- LinkedIn: Swayam Agarwal
- GitHub: SwayamAg
- Repository: Plant Classification API
Note:
- For local development: Download the
plant_species_Model.h5model file from Google Drive and place it in the root directory - For deployment: The model is automatically downloaded from Google Drive during startup
- Model file size: ~295MB (not included in repository due to size constraints)