CatherineProtas commited on
Commit
f2f15d3
1 Parent(s): f7148b5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +221 -26
app.py CHANGED
@@ -1,37 +1,232 @@
1
  import gradio as gr
 
 
 
2
  from fastai.vision.all import *
3
- from fastai.vision.all import PILImage
 
4
 
5
- # Load the trained model
6
  learn = load_learner('fog_classifier.pkl')
7
-
8
- # Get the labels from the data loaders
9
  labels = learn.dls.vocab
10
 
11
- # Define the prediction function
12
- def predict(img):
 
 
 
13
  img = PILImage.create(img)
14
  img = img.resize((512, 512))
15
  pred, pred_idx, probs = learn.predict(img)
16
  return {labels[i]: float(probs[i]) for i in range(len(labels))}
17
 
18
- # Example images for demonstration
19
- examples = [
20
- "dar3.jpg",
21
- "dar2.jpg",
22
- "untitled45.jpg"
23
- ]
24
-
25
- # Create the Gradio interface
26
- interface = gr.Interface(
27
- fn=predict,
28
- inputs=gr.Image(),
29
- outputs=gr.Label(num_top_classes=3),
30
- examples=examples # Move examples here
31
- )
32
-
33
- # Enable the queue to handle POST requests
34
- interface.queue(api_open=True)
35
-
36
- # Launch the interface
37
- interface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import requests
3
+ import pandas as pd
4
+ from sklearn.linear_model import LogisticRegression
5
  from fastai.vision.all import *
6
+ import os
7
+ from datetime import datetime, timedelta
8
 
9
+ # Load the trained model for image-based fog classification
10
  learn = load_learner('fog_classifier.pkl')
 
 
11
  labels = learn.dls.vocab
12
 
13
+ API_KEY = os.environ.get("OPENWEATHER_API_KEY")
14
+ BASE_URL = 'https://api.openweathermap.org/data/2.5/'
15
+
16
+ def predict_image(img):
17
+ """Predict fog conditions from image and return confidence scores"""
18
  img = PILImage.create(img)
19
  img = img.resize((512, 512))
20
  pred, pred_idx, probs = learn.predict(img)
21
  return {labels[i]: float(probs[i]) for i in range(len(labels))}
22
 
