Back to data catalog
Plant • Agriculture • Diseases • Health
Early disease detection in crops using open data and machine learning
OpenAPI Spec
Explore the OpenAPI spec for OpenEPI Crop Health Model API
Git Repository
Explore the source code behind OpenEPI Crop Health Model API
Client Libraries
Explore the client libraries for OpenEPI Crop Health Model API
Documentation
Explore the documentation for OpenEPI Crop Health Model API
The API uses a machine learning model to serve predictions given close-up images of crops. The data used for training consists of a vast array of labeled images from the Harvard Dataverse. These images cover a diverse range of crops such as maize, cassava, beans, cocoa, and bananas, pivotal for agricultural activities in sub-Saharan Africa. The label for an image is either "healthy" or one of several diseases. In total, approximately 120,000 labeled images were used for training.
The nine specific datasets used can be found at the following URLs: Spectrometry Cassava Dataset, Cassava Dataset Uganda, Maize Dataset Tanzania, Maize Dataset Namibia, Maize Dataset Uganda, Beans Dataset Uganda, Bananas Dataset Tanzania, Cocoa Dataset, and KaraAgro AI Maize Dataset. All datasets are licensed under the Creative Commons 1.0 DEED license.
Each dataset is downloaded programmatically from the Harvard Dataverse using HTTP requests. Each dataset is split up into several archive files, either in the form of a ZIP file or a RAR file. These files are then unpacked and processed to remove any corrupted images.
A CSV file containing the metadata (label and dimensions) for each image is generated by performing a walk through the directory structure of the dataset, and creating a row in the CSV file for each image. This file is used during training to match each image with its label. The model training process involves loading the images and labels from the CSV file, and then fine-tuning a pre-trained ResNet model in PyTorch.
The code for the models can be found in the crop-health-model repository.
The response from all three models is a JSON object with each model's respective classes paired with the confidence scores. The confidence score is a value between 0 and 1 indicating the model's confidence in the specific class. All scores are normalized to sum to 1.
Note that the models only accept images with three channels (RGB) and do not accept images with an alpha channel (RGBA). Before being passed to the model, the images undergo bilinear interpolation to resize them to 256x256 pixels. The images are then center cropped to 224x224 pixels and normalized using mean=[0.485, 0.456, 0.406] and std=[0.229, 0.224, 0.225].
Health predictions by the Binary model
1import os
2from openepi_client.crop_health import CropHealthClient
3from openepi_client.crop_health import AsyncCropHealthClient
4
5image_path = os.path.abspath("cocoa.jpg")
6
7# sync
8
9# Get the predicted health of the crop pictured in cocoa.jpg with the binary model.
10with open(image_path, "rb") as f:
11 image_data = f.read()
12 health = CropHealthClient.get_binary_prediction(image_data)
13
14# async
15
16# Get the predicted health of the crop pictured in cocoa.jpg with the binary model.
17with open(image_path, "rb") as f:
18 image_data = f.read()
19 health = await AsyncCropHealthClient.get_binary_prediction(image_data)
1import io.openepi.crop_health.api.CropHealthApi;
2import io.openepi.common.ApiException;
3import io.openepi.crop_health.model.BinaryPredictionResponse;
4import java.io.File;
5
6public class Main {
7 public static void main(String[] args) {
8 CropHealthApi api = new CropHealthApi();
9 try {
10 File file = new File("path/to/file");
11 BinaryPredictionResponse response = api.predictionsWithBinary(file);
12
13 // Print the prediction for the healthy class
14 System.out.println(response.getHLT());
15 } catch (ApiException e) {
16 System.err.println("Exception when calling CropHealthApi#predictionsWithBinary");
17 e.printStackTrace();
18 }
19 }
20}
1import { CropHealthClient } from 'openepi-client';
2import * as fs from 'fs';
3const image = fs.readFileSync('./cocoa.jpg');
4
5const client = new CropHealthClient();
6client.getBinaryPrediction(image).then((result) => {
7 const { data, error } = result;
8 if (error) {
9 console.error(error);
10 } else {
11 console.log(data);
12 }
13});
Health predictions by the SingleHLT model
1import os
2from openepi_client.crop_health import CropHealthClient
3from openepi_client.crop_health import AsyncCropHealthClient
4
5image_path = os.path.abspath("cocoa.jpg")
6
7# sync
8
9# Get the predicted health of the crop pictured in cocoa.jpg with the single-HLT model.
10with open(image_path, "rb") as f:
11 image_data = f.read()
12 health = CropHealthClient.get_singleHLT_prediction(image_data)
13
14# async
15
16# Get the predicted health of the crop pictured in cocoa.jpg with the single-HLT model.
17with open(image_path, "rb") as f:
18 image_data = f.read()
19 health = await AsyncCropHealthClient.get_singleHLT_prediction(image_data)
1import io.openepi.crop_health.api.CropHealthApi;
2import io.openepi.common.ApiException;
3import io.openepi.crop_health.model.SingleHLTPredictionResponse;
4import java.io.File;
5
6public class Main {
7 public static void main(String[] args) {
8 CropHealthApi api = new CropHealthApi();
9 try {
10 File file = new File("path/to/file");
11 SingleHLTPredictionResponse response = api.predictionsWithSingleHLT(file);
12
13 // Print the prediction for the CBSD class
14 System.out.println(response.getCSSVD());
15 } catch (ApiException e) {
16 System.err.println("Exception when calling CropHealthApi#predictionsWithSingleHLT");
17 e.printStackTrace();
18 }
19 }
20}
1import { CropHealthClient } from 'openepi-client';
2import * as fs from 'fs';
3const image = fs.readFileSync('./cocoa.jpg');
4
5const client = new CropHealthClient();
6client.getSingleHLTPrediction(image).then((result) => {
7 const { data, error } = result;
8 if (error) {
9 console.error(error);
10 } else {
11 console.log(data);
12 }
13});
Health predictions by the MultiHLT model
1import os
2from openepi_client.crop_health import CropHealthClient
3from openepi_client.crop_health import AsyncCropHealthClient
4
5image_path = os.path.abspath("cocoa.jpg")
6
7# sync
8
9# Get the predicted health of the crop pictured in cocoa.jpg with the multi-HLT model.
10with open(image_path, "rb") as f:
11 image_data = f.read()
12 health = CropHealthClient.get_multiHLT_prediction(image_data)
13
14# async
15
16# Get the predicted health of the crop pictured in cocoa.jpg with the multi-HLT model.
17with open(image_path, "rb") as f:
18 image_data = f.read()
19 health = await AsyncCropHealthClient.get_multiHLT_prediction(image_data)
1import io.openepi.crop_health.api.CropHealthApi;
2import io.openepi.common.ApiException;
3import io.openepi.crop_health.model.MultiHLTPredictionResponse;
4import java.io.File;
5
6public class Main {
7 public static void main(String[] args) {
8 CropHealthApi api = new CropHealthApi();
9 try {
10 File file = new File("path/to/file");
11 MultiHLTPredictionResponse response = api.predictionsWithMultiHLT(file);
12
13 // Print the prediction for the MLN_maize class
14 System.out.println(response.getMlNMaize());
15 } catch (ApiException e) {
16 System.err.println("Exception when calling CropHealthApi#predictionsWithMultiHLT");
17 e.printStackTrace();
18 }
19 }
20}
1import { CropHealthClient } from 'openepi-client';
2import * as fs from 'fs';
3const image = fs.readFileSync('./cocoa.jpg');
4
5const client = new CropHealthClient();
6client.getMultiHLTPrediction(image).then((result) => {
7 const { data, error } = result;
8 if (error) {
9 console.error(error);
10 } else {
11 console.log(data);
12 }
13});