lyimo commited on
Commit
aff0043
·
verified ·
1 Parent(s): 3b8895a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -324
app.py CHANGED
@@ -1,338 +1,109 @@
1
  import os
2
- import urllib.request
3
  import gradio as gr
4
- import numpy as np
5
- from part1_data import TobaccoAnalyzer
6
- from part2_visualization import VisualizationHandler
7
- from part3 import SAMAnalyzer
8
- import time
9
 
10
- MODEL_PATH = 'sam_vit_h_4b8939.pth'
11
-
12
- def download_with_progress(url, filename):
13
- if os.path.exists(filename):
14
- print(f"Model already exists at {filename}")
15
- return
16
- print(f"Downloading {filename}...")
17
- start_time = time.time()
18
- urllib.request.urlretrieve(url, filename)
19
- end_time = time.time()
20
- print(f"Download completed in {end_time - start_time:.2f} seconds")
21
-
22
- # Download SAM model if it doesn't exist
23
- if not os.path.exists(MODEL_PATH):
24
- try:
25
- download_with_progress(
26
- 'https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth',
27
- MODEL_PATH
28
- )
29
- except Exception as e:
30
- print(f"Error downloading SAM model: {e}")
31
- print("Please ensure you have internet connection and sufficient disk space.")
32
-
33
- def analyze_location(location_name):
34
- """Analyze location using weather and satellite data"""
35
- try:
36
- analyzer = TobaccoAnalyzer()
37
- visualizer = VisualizationHandler(analyzer.optimal_conditions)
38
-
39
- # Get coordinates from location name
40
- location_data = analyzer.geocode_location(location_name)
41
- if not location_data:
42
- return None, None, "Location not found. Please try a different location name.", None
43
-
44
- lat, lon = location_data['lat'], location_data['lon']
45
-
46
- # Get weather data
47
- df = analyzer.get_weather_data(lat, lon, historical_days=90, forecast_days=90)
48
- if df is None or df.empty:
49
- return None, None, "Unable to fetch weather data. Please try again.", None
50
-
51
- # Separate historical and forecast data
52
- historical = df[df['type'] == 'historical']
53
- forecast = df[df['type'] != 'historical']
54
-
55
- if historical.empty:
56
- return None, None, "No historical data available.", None
57
-
58
- # Calculate base scores
59
- temp_score = np.clip((historical['temperature'].mean() - 15) / (30 - 15), 0, 1)
60
- humidity_score = np.clip((historical['humidity'].mean() - 50) / (80 - 50), 0, 1)
61
- rainfall_score = np.clip(historical['rainfall'].mean() / 5, 0, 1)
62
- ndvi_score = np.clip((historical['estimated_ndvi'].mean() + 1) / 2, 0, 1)
63
-
64
- # Get trends analysis
65
- trends = analyzer.analyze_trends(df)
66
- if trends is None:
67
- return None, None, "Error calculating trends.", None
68
-
69
- # Calculate overall score
70
- weights = {
71
- 'temperature': 0.3,
72
- 'humidity': 0.2,
73
- 'rainfall': 0.2,
74
- 'ndvi': 0.3
75
- }
76
-
77
- overall_score = (
78
- temp_score * weights['temperature'] +
79
- humidity_score * weights['humidity'] +
80
- rainfall_score * weights['rainfall'] +
81
- ndvi_score * weights['ndvi']
82
- )
83
-
84
- # Create visualizations
85
- time_series_plot = visualizer.create_interactive_plots(df)
86
- gauge_plot = visualizer.create_gauge_chart(overall_score)
87
- location_map = visualizer.create_enhanced_map(lat, lon, overall_score, historical['estimated_ndvi'].mean())
88
-
89
- # Generate analysis text
90
- analysis_text = f"""
91
- 📍 Location Analysis:
92
- Location: {location_data['address']}
93
- Coordinates: {lat:.4f}°N, {lon:.4f}°E
94
- Region: {location_data['region'] if location_data['region'] else 'Unknown'}
95
-
96
- 🌡️ Historical Weather Analysis (Past 90 Days):
97
- Temperature: {historical['temperature'].mean():.1f}°C (±{historical['temperature'].std():.1f}°C)
98
- Daily Range: {historical['temp_range'].mean():.1f}°C
99
- Humidity: {historical['humidity'].mean():.1f}% (±{historical['humidity'].std():.1f}%)
100
- Rainfall: {historical['rainfall'].mean():.1f}mm/day (±{historical['rainfall'].std():.1f}mm)
101
-
102
- 🌿 Vegetation Analysis:
103
- Current NDVI: {historical['estimated_ndvi'].mean():.2f}
104
- Minimum NDVI: {historical['estimated_ndvi'].min():.2f}
105
- Maximum NDVI: {historical['estimated_ndvi'].max():.2f}
106
- Vegetation Status: {get_vegetation_status(historical['estimated_ndvi'].mean())}
107
-
108
- 🔮 Forecast Analysis (Next 90 Days):
109
- Temperature: {forecast['temperature'].mean():.1f}°C (±{forecast['temperature'].std():.1f}°C)
110
- Humidity: {forecast['humidity'].mean():.1f}% (±{forecast['humidity'].std():.1f}%)
111
- Rainfall: {forecast['rainfall'].mean():.1f}mm/day (±{forecast['rainfall'].std():.1f}mm)
112
- Expected NDVI: {forecast['estimated_ndvi'].mean():.2f}
113
-
114
- 📊 Growing Condition Scores:
115
- Temperature Score: {temp_score:.2f}
116
- Humidity Score: {humidity_score:.2f}
117
- Rainfall Score: {rainfall_score:.2f}
118
- Vegetation Score: {ndvi_score:.2f}
119
- Overall Score: {overall_score:.2f}
120
-
121
- 🎯 Recommendations:
122
- {get_recommendations(overall_score, ndvi_score)}
123
-
124
- ⚠️ Risk Factors:
125
- {get_risk_factors(df, trends)}
126
-
127
- 📝 Additional Notes:
128
- • Growing Season: {is_growing_season(historical['season'].iloc[-1])}
129
- • Weather Stability: {get_weather_stability(historical)}
130
- • Long-term Outlook: {get_long_term_outlook(trends)}
131
- """
132
-
133
- return location_map, analysis_text, time_series_plot, gauge_plot
134
-
135
- except Exception as e:
136
- error_message = f"An error occurred: {str(e)}"
137
- print(f"Error details: {e}")
138
- return None, None, error_message, None
139
-
140
- def analyze_satellite_image(image):
141
- """Analyze satellite image using SAM2"""
142
  try:
