How to use Google Gemini AI for Agriculture Productivity

vishalmysore - May 7 - - Dev Community

Food For Thought!

Crop losses resulting from pests and diseases pose substantial challenges to Indian agriculture, a concern shared globally. However with India's considerable strides in digitization, leveraging AI emerges as a promising solution for swiftly identifying crop issues such as diseases and pests. This technological approach facilitates prompt corrective actions, ensuring enhanced agricultural productivity and sustainability.

Image description

AI To the Rescue

Presenting few use cases with examples and working code on how AI can be used with agriculture. This approach uses Gemini and Java with Tools4AI. The complete code is available as opensource for reference and enhancement

We will use various aspects of Tools4AI to convert image into Pojo or JSON and take actions

Pojo

Lets define our Pojo first, I have kept it simple with basic parameters you can add more parameters to it. Please make sure parameter names are meaningful as Tools4AI maps the parameter names dynamically to the AI prompt. '@'Prompt Annotations are optional and can be used within the POJO to give special instructions to Gemini. In this case I am asking Gemini to provide plantType in one of the 4 different categories, also for the healthPercentage I am asking it to give 100% if the crop looks healthy. You can use as many prompt annotation inside Pojo to make it more meaningful if required.

@NoArgsConstructor
@Getter
@Setter
@ToString
public class Plant {
    @Prompt(describe ="what type is it CROP or FRUIT or VEGETABLE or FLOWER or TREE or SHRUB or GRASS or WEED or OTHER")
    String plantType;
    String plantName;
    @Prompt(describe ="if it looks healthy then give 100% else give a percentage")
    double healthPercentage;
    double waterPercentage;
    double soilPercentage;
    double sunlightPercentage;
    double temperature;
    boolean hasPest = false;
    boolean hasDisease = false;;
    boolean hasNutrientDeficiency = false;;
    boolean hasWaterDeficiency = false;;
    boolean hasSunlightDeficiency = false;;
    boolean hasSoilDeficiency = false;;
    boolean hasTemperatureDeficiency = false;;
    boolean hasFrost = false;;
    boolean hasHeatWave = false;;
    boolean hasDrought = false;;
    boolean hasFlood= false;;
    boolean doesItHaveAnyDisease = false;
    @Prompt(describe ="based on picture do you think the plant has any disease, if none then return NONE")
    String typeOfDisease;
}

Enter fullscreen mode Exit fullscreen mode

The image of the plant will be converted to this Pojo object in real time based on Google Gemini image api. Once its converted to Pojo various actions can be taken by Tools4AI Action Processor.

Image description

Example 1

Lets take an image of healthy corn plant

Image description

The image can be found here

lets convert this image to Json , you can convert to Pojo as well but for this example I am using JSON . You can add any number of JSON parameter names as you like but keep it meaningful as Tools4AI uses names to map to image

  String urlString = "https://raw.githubusercontent.com/spMohanty/PlantVillage-Dataset/master/raw/color/Corn_(maize)___healthy/00031d74-076e-4aef-b040-e068cd3576eb___R.S_HL%208315%20copy%202.jpg";
  Url url = new URL(urlString);
 String plantDetails = (String) processor.imageToJson(url,
 "cropType", "plantName", "healthPercentage", 
"waterPercentage", "soilPercentage", "sunlightPercentage", 
"temperature", "hasPest", "hasDisease", 
"hasNutrientDeficiency", "hasWaterDeficiency", 
"hasSunlightDeficiency", 
"hasSoilDeficiency",
 "hasTemperatureDeficiency", 
"hasFrost", "hasHeatWave", 
"hasDrought", "hasFlood", "typeOfDisease");
Enter fullscreen mode Exit fullscreen mode

and the result looks like this , as you can see each field provided above has been converted into fieldName and fieldValue , this can also be converted to XML or can be used to make a rest call to another application