23
+ def calculate_fog_risk_score(weather_data):
24
+ """Calculate a fog risk score (0-1) based on weather conditions"""
25
+ # Normalized weights for each factor
26
+ weights = {
27
+ 'humidity': 0.3,
28
+ 'dew_point_temp_diff': 0.3,
29
+ 'visibility': 0.2,
30
+ 'wind_speed': 0.1,
31
+ 'pressure_change': 0.1
32
+ }
33
+
34
+ # Calculate dew point
35
+ dew_point = weather_data['temperature'] - ((100 - weather_data['humidity']) / 5.0)
36
+ dew_point_temp_diff = abs(weather_data['temperature'] - dew_point)
37
+
38
+ # Normalize each factor to 0-1 scale
39
+ humidity_score = min(weather_data['humidity'] / 100, 1)
40
+ dew_point_score = 1 - min(dew_point_temp_diff / 5, 1) # Closer to dew point = higher score
41
+ visibility_score = 1 - min(weather_data['visibility'] / 10, 1) # Lower visibility = higher score
42
+ wind_score = 1 - min(weather_data['wind_speed'] / 10, 1) # Lower wind = higher score
43
+ pressure_score = min(abs(weather_data['pressure'] - 1013.25) / 50, 1) # Deviation from normal pressure
44
+
45
+ # Calculate weighted score
46
+ fog_risk = (
47
+ weights['humidity'] * humidity_score +
48
+ weights['dew_point_temp_diff'] * dew_point_score +
49
+ weights['visibility'] * visibility_score +
50
+ weights['wind_speed'] * wind_score +
51
+ weights['pressure_change'] * pressure_score
52
+ )
53
+
54
+ return fog_risk
55
+
56
+ def get_weather_data(location):
57
+ """Get current weather data with enhanced error handling"""
58
+ try:
59
+ current_weather_url = f'{BASE_URL}weather?q={location}&appid={API_KEY}&units=metric'
60
+ response = requests.get(current_weather_url)
61
+ response.raise_for_status()
62
+ data = response.json()
63
+
64
+ return {
65
+ 'temperature': data['main'].get('temp', 0),
66
+ 'feels_like': data['main'].get('feels_like', 0),
67
+ 'description': data['weather'][0].get('description', ''),
68
+ 'wind_speed': data['wind'].get('speed', 0),
69
+ 'pressure': data['main'].get('pressure', 0),
70
+ 'humidity': data['main'].get('humidity', 0),
71
+ 'visibility': data.get('visibility', 10000) / 1000,
72
+ 'timestamp': datetime.fromtimestamp(data['dt'])
73
+ }
74
+ except requests.exceptions.RequestException as e:
75
+ raise Exception(f"Failed to fetch weather data: {str(e)}")
76
+
77
+ def get_forecast_data(location):
78
+ """Get 5-day forecast with enhanced error handling"""
79
+ try:
80
+ forecast_url = f'{BASE_URL}forecast?q={location}&appid={API_KEY}&units=metric'
81
+ response = requests.get(forecast_url)
82
+ response.raise_for_status()
83
+ data = response.json()
84
+
85
+ forecasts = []
86
+ for item in data['list']:
87
+ forecasts.append({
88
+ 'temperature': item['main'].get('temp', 0),
89
+ 'humidity': item['main'].get('humidity', 0),
90
+ 'description': item['weather'][0].get('description', ''),
91
+ 'wind_speed': item['wind'].get('speed', 0),
92
+ 'pressure': item['main'].get('pressure', 0),
93
+ 'visibility': item.get('visibility', 10000) / 1000,
94
+ 'timestamp': datetime.fromtimestamp(item['dt'])
95
+ })
96
+ return forecasts
97
+ except requests.exceptions.RequestException as e:
98
+ raise Exception(f"Failed to fetch forecast data: {str(e)}")
99
+
100
+ def format_duration(duration):
101
+ """Format timedelta into days and hours string"""
102
+ total_hours = duration.total_seconds() / 3600
103
+ days = int(total_hours // 24)
104
+ hours = int(total_hours % 24)
105
+
106
+ if days > 0:
107
+ return f"{days} days and {hours} hours"
108
+ return f"{hours} hours"
109
+
110
+ def determine_transmission_power(image_prediction, weather_data, forecast_data=None):
111
+ """
112
+ Determine transmission power based on current conditions and forecast
113
+ Returns: (power_level, duration, explanation)
114
+ """
115
+ # Get fog confidence from image
116
+ image_fog_confidence = max(
117
+ image_prediction.get('Dense_Fog', 0),
118
+ image_prediction.get('Moderate_Fog', 0) * 0.6
119
+ )
120
+
121
+ # Calculate weather-based fog risk
122
+ current_fog_risk = calculate_fog_risk_score(weather_data)
123
+
124
+ # Combine image and weather predictions with weighted average
125
+ # Give slightly more weight to image prediction as it's more reliable
126
+ combined_fog_risk = (image_fog_confidence * 0.6) + (current_fog_risk * 0.4)
127
+
128
+ # Initialize explanation
129
+ explanation = []
130
+
131
+ # Determine base power level from current conditions
132
+ if combined_fog_risk > 0.7:
133
+ power_level = "High"
134
+ explanation.append(f"High fog risk detected (Risk score: {combined_fog_risk:.2f})")
135
+ elif combined_fog_risk > 0.4:
136
+ power_level = "Medium"
137
+ explanation.append(f"Moderate fog risk detected (Risk score: {combined_fog_risk:.2f})")
138
+ else:
139
+ power_level = "Normal"
140
+ explanation.append(f"Low fog risk detected (Risk score: {combined_fog_risk:.2f})")
141
+
142
+ # Analyze forecast data if available
143
+ duration = timedelta(hours=1) # Default duration
144
+ if forecast_data:
145
+ future_risks = []
146
+ for forecast in forecast_data[:40]: # 5 days of 3-hour forecasts
147
+ risk = calculate_fog_risk_score(forecast)
148
+ future_risks.append(risk)
149
+
150
+ # Find periods of high risk
151
+ high_risk_periods = [risk > 0.6 for risk in future_risks]
152
+ if any(high_risk_periods):
153
+ # Find the last high-risk timestamp
154
+ last_high_risk_idx = len(high_risk_periods) - 1 - high_risk_periods[::-1].index(True)
155
+ duration = forecast_data[last_high_risk_idx]['timestamp'] - weather_data['timestamp']
156
+
157
+ explanation.append(f"High fog risk predicted to continue for {format_duration(duration)}")
158
+
159
+ # Adjust power level based on forecast
160
+ if sum(high_risk_periods) / len(high_risk_periods) > 0.5:
161
+ power_level = "High"
162
+ explanation.append("Power level set to High due to sustained fog risk in forecast")
163
+
164
+ return power_level, duration, explanation
165
+
166
+ def integrated_prediction(image, location):
167
+ """Main function to process image and weather data"""
168
+ try:
169
+ # Get image prediction
170
+ image_prediction = predict_image(image)
171
+
172
+ # Get current weather
173
+ current_weather = get_weather_data(location)
174
+
175
+ # Get forecast
176
+ forecast_data = get_forecast_data(location)
177
+
178
+ # Determine transmission power
179
+ power_level, duration, explanation = determine_transmission_power(
180
+ image_prediction,
181
+ current_weather,
182
+ forecast_data
183
+ )
184
+
185
+ # Format result
186
+ result = [
187
+ f"Current Conditions ({current_weather['timestamp'].strftime('%Y-%m-%d %H:%M')})",
188
+ f"Temperature: {current_weather['temperature']:.1f}°C",
189
+ f"Humidity: {current_weather['humidity']}%",
190
+ f"Visibility: {current_weather['visibility']:.1f} km",
191
+ f"Wind Speed: {current_weather['wind_speed']} m/s",
192
+ "",
193
+ "Analysis Results:",
194
+ *explanation,
195
+ "",
196
+ f"Recommended Power Level: {power_level}",
197
+ f"Duration: {format_duration(duration)}",
198
+ "",
199
+ "5-Day Forecast Summary:"
200
+ ]
201
+
202
+ # Add daily forecast summary
203
+ current_date = current_weather['timestamp'].date()
204
+ for day in range(5):
205
+ forecast_date = current_date + timedelta(days=day)
206
+ day_forecasts = [f for f in forecast_data if f['timestamp'].date() == forecast_date]
207
+
208
+ if day_forecasts:
209
+ avg_risk = sum(calculate_fog_risk_score(f) for f in day_forecasts) / len(day_forecasts)
210
+ result.append(f"{forecast_date.strftime('%Y-%m-%d')}: "
211
+ f"Fog Risk: {'High' if avg_risk > 0.6 else 'Moderate' if avg_risk > 0.3 else 'Low'} "
212
+ f"({avg_risk:.2f})")
213
+
214
+ return "\n".join(result)
215
+
216
+ except Exception as e:
217
+ return f"Error: {str(e)}"
218
+
219
+ # Gradio interface
220
+ with gr.Blocks() as demo:
221
+ gr.Markdown("# Enhanced Fog Prediction and Transmission Power System")
222
+
223
+ with gr.Row():
224
+ image_input = gr.Image(label="Upload Current Conditions Image")
225
+ location_input = gr.Textbox(label="Enter Location")
226
+
227
+ predict_button = gr.Button("Analyze and Determine Transmission Power")
228
+ output = gr.Textbox(label="Analysis Results", lines=15)
229
+
230
+ predict_button.click(integrated_prediction, inputs=[image_input, location_input], outputs=output)
231
+
232
+ demo.launch()