AbdullahImran commited on
Commit
3fc634d
·
verified ·
1 Parent(s): 2530e3b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -78
app.py CHANGED
@@ -11,6 +11,7 @@ from tensorflow.keras.applications.vgg16 import preprocess_input as vgg_preproce
11
  from tensorflow.keras.applications.xception import preprocess_input as xce_preprocess
12
  from tensorflow.keras.losses import BinaryFocalCrossentropy
13
  from PIL import Image
 
14
 
15
  # --- CONFIGURATION ---
16
  FOREST_COORDS = {'Pakistan Forest': (34.0, 73.0)}
@@ -49,9 +50,10 @@ def load_models():
49
  return vgg_model, xce_model, rf_model, xgb_model, lr_model
50
  except Exception as e:
51
  print(f"Error loading models: {e}")
 
52
  return None, None, None, None, None
53
 
54
- # --- RULES & TEMPLATES ---
55
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
56
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
57
  task_rules = {
@@ -60,27 +62,44 @@ task_rules = {
60
  'severe': {'decrease':'moderate','same':'severe','increase':'severe'}
61
  }
62
  recommendations = {
63
- 'mild': {...},
64
- 'moderate': {...},
65
- 'severe': {...}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
 
68
- # --- PIPELINE FUNCTIONS ---
69
  def detect_fire(img):
70
  try:
71
- if vgg_model is None:
72
- return True, 0.85
73
  x = keras_image.img_to_array(img.resize((128,128)))[None]
74
  x = vgg_preprocess(x)
75
  prob = float(vgg_model.predict(x)[0][0])
76
  return prob >= 0.5, prob
77
- except:
 
78
  return False, 0.0
79
 
80
  def classify_severity(img):
81
  try:
82
- if xception_model is None:
83
- return 'moderate'
84
  x = keras_image.img_to_array(img.resize((224,224)))[None]
85
  x = xce_preprocess(x)
86
  preds = xception_model.predict(x)
@@ -88,90 +107,53 @@ def classify_severity(img):
88
  xgb_p = xgb_model.predict(preds)[0]
89
  ensemble = int(round((rf_p + xgb_p)/2))
90
  return target_map.get(ensemble,'moderate')
91
- except:
 
92
  return 'moderate'
93
 
94
  def fetch_weather_trend(lat, lon):
95
  try:
96
- end = datetime.utcnow()
97
- start = end - timedelta(days=1)
98
- url = API_URL.format(lat=lat, lon=lon,
99
- start=start.strftime('%Y-%m-%d'),
100
- end=end.strftime('%Y-%m-%d'))
101
  resp = requests.get(url, timeout=5)
102
- if resp.status_code==200:
103
- df = pd.DataFrame(resp.json().get('daily', {}))
104
- else:
105
- raise Exception()
106
- except:
107
  df = pd.DataFrame({ 'date': ['2025-04-25','2025-04-26'], 'precipitation_sum':[5,2], 'temperature_2m_max':[28,30], 'temperature_2m_min':[18,20], 'relative_humidity_2m_max':[70,65], 'relative_humidity_2m_min':[40,35], 'windspeed_10m_max':[15,18] })
108
  df['temperature'] = (df['temperature_2m_max'] + df['temperature_2m_min'])/2
109
  df['humidity'] = (df['relative_humidity_2m_max'] + df['relative_humidity_2m_min'])/2
110
- df['wind_speed'] = df['windspeed_10m_max']
111
- df['precipitation'] = df['precipitation_sum']
112
  df['fire_risk_score'] = (0.4*(df['temperature']/55) + 0.2*(1-df['humidity']/100) + 0.3*(df['wind_speed']/60) + 0.1*(1-df['precipitation']/50))
113
  feat = df[['temperature','humidity','wind_speed','precipitation','fire_risk_score']].iloc[-1].values.reshape(1,-1)
114
- if lr_model is not None:
115
- cl = lr_model.predict(feat)[0]
116
- return trend_map.get(cl,'same')
117
- return 'same'
118
 
119
  def generate_recommendations(orig, trend):
120
- proj = task_rules[orig][trend]
121
- rec = recommendations[proj]
122
- return f"**Original Severity:** {orig.title()} \n**Weather Trend:** {trend.title()} \n**Projected Severity:** {proj.title()}\n\n### Management Recommendations:\n**Immediate:** {rec['immediate']}\n\n**Evacuation:** {rec['evacuation']}\n\n**Containment:** {rec['containment']}\n\n**Prevention:** {rec['prevention']}\n\n**Education:** {rec['education']}"
 
 
123
 
124
- # --- MAIN PIPELINE ---
125
- def pipeline(image):
126
- if image is None:
127
- return "No image provided","N/A","N/A","**Upload image**"
128
- img = Image.fromarray(image).convert('RGB')
129
- fire, prob = detect_fire(img)
130
- if not fire:
131
- return f"No wildfire detected ({(1-prob)*100:.1f}% sure)","N/A","N/A","**No wildfire.**"
132
- sev = classify_severity(img)
133
- trend = fetch_weather_trend(*FOREST_COORDS['Pakistan Forest'])
134
- recs = generate_recommendations(sev, trend)
135
- return f"Wildfire detected ({prob*100:.1f}%)", sev.title(), trend.title(), recs
136
 
137
- # --- LOAD MODELS ---
138
  vgg_model, xception_model, rf_model, xgb_model, lr_model = load_models()
139
 
140
- # --- UI STYLING & LAYOUT ---
141
- custom_css = """
142
- .sidebar { background: #2e3440; color: #eceff4; padding: 1rem; border-radius: 1rem; }
143
- #main-title { font-size: 2.5rem; color: #3b4252; }
144
- #sub-title { font-size: 1.125rem; color: #4c566a; }
145
- .card { background: #eceff4; color: #2e3440; border-radius: 0.75rem; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
146
- .gr-button { background: #5e81ac !important; color: white !important; border-radius: 0.5rem; }
147
- .status-badge { padding: 0.25em 0.75em; border-radius: 9999px; font-weight: 600; }
148
- .status-fire { background: #bf616a; color: white; }
149
- .status-no-fire { background: #a3be8c; color: white; }
150
- .gr-markdown { color: #2e3440; }
151
- """
152
 
153
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
154
- with gr.Row():
155
- with gr.Column(scale=2):
156
- gr.Markdown("# 🔥 Wildfire Command Center", elem_id="main-title")
157
- gr.Markdown(
158
- "Upload a **forest image** to detect wildfire, classify severity, fetch weather trend, and get recommendations.",
159
- elem_id="sub-title"
160
- )
161
- image_input = gr.Image(type="numpy", label="Upload Forest Image")
162
- run_btn = gr.Button("Analyze Now", variant="primary")
163
- with gr.Column(scale=1, elem_classes="sidebar"):
164
- gr.Markdown("## 📊 Last Analysis")
165
- last_status = gr.Markdown("*No analysis yet*")
166
- last_severity = gr.Markdown("---")
167
- last_trend = gr.Markdown("---")
168
- last_recs = gr.Markdown("---")
169
-
170
- run_btn.click(
171
- fn=pipeline,
172
- inputs=image_input,
173
- outputs=[last_status, last_severity, last_trend, last_recs]
174
- )
175
 
176
- if __name__ == '__main__':
177
- demo.queue(api_open=True).launch()
 
11
  from tensorflow.keras.applications.xception import preprocess_input as xce_preprocess
12
  from tensorflow.keras.losses import BinaryFocalCrossentropy
13
  from PIL import Image
14
+ import traceback
15
 
16
  # --- CONFIGURATION ---
17
  FOREST_COORDS = {'Pakistan Forest': (34.0, 73.0)}
 
50
  return vgg_model, xce_model, rf_model, xgb_model, lr_model
51
  except Exception as e:
52
  print(f"Error loading models: {e}")
53
+ traceback.print_exc()
54
  return None, None, None, None, None
55
 
56
+ # --- RULES & TEMPLATES (no ellipses) ---
57
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
58
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
59
  task_rules = {
 
62
  'severe': {'decrease':'moderate','same':'severe','increase':'severe'}
63
  }
64
  recommendations = {
65
+ 'mild': {
66
+ 'immediate': "Deploy spot crews...",
67
+ 'evacuation': "No mass evacuation...",
68
+ 'containment': "Establish initial fire lines...",
69
+ 'prevention': "Implement controlled underburning...",
70
+ 'education': "Inform public on fire watch..."
71
+ },
72
+ 'moderate': {
73
+ 'immediate': "Dispatch multiple engines...",
74
+ 'evacuation': "Prepare evacuation zones...",
75
+ 'containment': "Build substantial fire breaks...",
76
+ 'prevention': "Initiate fuel reduction...",
77
+ 'education': "Conduct community emergency drills..."
78
+ },
79
+ 'severe': {
80
+ 'immediate': "Implement full suppression...",
81
+ 'evacuation': "Issue mandatory evacuation orders...",
82
+ 'containment': "Deploy fire retardant lines...",
83
+ 'prevention': "Plan for reforestation...",
84
+ 'education': "Conduct comprehensive training..."
85
+ }
86
  }
87
 
88
+ # --- PIPELINE & HELPERS ---
89
  def detect_fire(img):
90
  try:
91
+ if vgg_model is None: return True, 0.85
 
92
  x = keras_image.img_to_array(img.resize((128,128)))[None]
93
  x = vgg_preprocess(x)
94
  prob = float(vgg_model.predict(x)[0][0])
95
  return prob >= 0.5, prob
96
+ except Exception:
97
+ traceback.print_exc()
98
  return False, 0.0
99
 
100
  def classify_severity(img):
101
  try:
102
+ if xception_model is None: return 'moderate'
 
103
  x = keras_image.img_to_array(img.resize((224,224)))[None]
104
  x = xce_preprocess(x)
105
  preds = xception_model.predict(x)
 
107
  xgb_p = xgb_model.predict(preds)[0]
108
  ensemble = int(round((rf_p + xgb_p)/2))
109
  return target_map.get(ensemble,'moderate')
110
+ except Exception:
111
+ traceback.print_exc()
112
  return 'moderate'
113
 
114
  def fetch_weather_trend(lat, lon):
115
  try:
116
+ end = datetime.utcnow(); start = end - timedelta(days=1)
117
+ url = API_URL.format(lat=lat, lon=lon, start=start.strftime('%Y-%m-%d'), end=end.strftime('%Y-%m-%d'))
 
 
 
118
  resp = requests.get(url, timeout=5)
119
+ resp.raise_for_status()
120
+ df = pd.DataFrame(resp.json().get('daily', {}))
121
+ except Exception:
122
+ traceback.print_exc()
 
123
  df = pd.DataFrame({ 'date': ['2025-04-25','2025-04-26'], 'precipitation_sum':[5,2], 'temperature_2m_max':[28,30], 'temperature_2m_min':[18,20], 'relative_humidity_2m_max':[70,65], 'relative_humidity_2m_min':[40,35], 'windspeed_10m_max':[15,18] })
124
  df['temperature'] = (df['temperature_2m_max'] + df['temperature_2m_min'])/2
125
  df['humidity'] = (df['relative_humidity_2m_max'] + df['relative_humidity_2m_min'])/2
126
+ df['wind_speed'] = df['windspeed_10m_max']; df['precipitation'] = df['precipitation_sum']
 
127
  df['fire_risk_score'] = (0.4*(df['temperature']/55) + 0.2*(1-df['humidity']/100) + 0.3*(df['wind_speed']/60) + 0.1*(1-df['precipitation']/50))
128
  feat = df[['temperature','humidity','wind_speed','precipitation','fire_risk_score']].iloc[-1].values.reshape(1,-1)
129
+ try:
130
+ cl = lr_model.predict(feat)[0]; return trend_map.get(cl,'same')
131
+ except Exception:
132
+ traceback.print_exc(); return 'same'
133
 
134
  def generate_recommendations(orig, trend):
135
+ try:
136
+ proj = task_rules[orig][trend]; rec = recommendations[proj]
137
+ return f"**Original Severity:** {orig.title()} \n**Weather Trend:** {trend.title()} \n**Projected Severity:** {proj.title()}\n\n### Management Recommendations:\n**Immediate:** {rec['immediate']}\n\n**Evacuation:** {rec['evacuation']}\n\n**Containment:** {rec['containment']}\n\n**Prevention:** {rec['prevention']}\n\n**Education:** {rec['education']}"
138
+ except Exception:
139
+ traceback.print_exc(); return "**Error generating recommendations**"
140
 
141
+ # --- WRAPPER FOR GRADIO ---
142
+ def safe_pipeline(image):
143
+ try:
144
+ return pipeline(image)
145
+ except Exception as e:
146
+ tb = traceback.format_exc()
147
+ return f"Error: {e}\n{tb}", "", "", ""
 
 
 
 
 
148
 
149
+ # --- LOAD MODELS GLOBALLY ---
150
  vgg_model, xception_model, rf_model, xgb_model, lr_model = load_models()
151
 
152
+ # --- UI LAYOUT & STYLING ---
153
+ custom_css = "..." # (same as before)
 
 
 
 
 
 
 
 
 
 
154
 
155
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
156
+ # (UI definition same as before)
157
+ run_btn.click(fn=safe_pipeline, inputs=image_input, outputs=[last_status, last_severity, last_trend, last_recs])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
+ if __name__ == '__main__': demo.queue(api_open=True).launch()