143
- analyzer = SAMAnalyzer()
144
- veg_index, health_analysis, viz_plot = analyzer.process_image(image)
145
-
146
- if veg_index is None:
147
- return None, "Error processing image. Please try again."
148
-
149
- analysis_text = analyzer.format_analysis_text(health_analysis)
150
-
151
- return viz_plot, analysis_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  except Exception as e:
153
- return None, f"Error analyzing image: {str(e)}"
154
 
155
- def get_vegetation_status(ndvi):
156
- """Get detailed vegetation status based on NDVI value"""
157
- if ndvi < 0:
158
- return "Very Low - Bare soil or water bodies"
159
- elif ndvi < 0.1:
160
- return "Low - Very sparse vegetation"
161
- elif ndvi < 0.2:
162
- return "Sparse - Stressed vegetation"
163
- elif ndvi < 0.3:
164
- return "Moderate - Typical agricultural land"
165
- elif ndvi < 0.4:
166
- return "Good - Healthy vegetation"
167
- elif ndvi < 0.5:
168
- return "High - Very healthy vegetation"
169
- elif ndvi < 0.6:
170
- return "Very High - Dense vegetation"
171
- else:
172
- return "Dense - Very dense, healthy vegetation"
173
-
174
- def get_recommendations(score, ndvi):
175
- """Get detailed recommendations based on scores"""
176
- if score >= 0.8 and ndvi >= 0.6:
177
- return """
178
- ✅ Excellent conditions for tobacco growing
179
- • Proceed with standard planting schedule
180
- • Regular monitoring recommended
181
- • Consider expansion opportunities
182
- """
183
- elif score >= 0.6:
184
- return """
185
- 👍 Good conditions with some considerations
186
- • Implement basic risk mitigation measures
187
- • Regular monitoring essential
188
- • Consider crop insurance
189
- """
190
- elif score >= 0.4:
191
- return """
192
- ⚠️ Marginal conditions - proceed with caution
193
- • Enhanced monitoring required
194
- • Strong risk mitigation needed
195
- • Crop insurance strongly recommended
196
- • Consider alternative timing
197
- """
198
- else:
199
- return """
200
- ❌ Poor conditions - high risk
201
- • Not recommended for planting
202
- • Consider alternative locations
203
- • Extensive risk mitigation needed
204
- • Alternative crops suggested
205
- """
206
-
207
- def get_risk_factors(df, trends):
208
- """Analyze and return risk factors"""
209
- risks = []
210
 