starting analysis of healthy corn plant
{"fields":[{"fieldName":"cropType","fieldType":"String","fieldValue":"maize"
},{"fieldName":"plantName","fieldType":"String","fieldValue":"maize"
},{"fieldName":"healthPercentage","fieldType":"String","fieldValue":
"80"},{"fieldName":"waterPercentage","fieldType":"String","fieldValue":"
70"},{"fieldName":"soilPercentage","fieldType":"String","fieldValue":"6
0"},{"fieldName":"sunlightPercentage","fieldType":"String","fieldValue
":"50"},{"fieldName":"temperature","fieldType":"String","fieldValue":"25"
},{"fieldName":"hasPest","fieldType":"String","fieldValue":"false"}
,{"fieldName":"hasDisease","fieldType":"String","fieldValue":"false
"},{"fieldName":"hasNutrientDeficiency","fieldType":"String","fieldVa
lue":"false"},{"fieldName":"hasWaterDeficiency","fieldType":"String","fieldValue
":"false"},{"fieldName":"hasSunlightDeficiency","fieldType":"String","fieldVa
lue":"false"},{"fieldName":"hasSoilDeficiency","fieldType":"String","fieldValue"
:"false"},{"fieldName":"hasTemperatureDeficiency","fieldType":"String","fiel
dValue":"false"},{"fieldName":"hasFrost","fieldType":"String","fieldValue":"false"}
,{"fieldName":"hasHeatWave","fieldType":"String","fieldValue":"fals
e"},{"fieldName":"hasDrought","fieldType":"String","fieldValue":"false
"},{"fieldName":"hasFlood","fieldType":"String","fieldValue":"false"}

,{"fieldName":"typeOfDisease","fieldType":"String","fieldValue":""}
]}

Enter fullscreen mode Exit fullscreen mode

after you convert to Json you can also ask for suggestion

log.info(processor.imageToText(url, "based on image what action should i take on this plant?"));
Enter fullscreen mode Exit fullscreen mode

The response is

 The plant is healthy and does not need any action to be taken on it.
Enter fullscreen mode Exit fullscreen mode

Image description

Example 2

Lets look at an unhealthy corn Plant

Image description

You can find the image here

Lets call Tools4AI processor again with this url

String urlString = "https://raw.githubusercontent.com/spMohanty/PlantVillage-Dataset/master/raw/color/Corn_(maize)___Northern_Leaf_Blight/0079c731-80f5-4fea-b6a2-4ff23a7ce139___RS_NLB%204121.JPG";
Url url = new URL(urlString);
 Plant plantDetails = (Plant) processor.imageToPojo(url, Plant.class);
        log.info(plantDetails.toString());

Enter fullscreen mode Exit fullscreen mode

As you can see this time we converted it to Pojo object instead of Json , you can chose any format you want either Pojo, JSON or XML or just derive plain string on actions from the image.

The result is

Plant(platType=CROP, plantName=maize, healthPercentage=70.0,
 waterPercentage=80.0, soilPercentage=90.0, 
sunlightPercentage=100.0, temperature=30.0, hasPest=true,
 hasDisease=true, hasNutrientDeficiency=false, 
hasWaterDeficiency=false, hasSunlightDeficiency=false, 
hasSoilDeficiency=false, hasTemperatureDeficiency=false,
 hasFrost=false, hasHeatWave=false, hasDrought=false, 
hasFlood=false, doesItHaveAnyDisease=true, typeOfDisease=Leaf 
Blight)
Enter fullscreen mode Exit fullscreen mode

and when I ask Gemini for action suggestion

log.info(processor.imageToText(url, "based on image what action 
should i take on this plant?"));
Enter fullscreen mode Exit fullscreen mode

The result is

The image shows a corn leaf with symptoms of northern corn leaf 
blight. This disease is caused by the fungus Exserohilum turcicum.
 The fungus produces toxins that cause the leaves to develop long,
 narrow lesions that are tan to brown in color. The lesions may
 start out as small, water-soaked spots that later expand and
 coalesce. In severe cases, the leaves may dry out and die. 
Northern corn leaf blight can cause significant yield losses in 
corn.
Enter fullscreen mode Exit fullscreen mode

The beauty of Tools4AI lies in its capability to execute actions based on image descriptions, expanding its functionality as an extensive action model or LLM agent. You can read about it here

For instance, consider the scenario of estimating plant water intake based on forecasted weather. This action can be seamlessly integrated into the prediction list, enhancing adaptability and functionality.

@Log
@Predict
public class WeatherAction  {
    @Action(description = "get weather for city")
    public double getTemperature(String cityName) {
        double temperature = 0;
        String urlStr = "https://geocoding-api.open-meteo.com/v1/search?name="+cityName+"&count=1&language=en&format=json";
        String weatherURlStr = "https://api.open-meteo.com/v1/forecast?latitude=";
        try {
            StringBuilder response = getResponseFromURl(urlStr);

            // Parse JSON response
            JSONObject jsonObject  = new JSONObject(response.toString());

            // Extract latitude and longitude from the JSON response
            JSONArray resultsArray = jsonObject.getJSONArray("results");

            // Extract latitude and longitude from the first element of the "results" array
            if (resultsArray.length() > 0) {
                JSONObject result = resultsArray.getJSONObject(0);
                double latitude = result.getDouble("latitude");
                double longitude = result.getDouble("longitude");

                // Print latitude and longitude
                log.info("Latitude: " + latitude);
                log.info("Longitude: " + longitude);


                weatherURlStr = weatherURlStr+latitude+"&longitude="+longitude+"&current=temperature_2m";
                response = getResponseFromURl(weatherURlStr);

                log.info(response.toString());
                jsonObject = new JSONObject(response.toString());
                // Get the "current" object
                JSONObject currentObject = jsonObject.getJSONObject("current");

                // Extract the temperature value
                temperature = currentObject.getDouble("temperature_2m");

                // Print the temperature value
                log.info("Temperature: " + temperature + " °C");
            } else {
                log.info("No results found for the longitude and latidue for the city , city is invalid");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return temperature;
    }
Enter fullscreen mode Exit fullscreen mode

Another action example, the CropRecommendationAction class demonstrates an action that recommends a crop based on soil type and climate conditions. By providing inputs for soil type and climate, the action uses predefined rules to suggest an appropriate crop for cultivation. This functionality can be valuable for farmers and agricultural experts seeking guidance on crop selection for optimal yield and sustainability.

@Log
@Predict
public class CropRecommendationAction  {
    @Action(description = "recommend crop based on soil and climate")
    public String recommendCrop(String soilType, String climate) {
        String recommendedCrop = "";
        // Placeholder for actual implementation
        // For demonstration purposes, let's assume simple rules for crop recommendation
        if (soilType.equalsIgnoreCase("Loamy") && climate.equalsIgnoreCase("Tropical")) {
            recommendedCrop = "Rice";
        } else if (soilType.equalsIgnoreCase("Sandy") && climate.equalsIgnoreCase("Dry")) {
            recommendedCrop = "Millet";
        } else {
            recommendedCrop = "Unknown"; // Default recommendation if conditions don't match
        }
        // Log the recommended crop
        log.info("Recommended Crop: " + recommendedCrop);
        return recommendedCrop;
    }
}

Enter fullscreen mode Exit fullscreen mode

In another example, the LocustControlAction class represents an action designed to control locust attacks based on real-time parameters such as wind speed, wind direction, temperature, and humidity. By analyzing these parameters, the action suggests appropriate measures for mitigating locust infestations, such as spraying pesticides, deploying drones, or closely monitoring the situation. This functionality can assist agricultural authorities and farmers in promptly addressing locust threats to minimize crop damage.

@Log
@Predict
public class LocustControlAction {
    @Action(description = "control locust attack based on wind direction and other parameters")
    public String controlLocustAttack(double windSpeed, double windDirection, double temperature, double humidity) {
        String actionTaken = "";
        // Placeholder for actual implementation
        // For demonstration purposes, let's assume simple rules for locust control
        if (windSpeed > 10 && windDirection >= 180 && windDirection <= 270) {
            actionTaken = "Spraying pesticide in the affected area.";
        } else if (temperature > 30 && humidity > 70) {
            actionTaken = "Deploying drones to disperse locust swarms.";
        } else {
            actionTaken = "Monitoring the situation closely.";
        }
        // Log the action taken
        log.info("Action Taken: " + actionTaken);
        return actionTaken;
    }
}

Enter fullscreen mode Exit fullscreen mode

Tools4AI offers versatile applications like the examples provided earlier. It can work with Google Gemini, OpenAI and Anthropic and Since the entire codebase is written in Java, it can be executed on any Java-enabled device, including Android phones. Furthermore, as an open-source project, developers have the opportunity to enhance, contribute to, or share the codebase, fostering collaborative innovation in AI-driven solutions for various domains.

Code for above example is available here

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .