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"
Powered by Sentinel-2 Imagery & Deep Learning
" ) # ---- 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()