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:
public
andsrc
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 backend
python app.py
- Start the React Frontend
cd frontend
npm start