Plant Health Prediction Using CNNConvolutional Neural Network
Concept

Key Concepts

Domain concepts and API design patterns


Overview
Plant Disease Predictor — System Architecture PlantVillage Dataset 38 disease classes · leaf images (via Kaggle) ImageDataGenerator Augmentation · normalization Train / validation split CNN Sequential Model Conv2D · MaxPooling · Flatten Dense · Softmax (38 classes) model.keras Trained weights class_indices .json mapping load Client Farmer / Gardener Uploads leaf image Streamlit UI Web front-end Image upload widget Preprocessor Resize → 128×128 Normalize pixel values Inference Engine model.predict() Softmax probabilities Class Decoder argmax → class index index → disease label Result Display Disease name Confidence score image raw img tensor probs label shown to user Processing component ML model / inference Data / control flow Model load / feedback Logical zone / deployment boundary 38 supported classes · Apple, Blueberry, Cherry, Corn, Grape, Orange, Peach, Pepper, Potato, Raspberry, Soybean, Squash, Strawberry, Tomato

This page explains the core domain concepts and API design patterns behind the plant-disease-predictor. Understanding these concepts helps you submit well-formed requests, interpret prediction responses correctly, and handle errors gracefully. Before calling any endpoint, familiarise yourself with how the underlying CNN model classifies diseases, how class labels are structured, and how image data must be prepared.


Content

How the CNN Model Works

The plant-disease-predictor uses a Convolutional Neural Network (CNN) built with a Sequential architecture and Conv2D layers, trained on the PlantVillage dataset. When you submit a leaf image, the model processes the raw pixel data through a series of convolutional filters that extract visual features — such as colour patterns, lesion shapes, and texture gradients — before producing a probability distribution across all known disease classes.

Understanding this pipeline matters because it sets expectations for what the API can and cannot do:

  • The model was trained on colour images (RGB, 256×256 pixels). Submitting grayscale images or images at a substantially different resolution may reduce prediction accuracy.
  • The model assigns a single best-match class label per image. It does not return multiple candidate diseases or a confidence interval by default.
  • Predictions are only as reliable as the image quality you provide.

Disease Classes and the Class Index

The model recognises 38 distinct classes across 14 plant species. Each class is identified by an integer index (0–37) that maps to a human-readable label using the following pattern:

{PlantSpecies}___{ConditionName}

A ___ (triple underscore) separates the plant species from the disease or health status. The special suffix healthy indicates a leaf with no detected disease.

Full Class Index

IndexLabel
0Apple___Apple_scab
1Apple___Black_rot
2Apple___Cedar_apple_rust
3Apple___healthy
4Blueberry___healthy
5Cherry_(including_sour)___Powdery_mildew
6Cherry_(including_sour)___healthy
7Corn_(maize)___Cercospora_leaf_spot Gray_leaf_spot
8Corn_(maize)__Common_rust
9Corn_(maize)___Northern_Leaf_Blight
10Corn_(maize)___healthy
11Grape___Black_rot
12Grape___Esca_(Black_Measles)
13Grape___Leaf_blight_(Isariopsis_Leaf_Spot)
14Grape___healthy
15Orange___Haunglongbing_(Citrus_greening)
16Peach___Bacterial_spot
17Peach___healthy
18Pepper,_bell___Bacterial_spot
19Pepper,_bell___healthy
20Potato___Early_blight
21Potato___Late_blight
22Potato___healthy
23Raspberry___healthy
24Soybean___healthy
25Squash___Powdery_mildew
26Strawberry___Leaf_scorch
27Strawberry___healthy
28Tomato___Bacterial_spot
29Tomato___Early_blight
30Tomato___Late_blight
31Tomato___Leaf_Mold
32Tomato___Septoria_leaf_spot
33Tomato___Spider_mites Two-spotted_spider_mite
34Tomato___Target_Spot
35Tomato___Tomato_Yellow_Leaf_Curl_Virus
36Tomato___Tomato_mosaic_virus
37Tomato___healthy

When you receive a prediction response, the class_index field in the response body corresponds directly to this table. You should map it to the label field (also returned in the response) to present a meaningful result to end users.

Image Requirements

