Spaces:
Sleeping
Sleeping
File size: 12,059 Bytes
04fa07a 2d71661 d4e30d8 04fa07a 8c9a116 04fa07a 2d71661 04fa07a bb48649 04fa07a b7608ef bb48649 04fa07a bb48649 b7608ef bb48649 b7608ef 04fa07a bb48649 b7608ef 04fa07a bb48649 b7608ef 04fa07a bb48649 04fa07a b7608ef bb48649 6128586 bb48649 04fa07a bb48649 04fa07a bb48649 04fa07a bb48649 04fa07a bb48649 2d71661 bb48649 2d71661 04fa07a 2d71661 04fa07a bb48649 f1ea272 bb48649 2d71661 04fa07a bb48649 de67fba 2d71661 04fa07a bb48649 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
import os
import requests
import pandas as pd
import numpy as np
import joblib
import gradio as gr
from datetime import datetime, timedelta
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image as keras_image
from tensorflow.keras.applications.vgg16 import preprocess_input as vgg_preprocess
from tensorflow.keras.applications.xception import preprocess_input as xce_preprocess
from tensorflow.keras.losses import BinaryFocalCrossentropy
from PIL import Image
# --- CONFIGURATION ---
FOREST_COORDS = {'Pakistan Forest': (34.0, 73.0)}
API_URL = (
"https://archive-api.open-meteo.com/v1/archive"
"?latitude={lat}&longitude={lon}"
"&start_date={start}&end_date={end}"
"&daily=temperature_2m_max,temperature_2m_min,"
"precipitation_sum,windspeed_10m_max,"
"relative_humidity_2m_max,relative_humidity_2m_min"
"&timezone=UTC"
)
# --- LOAD MODELS ---
def load_models():
try:
# Fire detector (VGG16)
vgg_model = load_model(
'vgg16_focal_unfreeze_more.keras',
custom_objects={'BinaryFocalCrossentropy': BinaryFocalCrossentropy}
)
# Severity classifier (Xception)
def focal_loss_fixed(gamma=2., alpha=.25):
import tensorflow.keras.backend as K
def loss_fn(y_true, y_pred):
eps = K.epsilon(); y_pred = K.clip(y_pred, eps, 1.-eps)
ce = -y_true * K.log(y_pred)
w = alpha * K.pow(1-y_pred, gamma)
return K.mean(w * ce, axis=-1)
return loss_fn
xce_model = load_model(
'severity_post_tta.keras',
custom_objects={'focal_loss_fixed': focal_loss_fixed()}
)
# Ensemble and trend models
rf_model = joblib.load('ensemble_rf_model.pkl')
xgb_model = joblib.load('ensemble_xgb_model.pkl')
lr_model = joblib.load('wildfire_logistic_model_synthetic.joblib')
return vgg_model, xce_model, rf_model, xgb_model, lr_model
except Exception as e:
print(f"Error loading models: {e}")
return None, None, None, None, None
# --- RULES & TEMPLATES ---
# Mapping severity levels and trends
target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
# Severity progression rules based on current severity and weather trend
task_rules = {
'mild': {'decrease':'mild','same':'mild','increase':'moderate'},
'moderate':{'decrease':'mild','same':'moderate','increase':'severe'},
'severe': {'decrease':'moderate','same':'severe','increase':'severe'}
}
# Detailed recommendations for each severity level
recommendations = {
'mild': {
'immediate': "Deploy spot crews for initial attack. Establish command post. Monitor fire behavior with drones or aircraft. Alert local fire stations.",
'evacuation': "No mass evacuation needed. Notify nearby communities of potential risk. Prepare evacuation routes if conditions change.",
'containment': "Establish initial fire lines. Use hand crews for direct attack. Position water resources. Clear fuel breaks where feasible.",
'prevention': "Implement controlled underburning in surrounding areas. Manage vegetation density. Create defensible spaces around structures.",
'education': "Inform public on fire watch protocols and reporting mechanisms. Train local volunteers in basic firefighting techniques."
},
'moderate': {
'immediate': "Dispatch multiple engines and aerial support. Establish unified command system. Deploy heavy equipment. Request additional resources.",
'evacuation': "Prepare evacuation zones and staging areas. Advise voluntary evacuation for vulnerable populations. Alert emergency shelters.",
'containment': "Build substantial fire breaks. Conduct water drops from helicopters. Implement indirect attack strategies. Protect critical infrastructure.",
'prevention': "Initiate fuel reduction programs in adjacent areas. Create wider buffer zones. Assess watershed protection needs.",
'education': "Conduct community emergency drills. Launch awareness campaigns on evacuation procedures. Distribute preparedness materials."
},
'severe': {
'immediate': "Implement full suppression with air tankers and multiple resources. Establish incident management team. Request state/federal assistance. Deploy specialized teams.",
'evacuation': "Issue mandatory evacuation orders. Open multiple emergency shelters. Implement traffic control measures. Assist vulnerable populations.",
'containment': "Deploy fire retardant lines from aircraft. Consider backfires and burnout operations. Protect critical infrastructure. Establish multiple control lines.",
'prevention': "Plan for reforestation and erosion control. Harden infrastructure against future fires. Implement watershed protection measures.",
'education': "Conduct comprehensive emergency response training. Implement risk communication strategies. Develop long-term community resilience programs."
}
}
# --- PIPELINE FUNCTIONS ---
def detect_fire(img):
"""Detect if a wildfire is present in the image"""
try:
if vgg_model is None:
return True, 0.85 # Fallback if model not loaded
x = keras_image.img_to_array(img.resize((128,128)))[None]
x = vgg_preprocess(x)
prob = float(vgg_model.predict(x)[0][0])
return prob >= 0.5, prob
except Exception as e:
print(f"Error in fire detection: {e}")
return False, 0.0
def classify_severity(img):
"""Classify the severity of the detected wildfire"""
try:
if xception_model is None or rf_model is None or xgb_model is None:
return 'moderate' # Fallback if models not loaded
x = keras_image.img_to_array(img.resize((224,224)))[None]
x = xce_preprocess(x)
preds = xception_model.predict(x)
rf_p = rf_model.predict(preds)[0]
xgb_p = xgb_model.predict(preds)[0]
ensemble = int(round((rf_p + xgb_p)/2))
return target_map.get(ensemble, 'moderate')
except Exception as e:
print(f"Error in severity classification: {e}")
return 'moderate' # Default to moderate severity if error occurs
def fetch_weather_trend(lat, lon):
"""Fetch weather data and determine trend"""
try:
# Use local weather calculation if API fails
try:
end = datetime.utcnow()
start = end - timedelta(days=1)
url = API_URL.format(
lat=lat, lon=lon,
start=start.strftime('%Y-%m-%d'),
end=end.strftime('%Y-%m-%d')
)
response = requests.get(url, timeout=5)
if response.status_code != 200:
raise Exception(f"API returned status code {response.status_code}")
df = pd.DataFrame(response.json().get('daily', {}))
except Exception as e:
print(f"API error: {e}. Using synthetic data.")
# Create synthetic weather data if API fails
df = pd.DataFrame({
'date': [(datetime.utcnow() - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(1, -1, -1)],
'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]
})
# Process weather data
for c in ['precipitation_sum','temperature_2m_max','temperature_2m_min',
'relative_humidity_2m_max','relative_humidity_2m_min','windspeed_10m_max']:
df[c] = pd.to_numeric(df.get(c,[]), errors='coerce')
df['precipitation'] = df['precipitation_sum'].fillna(0)
df['temperature'] = (df['temperature_2m_max'] + df['temperature_2m_min'])/2
df['humidity'] = (df['relative_humidity_2m_max'] + df['relative_humidity_2m_min'])/2
df['wind_speed'] = df['windspeed_10m_max']
# Calculate fire risk score based on weather parameters
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)
)
# Prepare features for trend prediction
feats = df[['temperature','humidity','wind_speed','precipitation','fire_risk_score']]
feat = feats.fillna(feats.mean()).iloc[-1].values.reshape(1,-1)
# Predict trend using logistic regression model or fallback
if lr_model is not None:
trend_cl = lr_model.predict(feat)[0]
return trend_map.get(trend_cl, 'same')
else:
# Fallback logic if model isn't loaded
if df['fire_risk_score'].iloc[-1] > 0.6:
return 'increase'
elif df['fire_risk_score'].iloc[-1] < 0.4:
return 'decrease'
return 'same'
except Exception as e:
print(f"Error in weather trend analysis: {e}")
return 'same' # Default to 'same' trend if all else fails
def generate_recommendations(original_severity, weather_trend):
"""Generate comprehensive recommendations based on severity and trend"""
# Determine projected severity
projected_severity = task_rules[original_severity][weather_trend]
# Get recommendations for projected severity
rec = recommendations[projected_severity]
# Create detailed recommendation text
recommendation_text = f"""**Original Severity:** {original_severity.title()}
**Weather Trend:** {weather_trend.title()}
**Projected Severity:** {projected_severity.title()}
### Management Recommendations:
**1. Immediate Actions:**
{rec['immediate']}
**2. Evacuation Guidelines:**
{rec['evacuation']}
**3. Short-term Containment:**
{rec['containment']}
**4. Long-term Prevention & Recovery:**
{rec['prevention']}
**5. Community Education:**
{rec['education']}
"""
return recommendation_text
# --- MAIN PIPELINE ---
def pipeline(image):
"""Main processing pipeline for wildfire detection and analysis"""
if image is None:
return "No image provided", "N/A", "N/A", "**Please upload an image to analyze**"
# Convert to PIL Image
img = Image.fromarray(image).convert('RGB')
# Step 1: Detect fire
fire, prob = detect_fire(img)
if not fire:
return f"No wildfire detected (confidence: {(1-prob)*100:.1f}%)", "N/A", "N/A", "**No wildfire detected. Stay alert and maintain regular monitoring.**"
# Step 2: Classify severity
severity = classify_severity(img)
# Step 3: Fetch weather trend
trend = fetch_weather_trend(*FOREST_COORDS['Pakistan Forest'])
# Step 4: Generate recommendations
recommendations_text = generate_recommendations(severity, trend)
return f"Wildfire detected (confidence: {prob*100:.1f}%)", severity.title(), trend.title(), recommendations_text
# --- LOAD MODELS GLOBALLY ---
vgg_model, xception_model, rf_model, xgb_model, lr_model = load_models()
# --- GRADIO INTERFACE ---
interface = gr.Interface(
fn=pipeline,
inputs=gr.Image(type='numpy', label='Upload Wildfire Image'),
outputs=[
gr.Textbox(label='Fire Status'),
gr.Textbox(label='Current Severity Level'),
gr.Textbox(label='Weather Trend'),
gr.Markdown(label='Management Recommendations')
],
title='Wildfire Detection & Management Assistant',
description='Upload an image from a forest region in Pakistan to determine wildfire presence, severity, weather-driven trend, and get expert management recommendations.',
examples=[],
theme=gr.themes.Base(),
allow_flagging='never'
).queue(api_open=True)
if __name__ == '__main__':
interface.launch(share=False) |