Skip to content

Commit f09327e

Browse files
committedOct 19, 2024
Integrated paddy prediction
1 parent c9b88ad commit f09327e

File tree

7 files changed

+172
-52
lines changed

7 files changed

+172
-52
lines changed
 

‎agrotech-ai-apis/.env-sample

-1
This file was deleted.

‎agrotech-ai-apis/app.py

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
import os
1010
from mushroom_edibility import check_mushroom_edibility
11+
from paddy_prediction import paddy_prediction
1112

1213
# Initialize Google Gemini API with the embedded key
1314
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
@@ -97,6 +98,21 @@ def find_ee_shops():
9798
def mushroom_edibility():
9899
return check_mushroom_edibility()
99100

101+
# API route to handle paddy disease prediction
102+
@app.route('/submit_paddy', methods=['POST'])
103+
def submit_paddy():
104+
if 'image' not in request.files:
105+
return jsonify({'error': 'No image part in the request'}), 400
106+
107+
image = request.files['image']
108+
filename = image.filename
109+
file_path = os.path.join('uploaded_image', filename)
110+
image.save(file_path)
111+
112+
result = paddy_prediction(file_path)
113+
return jsonify(result), 200
114+
115+
100116
# Run the Flask app
101117
if __name__ == "__main__":
102118
app.run(debug=True)

‎agrotech-ai-apis/models/rice_model.h5

1.53 MB
Binary file not shown.

‎agrotech-ai-apis/paddy_prediction.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# paddy_prediction.py
2+
3+
import os
4+
import tensorflow as tf
5+
from tensorflow.keras.models import load_model
6+
from tensorflow.keras.preprocessing.image import load_img, img_to_array
7+
import numpy as np
8+
9+
# Load your trained model (make sure to adjust the model path)
10+
model = load_model('models/rice_model.h5')
11+
12+
# Class labels for the paddy diseases
13+
modified_class_label = ['Bacterial Leaf Blight', 'Bacterial Leaf Streak', 'Bacterial Panicle Blight', 'Blast',
14+
'Brown Spot', 'Dead Heart', 'Downy Mildew', 'Hispa', 'Normal', 'Tungro']
15+
16+
LABEL_DESCRIPTION = [
17+
{
18+
"label": "bacterial_leaf_blight",
19+
"description": "A bacterial infection that causes dark, water-soaked lesions on the leaves of the sugarcane plant.",
20+
"symptoms": "Yellowing and browning of the leaves, water-soaked spots, and leaf curling.",
21+
"impact": "Severe infection can lead to yield loss due to impaired photosynthesis.",
22+
"recommended_action": "Apply copper-based bactericides and practice crop rotation to reduce bacterial spread."
23+
},
24+
{
25+
"label": "bacterial_leaf_streak",
26+
"description": "A bacterial disease that manifests as long, narrow streaks on the sugarcane leaves.",
27+
"symptoms": "Yellow streaks along the veins of leaves, which eventually turn brown and die.",
28+
"impact": "Leads to reduced photosynthesis and weaker plants, resulting in lower yields.",
29+
"recommended_action": "Improve field drainage, avoid overhead irrigation, and use resistant varieties."
30+
},
31+
{
32+
"label": "bacterial_panicle_blight",
33+
"description": "A bacterial disease affecting the panicle, leading to poor grain filling and discolored panicles.",
34+
"symptoms": "Browning and blighting of the panicle, poor seed formation.",
35+
"impact": "Significant yield reduction due to poor grain development.",
36+
"recommended_action": "Remove infected plants, ensure good field hygiene, and use disease-resistant varieties."
37+
},
38+
{
39+
"label": "blast",
40+
"description": "A fungal disease that attacks leaves, stems, and panicles, forming blast-like lesions.",
41+
"symptoms": "Spindle-shaped lesions with brown borders and gray centers on leaves.",
42+
"impact": "Severe yield losses due to damaged leaf tissue and weakened stems.",
43+
"recommended_action": "Apply appropriate fungicides, use resistant varieties, and ensure proper field drainage."
44+
},
45+
{
46+
"label": "brown_spot",
47+
"description": "A fungal infection that causes brown lesions on leaves, particularly older leaves.",
48+
"symptoms": "Small, round to oval brown spots with gray or brown centers.",
49+
"impact": "Moderate to severe defoliation, reduced photosynthesis, and yield loss.",
50+
"recommended_action": "Apply foliar fungicides, improve air circulation, and maintain crop health with balanced fertilization."
51+
},
52+
{
53+
"label": "dead_heart",
54+
"description": "A condition where the central shoot of the sugarcane plant dies, often due to insect or disease damage.",
55+
"symptoms": "The central shoot dies and turns brown, while surrounding leaves remain unaffected.",
56+
"impact": "Reduced yield due to stunted plant growth and loss of the main shoot.",
57+
"recommended_action": "Remove affected plants and control pests or pathogens causing the condition."
58+
},
59+
{
60+
"label": "downy_mildew",
61+
"description": "A fungal disease that affects the leaves, causing a downy, mold-like growth on the surface.",
62+
"symptoms": "White to grayish fungal growth on the underside of leaves, along with yellowing and browning.",
63+
"impact": "Weakened plants, reduced photosynthesis, and yield loss.",
64+
"recommended_action": "Apply appropriate fungicides, practice crop rotation, and avoid overhead irrigation."
65+
},
66+
{
67+
"label": "hispa",
68+
"description": "An insect pest that causes damage to sugarcane by feeding on the leaves, leaving white streaks.",
69+
"symptoms": "White, linear streaks along the leaves, caused by larvae feeding within the leaf tissues.",
70+
"impact": "Severe infestations can lead to significant leaf area loss, reducing photosynthesis and yield.",
71+
"recommended_action": "Use insecticides and biological controls like parasitic wasps to manage hispa populations."
72+
},
73+
{
74+
"label": "normal",
75+
"description": "The sugarcane plant is healthy and vigorous, displaying bright green leaves without any signs of disease.",
76+
"symptoms": "None observed.",
77+
"impact": "No adverse effects on yield; optimal growth.",
78+
"recommended_action": "Maintain regular care practices, including proper irrigation and nutrient management."
79+
},
80+
{
81+
"label": "tungro",
82+
"description": "A viral disease transmitted by leafhoppers, causing stunted growth and discoloration of leaves.",
83+
"symptoms": "Yellow-orange discoloration of leaves, stunted growth, and poor tillering.",
84+
"impact": "Severe yield loss due to stunted plants and reduced grain production.",
85+
"recommended_action": "Use resistant varieties, control leafhopper populations, and remove infected plants."
86+
}
87+
]
88+
89+
def preprocess_image(image_path, target_size=(256, 256)):
90+
img = load_img(image_path, target_size=target_size)
91+
img_array = img_to_array(img)
92+
img_array = np.expand_dims(img_array, axis=0)
93+
img_array = tf.cast(img_array / 255.0, tf.float32)
94+
return img_array
95+
96+
def predict_paddy(filepath):
97+
predictions = model.predict(preprocess_image(filepath))
98+
predicted_class = np.argmax(predictions, axis=1)
99+
return predicted_class[0] # Return the class index
100+
101+
def paddy_prediction(image_path):
102+
try:
103+
label_index = predict_paddy(image_path)
104+
label = modified_class_label[label_index]
105+
os.remove(image_path) # Clean up the image after prediction
106+
return {
107+
'prediction': label,
108+
'details': LABEL_DESCRIPTION[label_index]
109+
}
110+
except Exception as e:
111+
return {"error": str(e)}

