---
title: Key Concepts
product: plant-health-prediction-using-cnn
doc_type: concept
version: main
source: git2docs (code-derived, validation-filtered)
canonical: https://git2docs.com/source2books/docs/plant-health-prediction-using-cnn/plant-disease-predictor/key-concepts
---

# Key Concepts

_Domain concepts and API design patterns_

## Overview

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](https://www.kaggle.com/datasets/abdallahalidev/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

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

| Field | Type | Description |
|-------|------|-------------|
| `file` | Binary (image) | The leaf image to classify |

### Response structure

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

| Field | Type | Description |
|-------|------|-------------|
| `class_index` | Integer | Numeric index of the predicted disease class (0–37) |
| `label` | String | Human-readable disease label (e.g., `Tomato___Early_blight`) |
| `plant` | String | Extracted plant species (e.g., `Tomato`) |
| `condition` | String | Extracted condition name (e.g., `Early_blight` or `healthy`) |

> **Note for reviewer:** The exact response field names are inferred from the class index structure and common API conventions. Confirm these against the actual application route handlers (`app.py` or equivalent) before publishing.

## Authentication

> **Note for reviewer:** No authentication mechanism (API keys, OAuth, JWT, etc.) is described in the source material. If the API is publicly accessible without auth (e.g., a local or Docker-deployed instance), this should be stated explicitly. If auth is planned or exists in the deployment layer, add those details here.

## Error Handling

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

| Status Code | Meaning | Common Cause |
|-------------|---------|---------------|
| `400 Bad Request` | The request was malformed | Missing `file` field, unsupported file format |
| `422 Unprocessable Entity` | The image could not be processed | Corrupt image data, non-leaf image |
| `500 Internal Server Error` | Unexpected server-side failure | Model inference error |

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

```json
{
  "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.

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

**Expected response (HTTP 200):**

```json
{
  "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`.

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

**Expected response (HTTP 200):**

```json
{
  "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.

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

**Expected response (HTTP 400):**

```json
{
  "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.

```python
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
```

> **Note for reviewer:** The endpoint URL (`/predict`) and port (`8501`, the default Streamlit port) are inferred from the Streamlit deployment context. Verify the exact route path against the application source before publishing.

## 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.
