Building a Plant Detection Web Application: A Step-by-Step Guide
In this blog, we’ll create a fully functional web application that detects plants from images using a machine learning model. This application uses Flask as the backend, TensorFlow for the ML model, and React.js for the frontend. By the end of this guide, you’ll have a working app that can predict the name of a plant from an image.
What You’ll Learn
- Building a machine learning model for image classification.
- Setting up a Flask backend to handle predictions.
- Creating a React.js frontend for image uploads and displaying results.
- Integrating everything into a seamless application.
Key Features of the Plant Detection App
- Image Upload: Users can upload an image of a plant.
- Plant Identification: The app identifies the plant species using a trained ML model.
- Confidence Score: Displays the confidence score for the prediction.
- Plant Details: Provides additional information about the identified plant.
- User-Friendly Interface: A clean and interactive frontend built with React.js.
Prerequisites for creating Plant Detection web app
Before starting, ensure you have the following:
- Basic Knowledge: Familiarity with Python, React.js, and machine learning concepts.
- Tools Installed:
- Python 3.8+
- Node.js (with npm or yarn)
- TensorFlow or Keras for ML
- Dependencies: Install these as you progress:
- Python: flask, flask-cors, tenserflow, pillow
- React: axios
- Dataset: A labeled plant dataset for training (e.g. PlantVillage).
Folder Structure setup
- Create a root folder named
Plant-detection-web-app - Inside the root folder create three folders named:
frontend, backend anddataset - Inside the frontend folder create two folders named:
publicandsrc
Train the Machine Learning Model
The first step in building the plant detection web application is training a machine learning model capable of identifying plant species from images. We’ll use TensorFlow to create a Convolutional Neural Network (CNN) that processes images and classifies them into predefined categories. The model is trained on a labeled dataset, such as PlantVillage, where each image is associated with its plant type. During training, the model learns patterns like leaf shapes, colors, and textures that are unique to each species.
create a separate file (train.model.py) under the backend folder:
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
# data prep
train_datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)
train_generator = train_datagen.flow_from_directory(
'dataset/train', target_size=(224, 224), batch_size=32, class_mode='categorical', subset='training')
val_generator = train_datagen.flow_from_directory(
'dataset/train', target_size=(224, 224), batch_size=32, class_mode='categorical', subset='validation')
# model
model = Sequential([
Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),
MaxPooling2D(2, 2),
Flatten(),
Dense(128, activation='relu'),
Dense(len(train_generator.class_indices), activation='softmax')
])
# compile and train
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(train_generator, validation_data=val_generator, epochs=10)
# save the model
model.save('plant_model.h5')
Dependencies required for Plant Detection web-app
create a file named dependencies.txt in backend folder
flask flask-cors tensorflow pillow
then run a command in your terminal:
pip install -r dependencies.txt
Create the Flask Backend
Create a file named app.py in backend folder.
from flask import Flask, request, jsonify
from flask_cors import CORS
import tensorflow as tf
from PIL import Image
import numpy as np
app = Flask(__name__)
CORS(app)
# Load the trained model
model = tf.keras.models.load_model("plant_model.h5")
CLASS_NAMES = ['Rose', 'Sunflower', 'Tulip', 'Daisy', 'Dandelion']
def preprocess_image(image):
image = image.resize((224, 224))
image = np.array(image) / 255.0
image = np.expand_dims(image, axis=0)
return image
@app.route('/predict', methods=['POST'])
def predict():
if 'file' not in request.files:
return jsonify({"error": "No file uploaded"}), 400
file = request.files['file']
img = Image.open(file.stream).convert('RGB')
processed_img = preprocess_image(img)
predictions = model.predict(processed_img)
class_idx = np.argmax(predictions)
class_name = CLASS_NAMES[class_idx]
confidence = float(predictions[0][class_idx])
return jsonify({"plant": class_name, "confidence": confidence})
if __name__ == '__main__':
app.run(debug=True)
Build the React Frontend
Create a app.js file inside of src folder in the frontend folder.
import React, { useState } from 'react';
import axios from 'axios';
import './App.css';
function App() {
const [file, setFile] = useState(null);
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
const handleFileChange = (e) => {
setFile(e.target.files[0]);
setResult(null);
setError(null);
};
const handleSubmit = async () => {
if (!file) {
setError("Please upload a file first.");
return;
}
const formData = new FormData();
formData.append('file', file);
try {
const response = await axios.post('http://127.0.0.1:5000/predict', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
setResult(response.data);
} catch (err) {
setError("Something went wrong. Please try again.");
}
};
return (
<div className="App">
<h1>Plant Detection</h1>
<input type="file" accept="image/*" onChange={handleFileChange} />
<button onClick={handleSubmit}>Predict</button>
{result && (
<div>
<h3>Prediction: {result.plant}</h3>
<p>Confidence: {(result.confidence * 100).toFixed(2)}%</p>
</div>
)}
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}
export default App;
Run and Test your web-app
-
- Start the Flask Backend
cd backendpython app.py - Start the React Frontend
cd frontend
npm start