211
- if df['temp_range'].mean() > 15:
212
- risks.append(" High daily temperature variations")
213
- if trends['historical']['temperature']['trend'] < 0:
214
- risks.append("• Declining temperature trend")
215
- if df['rainfall'].std() > df['rainfall'].mean():
216
- risks.append("• Inconsistent rainfall patterns")
217
- if trends['historical']['rainfall']['trend'] < 0:
218
- risks.append("• Decreasing rainfall trend")
219
- if trends['historical']['ndvi']['trend'] < 0:
220
- risks.append("• Declining vegetation health")
221
 
222
- return "\n".join(risks) if risks else "No major risk factors identified"
223
-
224
- def is_growing_season(season):
225
- """Check if current season is suitable for growing"""
226
- season_suitability = {
227
- 'Main': "Prime growing season - Optimal conditions",
228
- 'Early': "Early growing season - Good potential",
229
- 'Late': "Late growing season - Monitor closely",
230
- 'Dry': "Dry season - Higher risk period"
231
- }
232
- return season_suitability.get(season, "Season not identified")
233
-
234
- def get_weather_stability(df):
235
- """Assess weather stability"""
236
- temp_std = df['temperature'].std()
237
- if temp_std < 2:
238
- return "Very stable weather patterns"
239
- elif temp_std < 4:
240
- return "Moderately stable weather"
241
- return "Unstable weather patterns - higher risk"
242
-
243
- def get_long_term_outlook(trends):
244
- """Assess long-term outlook based on trends"""
245
- temp_trend = trends['historical']['temperature']['trend']
246
- rain_trend = trends['historical']['rainfall']['trend']
247
 
248
- if temp_trend > 0 and rain_trend > 0:
249
- return "Improving conditions"
250
- elif temp_trend < 0 and rain_trend < 0:
251
- return "Deteriorating conditions"
252
- return "Mixed conditions - monitor closely"
253
-
254
- # Create Gradio interface
255
- with gr.Blocks(theme=gr.themes.Base()) as demo:
256
- gr.Markdown(
257
- """
258
- # 🌱 Agricultural Credit Risk Assessment System
259
- ## Weather, Vegetation, and Credit Scoring Analysis for Tobacco Farming
260
- """
261
  )
262
 
263
- with gr.Tab("📊 Location Analysis"):
264
- # Input Section
265
- with gr.Row():
266
- location_input = gr.Textbox(
267
- label="Enter Location",
268
- placeholder="e.g., Tabora, Tanzania",
269
- scale=4
270
- )
271
- analyze_button = gr.Button("Analyze", variant="primary", scale=1)
272
-
273
- # Map and Analysis Section
274
- with gr.Row():
275
- with gr.Column(scale=2):
276
- location_map = gr.HTML(label="NDVI Analysis Map")
277
- with gr.Column(scale=1):
278
- analysis_text = gr.Textbox(
279
- label="Analysis Results",
280
- lines=25,
281
- show_label=False
282
- )
283
-
284
- # Plots Section
285
- with gr.Row():
286
- weather_plot = gr.Plot(label="Weather Analysis")
287
-
288
- with gr.Row():
289
- score_gauge = gr.Plot(label="Growing Conditions Score")
290
-
291
- # Location Examples
292
- gr.Examples(
293
- examples=[
294
- ["Tabora, Tanzania"],
295
- ["Urambo, Tabora, Tanzania"],
296
- ["Sikonge, Tabora, Tanzania"],
297
- ["Nzega, Tabora, Tanzania"]
298
- ],
299
- inputs=location_input,
300
- outputs=[location_map, analysis_text, weather_plot, score_gauge],
301
- fn=analyze_location,
302
- cache_examples=True
303
- )
304
-
305
- # Handle location analysis
306
- analyze_button.click(
307
- fn=analyze_location,
308
- inputs=[location_input],
309
- outputs=[location_map, analysis_text, weather_plot, score_gauge]
310
- )
311
-
312
- with gr.Tab("🛰️ Satellite Image Analysis"):
313
- gr.Markdown("""
314
- ## Satellite Image Analysis with SAM2
315
- Upload a satellite or aerial image to analyze vegetation health using advanced segmentation.
316
- """)
317
-
318
- with gr.Row():
319
- image_input = gr.Image(
320
- label="Upload Satellite/Aerial Image"
321
- )
322
-
323
- with gr.Row():
324
- analyze_image_button = gr.Button("🔍 Analyze Image", variant="primary")
325
-
326
- with gr.Row():
327
- with gr.Column():
328
- image_plot = gr.Plot(label="Vegetation Analysis Results")
329
- with gr.Column():
330
- image_analysis = gr.Textbox(
331
- label="Analysis Results",
332
- lines=10,
333
- show_label=False
334
- )
335
 