‎agrotech-ai-apis/requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ matplotlib
99
scikit-learn
1010
xgboost
1111
seaborn
12+
pillow
13+
tensorflow
1214
gunicorn

‎frontend/src/components/help/Climate.jsx

+43-51
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ import React, { useEffect, useState } from 'react';
22
import { WiHumidity, WiBarometer, WiStrongWind, WiThermometer, WiSunrise, WiSunset, WiCloudyGusts } from 'react-icons/wi';
33
import { Search } from 'lucide-react';
44

5-
// API key (Note: In a production environment, this should be stored securely)
65
const API_KEY = 'af0348ed3ad216d028627277b50db13f';
76

8-
// Utility functions
97
const fetchData = async (URL) => {
108
const response = await fetch(`${URL}&appid=${API_KEY}`);
119
if (!response.ok) {
@@ -14,28 +12,23 @@ const fetchData = async (URL) => {
1412
return response.json();
1513
};
1614

17-
// OpenWeatherAPI Endpoints
1815
const url = {
19-
currentWeather: (lat, lon) =>
20-
`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}`,
21-
airPollution: (lat, lon) =>
22-
`https://api.openweathermap.org/data/2.5/air_pollution?lat=${lat}&lon=${lon}`,
23-
forecast: (lat, lon) =>
24-
`https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}`,
16+
currentWeather: (lat, lon) => `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}`,
17+
airPollution: (lat, lon) => `https://api.openweathermap.org/data/2.5/air_pollution?lat=${lat}&lon=${lon}`,
18+
forecast: (lat, lon) => `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}`,
2519
geocoding: (query) => `https://api.openweathermap.org/geo/1.0/direct?q=${query}&limit=5`,
2620
};
2721

28-
// Helper functions
29-
const getDate = (dateUnix, timezone) => {
30-
const date = new Date((dateUnix + timezone) * 1000);
31-
return date.toLocaleDateString(undefined, { weekday: 'short', month: 'short', day: 'numeric' });
32-
};
33-
3422
const getTime = (timeUnix, timezone) => {
3523
const date = new Date((timeUnix + timezone) * 1000);
3624
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
3725
};
3826

27+
const getDate = (timeUnix, timezone) => {
28+
const date = new Date((timeUnix + timezone) * 1000);
29+
return date.toLocaleDateString([], { weekday: 'long', day: 'numeric', month: 'short' });
30+
};
31+
3932
export default function Climate() {
4033
const [loading, setLoading] = useState(false);
4134
const [weatherData, setWeatherData] = useState(null);
@@ -46,7 +39,6 @@ export default function Climate() {
4639
const [searchTerm, setSearchTerm] = useState('');
4740
const [selectedLocation, setSelectedLocation] = useState('');
4841

49-
// Fetch weather data
5042
const fetchWeatherData = async (lat, lon) => {
5143
setLoading(true);
5244
setError(false);
@@ -60,7 +52,6 @@ export default function Climate() {
6052

6153
const now = new Date();
6254
const cutoffTime = new Date(now.getTime() + 24 * 60 * 60 * 1000);
63-
6455
const next24HoursForecast = forecast.list.filter((entry) => {
6556
const entryDate = new Date(entry.dt * 1000);
6657
return entryDate >= now && entryDate <= cutoffTime;
@@ -76,7 +67,6 @@ export default function Climate() {
7667
}
7768
};
7869

79-
// Handle search
8070
const handleSearch = async (e) => {
8171
e.preventDefault();
8272
if (!searchTerm) {
@@ -99,7 +89,6 @@ export default function Climate() {
9989
return;
10090
}
10191

102-
// Assuming the first result is the most relevant
10392
const { lat, lon, name, state, country } = locations[0];
10493
setSelectedLocation(`${name}${state ? ', ' + state : ''}, ${country}`);
10594
fetchWeatherData(lat, lon);
@@ -110,7 +99,6 @@ export default function Climate() {
11099
}
111100
};
112101

113-
// Handle current location
114102
const handleCurrentLocation = () => {
115103
if (!navigator.geolocation) {
116104
alert('Geolocation is not supported by your browser.');
@@ -139,10 +127,9 @@ export default function Climate() {
139127
);
140128
};
141129

142-
// Use effect to fetch current location weather on component mount
143130
useEffect(() => {
144131
handleCurrentLocation();
145-
}, []); // Empty dependency array to run only once when the component mounts
132+
}, []);
146133

147134
return (
148135
<div className="min-h-screen flex flex-col items-center bg-gradient-to-br from-blue-100 to-green-100 p-5 w-full mt-14">
@@ -174,29 +161,11 @@ export default function Climate() {
174161
{error && <p className="text-red-500">Error fetching data. Please try again.</p>}
175162

176163
{weatherData && (
177-
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 w-full max-w-4xl">
178-
{/* Current Weather */}
179-
<div className="bg-white rounded-xl shadow-lg p-6 transition duration-300 hover:shadow-xl">
180-
<h2 className="text-3xl font-bold text-center text-gray-800 mb-4">
181-
{selectedLocation || weatherData.name}
182-
</h2>
183-
<div className="flex flex-col items-center">
184-
<img
185-
src={`https://openweathermap.org/img/wn/${weatherData.weather[0].icon}@4x.png`}
186-
alt={weatherData.weather[0].description}
187-
className="w-32 h-32 mb-4"
188-
/>
189-
<p className="text-6xl font-semibold text-gray-800 mb-2">
190-
{Math.round(weatherData.main.temp - 273.15)}°C
191-
</p>
192-
<p className="text-xl text-gray-600 capitalize">{weatherData.weather[0].description}</p>
193-
</div>
194-
</div>
195-
196-
{/* Weather Details */}
197-
<div className="bg-white rounded-xl shadow-lg p-6 transition duration-300 hover:shadow-xl">
198-
<h3 className="text-2xl font-semibold mb-4 text-center text-gray-800">Current Conditions</h3>
199-
<div className="grid grid-cols-2 gap-4">
164+
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 w-full max-w-4xl mt-16">
165+
<WeatherCard weatherData={weatherData} airQualityIndex={airQualityIndex} selectedLocation={selectedLocation} />
166+
<div className="rounded-xl p-6 transition duration-300 hover:shadow-xl group hover:-rotate-0 [transform:rotate3d(1_,-1,_1,_15deg)] duration-500 overflow-hidden bg-gradient-to-bl from-green-400 via-green-500 to-green-700 p-6 rounded-lg hover:shadow-lg [box-shadow:12px_12px_0px_0px_#0d0d0d] backdrop-filter backdrop-blur-md border border-neutral-600">
167+
<h3 className="text-2xl font-semibold mb-4 text-center text-gray-800 ">Current Conditions</h3>
168+
<div className="grid grid-cols-2 gap-4 group">
200169
<WeatherDetail icon={WiHumidity} label="Humidity" value={`${weatherData.main.humidity}%`} />
201170
<WeatherDetail icon={WiThermometer} label="Feels Like" value={`${Math.round(weatherData.main.feels_like - 273.15)}°C`} />
202171
<WeatherDetail icon={WiStrongWind} label="Wind Speed" value={`${Math.round(weatherData.wind.speed * 3.6)} km/h`} />
@@ -211,7 +180,7 @@ export default function Climate() {
211180

212181
{/* 5-Day Forecast */}
213182
{forecastData.length > 0 && (
214-
<div className="mt-8 w-full max-w-4xl bg-white rounded-xl shadow-lg p-6 transition duration-300 hover:shadow-xl">
183+
<div className="mt-16 w-full max-w-4xl bg-white rounded-xl shadow-lg p-6 transition duration-300 hover:shadow-xl duration-500 overflow-hidden bg-gradient-to-bl from-green-400 via-green-500 to-green-700 p-6 rounded-lg hover:shadow-lg [box-shadow:12px_12px_0px_0px_#0d0d0d] backdrop-filter backdrop-blur-md border border-neutral-600">
215184
<h3 className="text-2xl font-semibold mb-4 text-center text-gray-800">5-Day Forecast</h3>
216185
<div className="grid grid-cols-2 md:grid-cols-5 gap-4">
217186
{forecastData.map((forecast, index) => (
@@ -232,7 +201,7 @@ export default function Climate() {
232201

233202
{/* Hourly Forecast */}
234203
{currentWeather.length > 0 && (
235-
<div className="mt-8 w-full max-w-4xl bg-white rounded-xl shadow-lg p-6 transition duration-300 hover:shadow-xl">
204+
<div className="mt-16 mb-10 w-full max-w-4xl bg-white rounded-xl shadow-lg p-6 transition duration-300 duration-500 overflow-hidden bg-gradient-to-bl from-green-400 via-green-500 to-green-700 p-6 rounded-lg hover:shadow-lg [box-shadow:12px_12px_0px_0px_#0d0d0d] backdrop-filter backdrop-blur-md border border-neutral-600">
236205
<h3 className="text-2xl font-semibold mb-4 text-center text-gray-800">Hourly Forecast</h3>
237206
<div className="overflow-x-auto">
238207
<div className="inline-flex space-x-4 pb-4">
@@ -256,13 +225,36 @@ export default function Climate() {
256225
);
257226
}
258227

228+
function WeatherCard({ weatherData, airQualityIndex, selectedLocation }) {
229+
return (
230+
<div className="bg-gradient-to-br from-sky-500 to-blue-500 p-8 rounded-xl shadow-lg transition duration-300 hover:-rotate-0 [transform:rotate3d(1_,-1,_1,_15deg)] duration-500 overflow-hidden bg-gradient-to-bl from-green-400 via-green-500 to-green-700 p-6 rounded-lg hover:shadow-lg [box-shadow:12px_12px_0px_0px_#0d0d0d] backdrop-filter backdrop-blur-md border border-neutral-600">
231+
<div className="flex flex-col items-center justify-center text-center">
232+
<div>
233+
<h2 className="text-4xl font-bold text-white mt-2">{selectedLocation || weatherData.name}</h2>
234+
<p className="text-xl text-gray-200 mt-4">{weatherData.weather[0].description}</p>
235+
</div>
236+
<img
237+
src={`http://openweathermap.org/img/w/${weatherData.weather[0].icon}.png`}
238+
alt={weatherData.weather[0].description}
239+
className="w-36 h-36 my-4"
240+
/>
241+
</div>
242+
<div className="mt-4 text-white text-center">
243+
<p className="text-5xl font-semibold">
244+
{Math.round(weatherData.main.temp - 273.15)}°C
245+
</p>
246+
</div>
247+
</div>
248+
);
249+
}
250+
259251
function WeatherDetail({ icon: Icon, label, value }) {
260252
return (
261-
<div className="flex items-center space-x-2">
262-
<Icon className="w-8 h-8 text-blue-500" />
253+
<div className="flex items-center space-x-3 bg-white p-4 rounded-lg shadow-md hover:shadow-lg transition duration-300 ease-in-out">
254+
<Icon className="w-8 h-8 text-sky-500" />
263255
<div>
264-
<p className="text-sm text-gray-600">{label}</p>
265-
<p className="text-lg font-semibold text-gray-800">{value}</p>
256+
<h3 className="text-lg font-medium text-gray-800">{label}</h3>
257+
<p className="text-sm text-gray-600">{value}</p>
266258
</div>
267259
</div>
268260
);
Binary file not shown.

0 commit comments

Comments
 (0)
Please sign in to comment.