AyoAgbaje's picture
Update app.py
27bfb83 verified
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import image
plt.style.use("fivethirtyeight")
import PIL
from PIL import Image, ImageFile
import os, shutil
from tqdm.auto import tqdm, trange
import gradio as gr
import torch, torchvision
import torch.nn as nn
from torchvision.transforms import v2 as v2
import lightning.pytorch as pl
from lightning.pytorch import LightningModule, LightningDataModule
import tempfile
ImageFile.LOAD_TRUNCATED_IMAGES = True
import utils
from utils.utils import prepare_image, make_preds_return_mask, load_model, get_gt
def run_gradio_app():
def process_image(img_path_):
lightning_model = load_model()
image = prepare_image(path=img_path_)
mask_array = make_preds_return_mask(img=image, model=lightning_model) # return numpy
gt_array = np.array(get_gt(img_path_))
# Visualization
gt_pil = Image.fromarray(gt_array).resize((500,500))
mask_pil = Image.fromarray((mask_array * 255.0).astype(np.uint8)).resize((500,500))
# Flood ratio
flood_pixels = np.sum(mask_array > 0.5)
total_pixels = mask_array.size
flood_ratio = flood_pixels / total_pixels
if flood_ratio > 0.05:
status_text = (
f"Flood detected in approximately {flood_ratio*100:.2f}% of the area.\n\n"
"πŸ“Œ Recommended Actions for Urban Planners:\n"
"- Prioritize evacuation and relief efforts in the most affected zones.\n"
"- Assess drainage and waterway capacity; reinforce weak infrastructure.\n"
"- Deploy flood barriers or temporary defenses where feasible.\n"
"- Coordinate with emergency services for rapid response.\n"
"- Use these flood maps for long-term planning: zoning, flood-resilient housing, "
"and sustainable water management strategies."
)
else:
status_text = (
"⚠️ No significant flooding detected.\n\n"
"πŸ“Œ Recommendations:\n"
"- Continue monitoring the area, as conditions may change with rainfall.\n"
"- Maintain drainage systems to prevent localized flooding.\n"
"- Use this opportunity to strengthen flood preparedness measures "
"and update urban planning models with the latest satellite data."
)
# Save mask to temp file for download
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
mask_pil.save(temp_file.name)
return gt_pil, mask_pil, status_text, temp_file.name
title = "🌊 Flood Detection & Mapping (Sentinel-1 & Sentinel-2)"
description = """
## 🌍 Automated Flood Mapping & Evaluation Platform
This platform leverages **Sentinel-2 satellite imagery** combined with a trained **UNet deep learning model**
to deliver high-resolution flood detection and mapping. The system is designed to support **urban planners,
emergency response teams, and environmental agencies** in making timely, data-driven decisions.
### πŸ“Š What the System Provides
- **Automated Processing** of raw satellite imagery to generate accurate flood masks.
- **Visual Insights** with side-by-side comparisons of **Ground Truth** and **Predicted Flood Masks**.
- **Quantitative Summaries** including the percentage of land area inundated.
- **Downloadable GIS-Ready Outputs** (flood masks) for integration into planning and analysis tools.
- **Scalable Utility** across disaster response, environmental monitoring, climate adaptation,
and risk assessment workflows.
"""
# ### πŸ› οΈ How to Use
# 1. Upload a **Sentinel-2 TIFF image** (preferably cloud-free).
# 2. Let the model process and generate the predicted flood mask.
# 3. Review the **visual outputs and textual summary** to assess flood extent.
# 4. Download the mask for use in **GIS software** or further analysis.
# ⚑ *This tool bridges cutting-edge AI with remote sensing data to empower better decisions
# for disaster management and long-term resilience planning.*
description2 = """
### 🌐 Why This Matters
Flooding remains one of the most destructive natural disasters worldwide. Rapid, reliable detection
is essential for:
- Guiding **evacuation planning** and **emergency relief operations**.
- Supporting **sustainable urban development** through flood-resilient zoning.
- Enhancing **climate resilience strategies** for vulnerable regions.
"""
professional_theme = gr.themes.Base(
primary_hue="blue",
secondary_hue="slate",
).set(
button_primary_background_fill="linear-gradient(90deg, #0F4C75, #3282B8)",
button_primary_background_fill_hover="linear-gradient(90deg, #3282B8, #0F4C75)",
button_primary_text_color="white",
button_primary_shadow="0px 2px 6px rgba(0,0,0,0.15)",
block_title_text_color="#0F3057",
body_background_fill="#F8FAFC", # light gray background
block_background_fill="#FFFFFF", # white for content cards
block_shadow="0px 2px 6px rgba(0,0,0,0.1)",
border_color_primary="#D1D5DB",
)
# ----------------------------
# Gradio App Layout
# ----------------------------
with gr.Blocks(theme=professional_theme) as demo:
# ---- HEADER BAR ----
with gr.Row():
with gr.Column(scale = 1):
gr.Markdown(
f"<h1 style='color:#0F3057; margin-bottom:0'>Flood Detection & Mapping Platform</h1>"
"<p style='font-size:18px; color:#555;'>Powered by Sentinel-2 Imagery & Deep Learning</p>"
)
# ---- DESCRIPTION ----
gr.Markdown(description)
# ---- INPUT & STATUS ----
with gr.Row():
with gr.Column():
input_img = gr.File(file_types=["image"], label="Upload Sentinel Image")
run_btn = gr.Button("Run Flood Detection", variant="primary")
with gr.Column():
status_box = gr.Textbox(label="Detection Summary", interactive=False)
gr.Markdown(description2)
# ---- OUTPUT VISUALS ----
with gr.Row():
gt_out = gr.Image(type="pil", label="Ground Truth", width = 500, height = 500)
pred_out = gr.Image(type="pil", label="Predicted Flood Mask", height = 500, width = 500)
# ---- DOWNLOAD ----
with gr.Row():
download_mask = gr.File(label="Download Predicted Mask")
# ---- BUTTON ACTION ----
run_btn.click(
fn=process_image,
inputs=[input_img],
outputs=[gt_out, pred_out, status_box, download_mask]
)
# gr.Markdown(description2)
demo.launch(share=False)
if __name__ == "__main__":
run_gradio_app()