Because the CNN was trained on a specific image format, the API enforces constraints on uploaded images to ensure predictions are meaningful:

  • Format: JPEG or PNG
  • Colour mode: RGB (colour images)
  • Subject: A single, clearly visible leaf filling most of the frame
  • Background: Plain or natural backgrounds; heavy obstructions reduce accuracy

The API automatically resizes images internally to match the model's expected input dimensions, but you should still submit reasonably high-quality images. Blurry, partially cropped, or heavily shadowed leaf images will yield less reliable predictions.

Request/Response Design Pattern

The API follows a multipart/form-data upload → synchronous JSON response pattern. You send a single POST request containing the image file, and the API returns a prediction immediately — there is no polling or webhook involved.

Request structure

Every prediction request uses multipart/form-data encoding with a single required field:

FieldTypeDescription
fileBinary (image)The leaf image to classify

Response structure

A successful response returns a JSON object with the following fields:

FieldTypeDescription
class_indexIntegerNumeric index of the predicted disease class (0–37)
labelStringHuman-readable disease label (e.g., Tomato___Early_blight)
plantStringExtracted plant species (e.g., Tomato)
conditionStringExtracted condition name (e.g., Early_blight or healthy)

Authentication

Error Handling

The API uses standard HTTP status codes to communicate errors. Your client code should handle the following cases:

Status CodeMeaningCommon Cause
400 Bad RequestThe request was malformedMissing file field, unsupported file format
422 Unprocessable EntityThe image could not be processedCorrupt image data, non-leaf image
500 Internal Server ErrorUnexpected server-side failureModel inference error

When an error occurs, the response body contains a JSON object with an error field describing the problem:

{
  "error": "Unsupported file format. Only JPEG and PNG are accepted."
}

Always check the HTTP status code before attempting to parse a prediction result from the response body.

Reproducibility and Model Determinism

The CNN model was trained with fixed random seeds (seed=0 for Python's random, NumPy, and TensorFlow). This means the model weights are deterministic with respect to training — given the same image, the model will always return the same prediction. You do not need to account for non-deterministic behaviour in your integration.


Examples

Example 1 — Submit a leaf image and receive a prediction

This example shows how to POST a leaf image using curl and what a successful JSON response looks like.

curl -X POST http://localhost:8501/predict \
  -F "file=@/path/to/tomato_leaf.jpg"

Expected response (HTTP 200):

{
  "class_index": 29,
  "label": "Tomato___Early_blight",
  "plant": "Tomato",
  "condition": "Early_blight"
}

Example 2 — Submit a healthy leaf

When the model detects no disease, the condition field returns healthy.

curl -X POST http://localhost:8501/predict \
  -F "file=@/path/to/healthy_apple_leaf.jpg"

Expected response (HTTP 200):

{
  "class_index": 3,
  "label": "Apple___healthy",
  "plant": "Apple",
  "condition": "healthy"
}

Example 3 — Handling an error response

If you submit a file in an unsupported format (e.g., a PDF), the API returns a 400 status with an error message.

curl -X POST http://localhost:8501/predict \
  -F "file=@/path/to/document.pdf"

Expected response (HTTP 400):

{
  "error": "Unsupported file format. Only JPEG and PNG are accepted."
}

Example 4 — Python client using requests

This shows how to call the prediction endpoint from a Python script.

import requests

url = "http://localhost:8501/predict"

with open("/path/to/grape_leaf.jpg", "rb") as image_file:
    response = requests.post(url, files={"file": image_file})

if response.status_code == 200:
    result = response.json()
    print(f"Plant  : {result['plant']}")
    print(f"Condition: {result['condition']}")
    print(f"Full label: {result['label']}")
else:
    error = response.json()
    print(f"Error {response.status_code}: {error['error']}")

Expected output:

Plant    : Grape
Condition: Black_rot
Full label: Grape___Black_rot

Related concepts
  • Installation and Setup — Learn how to install dependencies, run the application locally, and deploy it using Docker before making API calls.
  • Upload Leaf Image — Step-by-step guidance on preparing and submitting a leaf image through the API.
  • Interpreting Results — How to parse the prediction response, map class indices to disease labels, and present actionable information to end users.
  • Error Reference — A complete list of API error codes, their meanings, and recommended remediation steps.
  • PlantVillage Dataset — The public dataset used to train the model, covering 38 disease and health classes across 14 plant species. Understanding the training data helps you set accurate expectations for model performance on real-world images.