336
- # Launch the app
337
  if __name__ == "__main__":
338
  demo.launch()
 
1
  import os
2
+ import requests
3
  import gradio as gr
4
+ from huggingface_hub import HfApi, login, create_repo
5
+ import tempfile
 
 
 
6
 
7
+ def download_and_push_model(progress=gr.Progress()):
8
+ """
9
+ Download SAM model and push it to Hugging Face Space
10
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  try:
12
+ # Login to Hugging Face
13
+ token = os.environ.get('HF_TOKEN')
14
+ if not token:
15
+ return "❌ Error: HF_TOKEN not found in environment variables. Please add it to Space secrets."
16
+
17
+ login(token) # Authenticate with Hugging Face
18
+
19
+ # Initialize Hugging Face API
20
+ api = HfApi()
21
+ space_id = "lyimo/downloadmodel"
22
+ model_url = "https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth"
23
+
24
+ progress(0.05, desc="Ensuring repository exists...")
25
+ try:
26
+ # Try to create the repo (will fail if it already exists, which is fine)
27
+ create_repo(
28
+ repo_id=space_id,
29
+ repo_type="space",
30
+ token=token,
31
+ exist_ok=True
32
+ )
33
+ except Exception as e:
34
+ progress(0.1, desc="Repository already exists, continuing...")
35
+ pass
36
+
37
+ # Create a temporary directory for downloading
38
+ with tempfile.TemporaryDirectory() as temp_dir:
39
+ progress(0.1, desc="Started download process...")
40
+
41
+ # Download file
42
+ local_path = os.path.join(temp_dir, "sam_vit_h_4b8939.pth")
43
+ response = requests.get(model_url, stream=True)
44
+ total_size = int(response.headers.get('content-length', 0))
45
+
46
+ progress(0.2, desc="Downloading model...")
47
+ downloaded_size = 0
48
+
49
+ with open(local_path, 'wb') as file:
50
+ for chunk in response.iter_content(chunk_size=1024*1024):
51
+ if chunk:
52
+ file.write(chunk)
53
+ downloaded_size += len(chunk)
54
+ progress(0.2 + 0.6 * (downloaded_size/total_size),
55
+ desc=f"Downloading... {downloaded_size/(1024*1024):.1f}MB / {total_size/(1024*1024):.1f}MB")
56
+
57
+ progress(0.8, desc="Uploading to Hugging Face Space...")
58
+
59
+ # Upload to Hugging Face using commit operation
60
+ api.upload_file(
61
+ path_or_fileobj=local_path,
62
+ path_in_repo="sam_vit_h_4b8939.pth",
63
+ repo_id=space_id,
64
+ repo_type="space",
65
+ token=token,
66
+ commit_message="Upload SAM model weights"
67
+ )
68
+
69
+ progress(1.0, desc="Complete!")
70
+ return "✅ Model successfully downloaded and pushed to your Space!"
71
+
72
  except Exception as e:
73
+ return f"Error: {str(e)}\nToken status: {'Token exists' if token else 'No token found'}"
74
 
75
+ # Create Gradio interface
76
+ with gr.Blocks() as demo:
77
+ gr.Markdown("# Download SAM Model to Space")
78
+ gr.Markdown("This will download the Segment Anything Model (SAM) weights (~2.4GB) and push to this Space")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ with gr.Row():
81
+ download_button = gr.Button("📥 Download & Push Model", variant="primary")
82
+ status_text = gr.Textbox(label="Status", interactive=False)
 
 
 
 
 
 
 
83
 
84
+ gr.Markdown("""
85
+ ### Important Setup Steps:
86
+ 1. Get your Hugging Face token from https://huggingface.co/settings/tokens
87
+ 2. Add the token to Space secrets:
88
+ - Go to Space Settings > Secrets
89
+ - Add new secret named `HF_TOKEN`
90
+ - Paste your token as the value
91
+ 3. Restart the Space after adding the token
92
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
+ download_button.click(
95
+ fn=download_and_push_model,
96
+ outputs=status_text,
97
+ show_progress=True,
 
 
 
 
 
 
 
 
 
98
  )
99
 
100
+ gr.Markdown("""
101
+ ### Notes:
102
+ - Download size is approximately 2.4GB
103
+ - The model will be pushed to the Space repository
104
+ - Please wait for both download and upload to complete
105
+ - You can check the files tab after completion
106
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
 
108
  if __name__ == "__main__":
109
  demo.launch()