AbdullahImran commited on
Commit
efe2c93
·
verified ·
1 Parent(s): 050d179

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -25
app.py CHANGED
@@ -33,9 +33,10 @@ def load_models():
33
  def focal_loss_fixed(gamma=2., alpha=.25):
34
  import tensorflow.keras.backend as K
35
  def loss_fn(y_true, y_pred):
36
- eps = K.epsilon(); y_pred = K.clip(y_pred, eps, 1.-eps)
 
37
  ce = -y_true * K.log(y_pred)
38
- w = alpha * K.pow(1-y_pred, gamma)
39
  return K.mean(w * ce, axis=-1)
40
  return loss_fn
41
  xce_model = load_model(
@@ -49,13 +50,13 @@ def load_models():
49
 
50
  vgg_model, xception_model, rf_model, xgb_model, lr_model = load_models()
51
 
52
- # --- RULES & TEMPLATES (expanded!) ---
53
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
54
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
55
  task_rules = {
56
- 'mild': {'decrease':'mild','same':'mild','increase':'moderate'},
57
- 'moderate':{'decrease':'mild','same':'moderate','increase':'severe'},
58
- 'severe': {'decrease':'moderate','same':'severe','increase':'severe'}
59
  }
60
  templates = {
61
  'mild': (
@@ -81,7 +82,58 @@ templates = {
81
  )
82
  }
83
 
84
- # --- RECOMMENDATION GENERATOR ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  def generate_recommendations(original, trend):
86
  projected = task_rules[original][trend]
87
  header = (
@@ -90,40 +142,35 @@ def generate_recommendations(original, trend):
90
  f"- **Weather Trend:** {trend.title()}\n"
91
  f"- **Projected Severity:** {projected.title()}\n\n"
92
  )
93
- # build bullet paragraphs
94
  paras = templates[projected].split("\n\n")
95
  formatted = "\n\n".join(paras)
96
  return header + formatted
97
 
98
- # --- PIPELINE ---
99
  def pipeline(image):
100
  img = Image.fromarray(image).convert('RGB')
101
  fire, prob = detect_fire(img)
102
  if not fire:
103
  return (
104
- f"**No wildfire detected** (probability={prob:.2f})",
105
- "N/A",
106
- "N/A",
107
  "There is currently no sign of wildfire in the image. Continue normal monitoring."
108
  )
109
  sev = classify_severity(img)
110
  trend = fetch_weather_trend(*FOREST_COORDS['Pakistan Forest'])
111
  recs = generate_recommendations(sev, trend)
112
  return (
113
- f"**🔥 Fire Detected** (probability={prob:.2f})",
114
- sev.title(),
115
- trend.title(),
116
  recs
117
  )
118
 
119
- # --- GRADIO BLOCKS UI ---
120
  with gr.Blocks(css="""
121
- /* background for entire app */
122
  .gradio-container {
123
  background-color: #f5f7fa !important;
124
  }
125
-
126
- /* style each of the three Textbox outputs */
127
  .gradio-textbox textarea {
128
  background-color: #ffffff !important;
129
  border: 1px solid #cbd2d9 !important;
@@ -133,16 +180,12 @@ with gr.Blocks(css="""
133
  color: #333333 !important;
134
  min-height: 3em !important;
135
  }
136
-
137
- /* style the Accordion panel */
138
  .gradio-accordion {
139
  background-color: #ffffff !important;
140
  border: 1px solid #cbd2d9 !important;
141
  border-radius: 8px !important;
142
  padding: 8px !important;
143
  }
144
-
145
- /* style the Analyze button */
146
  .gradio-button {
147
  background-color: #0072ce !important;
148
  color: white !important;
@@ -153,8 +196,6 @@ with gr.Blocks(css="""
153
  .gradio-button:hover {
154
  background-color: #005bb5 !important;
155
  }
156
-
157
- /* section headers */
158
  .gradio-markdown h1, .gradio-markdown h2 {
159
  color: #1f2937 !important;
160
  margin-bottom: 0.5em !important;
 
33
  def focal_loss_fixed(gamma=2., alpha=.25):
34
  import tensorflow.keras.backend as K
35
  def loss_fn(y_true, y_pred):
36
+ eps = K.epsilon()
37
+ y_pred = K.clip(y_pred, eps, 1. - eps)
38
  ce = -y_true * K.log(y_pred)
39
+ w = alpha * K.pow(1 - y_pred, gamma)
40
  return K.mean(w * ce, axis=-1)
41
  return loss_fn
42
  xce_model = load_model(
 
50
 
51
  vgg_model, xception_model, rf_model, xgb_model, lr_model = load_models()
52
 
53
+ # --- RULES & TEMPLATES ---
54
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
55
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
56
  task_rules = {
57
+ 'mild': {'decrease': 'mild', 'same': 'mild', 'increase': 'moderate'},
58
+ 'moderate': {'decrease': 'mild', 'same': 'moderate', 'increase': 'severe'},
59
+ 'severe': {'decrease': 'moderate', 'same': 'severe', 'increase': 'severe'}
60
  }
61
  templates = {
62
  'mild': (
 
82
  )
83
  }
84
 
85
+ # --- FUNCTIONS ---
86
+ def detect_fire(img):
87
+ img_resized = img.resize((224, 224))
88
+ arr = keras_image.img_to_array(img_resized)
89
+ arr = np.expand_dims(arr, axis=0)
90
+ arr = vgg_preprocess(arr)
91
+ pred = vgg_model.predict(arr)[0][0]
92
+ is_fire = pred >= 0.5
93
+ return is_fire, pred
94
+
95
+ def classify_severity(img):
96
+ img_resized = img.resize((224, 224))
97
+ arr = keras_image.img_to_array(img_resized)
98
+ arr = np.expand_dims(arr, axis=0)
99
+ arr = xce_preprocess(arr)
100
+ feat = np.squeeze(arr)
101
+ feat_flat = feat.flatten().reshape(1, -1)
102
+
103
+ rf_pred = rf_model.predict_proba(feat_flat)
104
+ xgb_pred = xgb_model.predict_proba(feat_flat)
105
+ avg_pred = (rf_pred + xgb_pred) / 2
106
+ final_class = np.argmax(avg_pred)
107
+ return target_map[final_class]
108
+
109
+ def fetch_weather_trend(lat, lon):
110
+ today = datetime.utcnow().date()
111
+ start_date = today - timedelta(days=2)
112
+ end_date = today - timedelta(days=1)
113
+
114
+ url = API_URL.format(lat=lat, lon=lon, start=start_date, end=end_date)
115
+ response = requests.get(url)
116
+ if response.status_code != 200:
117
+ return 'same' # fallback if API fails
118
+
119
+ data = response.json()
120
+ temp_max = data['daily']['temperature_2m_max']
121
+ wind_max = data['daily']['windspeed_10m_max']
122
+ humidity_min = data['daily']['relative_humidity_2m_min']
123
+
124
+ # crude trend logic: hotter, windier = worse
125
+ temp_trend = np.sign(temp_max[-1] - temp_max[0])
126
+ wind_trend = np.sign(wind_max[-1] - wind_max[0])
127
+ humidity_trend = -np.sign(humidity_min[-1] - humidity_min[0])
128
+
129
+ overall_trend = temp_trend + wind_trend + humidity_trend
130
+ if overall_trend > 0:
131
+ return 'increase'
132
+ elif overall_trend < 0:
133
+ return 'decrease'
134
+ else:
135
+ return 'same'
136
+
137
  def generate_recommendations(original, trend):
138
  projected = task_rules[original][trend]
139
  header = (
 
142
  f"- **Weather Trend:** {trend.title()}\n"
143
  f"- **Projected Severity:** {projected.title()}\n\n"
144
  )
 
145
  paras = templates[projected].split("\n\n")
146
  formatted = "\n\n".join(paras)
147
  return header + formatted
148
 
 
149
  def pipeline(image):
150
  img = Image.fromarray(image).convert('RGB')
151
  fire, prob = detect_fire(img)
152
  if not fire:
153
  return (
154
+ f"**No wildfire detected** (probability={prob:.2f})",
155
+ "N/A",
156
+ "N/A",
157
  "There is currently no sign of wildfire in the image. Continue normal monitoring."
158
  )
159
  sev = classify_severity(img)
160
  trend = fetch_weather_trend(*FOREST_COORDS['Pakistan Forest'])
161
  recs = generate_recommendations(sev, trend)
162
  return (
163
+ f"**🔥 Fire Detected** (probability={prob:.2f})",
164
+ sev.title(),
165
+ trend.title(),
166
  recs
167
  )
168
 
169
+ # --- GRADIO APP ---
170
  with gr.Blocks(css="""
 
171
  .gradio-container {
172
  background-color: #f5f7fa !important;
173
  }
 
 
174
  .gradio-textbox textarea {
175
  background-color: #ffffff !important;
176
  border: 1px solid #cbd2d9 !important;
 
180
  color: #333333 !important;
181
  min-height: 3em !important;
182
  }
 
 
183
  .gradio-accordion {
184
  background-color: #ffffff !important;
185
  border: 1px solid #cbd2d9 !important;
186
  border-radius: 8px !important;
187
  padding: 8px !important;
188
  }
 
 
189
  .gradio-button {
190
  background-color: #0072ce !important;
191
  color: white !important;
 
196
  .gradio-button:hover {
197
  background-color: #005bb5 !important;
198
  }
 
 
199
  .gradio-markdown h1, .gradio-markdown h2 {
200
  color: #1f2937 !important;
201
  margin-bottom: 0.5em !important;