
PROJECT
| Anish Dev Edward | AUTHOR | ACTIVE |
| Sohan Aiyappa | COORDINATOR | ACTIVE |

Author: Anish Dev Edward
Affiliation: MARVEL, UVCE
Source Code: https://github.com/tramplingh/Machine-Learning-Projects/tree/main/FloodMapping
Deployment Demo: https://floodmapping-xnqphjv4amhud88gbgfd2n.streamlit.app/
This project presents an AI-powered flood mapping system that uses semantic segmentation on satellite or aerial imagery to identify flooded regions at the pixel level. A U-Net model with a ResNet-34 encoder (pretrained on ImageNet) is trained on paired RGB images and binary masks representing flooded vs. non-flooded pixels.
The model is trained with a combination of Binary Cross Entropy and Dice Loss, and evaluated primarily using Intersection over Union (IoU). In addition to the core model, a Streamlit web application is built to allow users to upload images and visualize predicted flood masks as a heatmap and overlay.
This system demonstrates how deep learning can support disaster response, urban planning, environmental monitoring, and risk assessment by providing fast, automated flood extent mapping.
Floods are among the most frequent and destructive natural disasters worldwide. Rapid assessment of flood extent is critical for:
Evacuation planning
Resource allocation
Damage assessment
Long-term infrastructure and urban planning
Traditional flood mapping often involves manual image interpretation, which is time-consuming and not scalable in real-time scenarios. This project addresses that gap by building a deep learning-based flood mapping model that automatically segments flooded regions from imagery.
Key goals:
Build a robust semantic segmentation model for flood detection
Achieve good performance using IoU on held-out data
Provide a user-friendly demo via a Streamlit app
Given an input satellite or aerial RGB image, the task is to predict a binary mask where:
1 indicates flooded pixels
0 indicates non-flooded pixels
The solution must:
Handle diverse image content and lighting conditions
Be trainable on commodity hardware (Colab GPU)
Generalize to unseen test images
The dataset consists of paired RGB images and corresponding masks:
Images directory: FloodMappingData/Images
Masks directory: FloodMappingData/Masks
Each image xxx.png has a corresponding mask xxx.png in the Masks folder, where:
Flooded pixels are foreground (white / high intensity)
Non-flooded pixels are background (black / low intensity)
Dataset:
https://www.kaggle.com/datasets/saiharshitjami/flood-images-mask-segmentation?select=Images
In the notebook, the dataset is split and copied into a new directory:
/content/data_split/
└── train/
├── images/
└── masks/
└── val/
├── images/
└── masks/
└── test/
├── images/
└── masks/
A list of all .png images is collected.
Only those files that exist in both Images and Masks directories are kept.
The data is shuffled with random.seed(42) for reproducibility.
Split proportions:
80% → Train
10% → Validation
10% → Test
In the custom SegDataset class:
For each filename, the code checks that:
The image can be read with cv2.imread
The mask can be read in grayscale
If either fails, the file is skipped and a warning is printed.
This avoids training on corrupted or unreadable pairs.
All images are resized to a fixed size:
IMG_SIZE = 256
Training transforms (Albumentations):
Resize(256, 256)
HorizontalFlip(p=0.5)
RandomBrightnessContrast(p=0.2)
Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
ToTensorV2() to convert to PyTorch tensors
Validation / Test transforms:
Resize(256, 256)
Normalize(...)
ToTensorV2()
The mask is binarized using a threshold:
mask = (mask > 127).astype("float32")
Merging these, each dataset sample returns:
img – tensor of shape [3, H, W]
mask – tensor of shape [1, H, W]
The model is a U-Net implemented via segmentation-models-pytorch:
model = smp.Unet(
encoder_name="resnet34",
encoder_weights="imagenet",
in_channels=3,
classes=1
)
Key points:
Encoder: ResNet-34 pretrained on ImageNet
Decoder: U-Net style upsampling with skip connections
Input channels: 3 (RGB)
Output: 1-channel logits (for binary segmentation)
The model is moved to:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
A combination of Binary Cross Entropy (BCE) with Logits and Dice Loss is used:
bce = nn.BCEWithLogitsLoss()
dice = smp.losses.DiceLoss(mode='binary')
def loss_fn(pred, y):
return bce(pred, y) + dice(pred, y)
This balances pixel-wise accuracy (BCE) with region overlap (Dice), which is critical for segmentation tasks.
Optimizer: Adam
Learning rate: 1e-4
opt = torch.optim.Adam(model.parameters(), lr=1e-4)
IoU is computed per batch and then averaged:
def iou_pytorch(outputs: torch.Tensor, labels: torch.Tensor, threshold=0.5):
preds = (torch.sigmoid(outputs) > threshold).int()
labels = labels.int()
intersection = (preds & labels).float().sum((1, 2))
union = (preds | labels).float().sum((1, 2))
iou = (intersection + 1e-6) / (union + 1e-6)
return iou.mean()
Number of epochs: 10
For each epoch:
Training phase:
Forward pass
Compute loss
Backpropagation (loss.backward())
Optimizer step
Accumulate training loss
Validation phase:
Disable gradients (torch.no_grad())
Compute validation loss and IoU
Use tqdm progress bars for both train and validation loops.
The model checkpointing uses best validation IoU:
if avg_val_iou > best_val_iou:
best_val_iou = avg_val_iou
torch.save(model.state_dict(), "best_unet.pth")
Training and validation losses and validation IoU are stored and plotted across epochs using Matplotlib.
During training, after each epoch, the following are printed:
Average training loss
Average validation loss
Average validation IoU
Final Training Loss = 0.1942
Final Validation Loss = 0.1899
Best Validation IoU = 0.8628
After training, the best model (best_unet.pth) is loaded and evaluated on the test set:
total_test_iou = 0.0
for x, y in test_dl:
pred = model(x.to(device))
iou = iou_pytorch(pred, y.to(device))
total_test_iou += iou.item()
avg_test_iou = total_test_iou / len(test_dl)
The final metric:
Final Average IoU on the Test Set: 0.8639
To better understand model behavior, several visualizations are produced:
Training vs. Validation Loss Curves
Validation IoU Curve
Prediction Visualizations For a set of sample test images, the notebook displays:
Original RGB image
Predicted flood heatmap (continuous values)
Overlay of the heatmap on the original image
Example inference function:
def show_pred(img_path, thr=0.5, alpha=0.5):
img = cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB)
h, w = img.shape[:2]
aug = val_tfms(image=img)
x = aug["image"].unsqueeze(0).to(device)
with torch.no_grad():
pred = torch.sigmoid(model(x))[0][0].cpu().numpy()
pred_resized = cv2.resize(pred, (w, h))
heatmap = (pred_resized * 255).astype(np.uint8)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
heatmap = cv2.cvtColor(heatmap, cv2.COLOR_BGR2RGB)
overlay = cv2.addWeighted(img, 1 - alpha, heatmap, alpha, 0)
# The function plots Original | Heatmap | Overlay
These qualitative results confirm that the model is able to highlight flooded regions visually in a meaningful way.
To demonstrate the model in an interactive way, a Streamlit app is created (app.py).
WebApp: https://floodmapping-xnqphjv4amhud88gbgfd2n.streamlit.app/
Page title: "🌊 AI-Powered Flood Mapping Tool"
File upload: Accepts .jpg, .jpeg, .png.
Slider to control overlay transparency between the heatmap and original image.
Once an image is uploaded:
Model predicts flood mask
App displays:
Original image
Flood heatmap
Overlay of heatmap on original
Uses @st.cache_resource to cache the loaded model for faster re-runs.
Loads best_unet.pth on CPU:
DEVICE = torch.device("cpu")
def load_model():
model = smp.Unet(encoder_name="resnet34", in_channels=3, classes=1)
model.load_state_dict(torch.load("best_unet.pth", map_location=DEVICE))
model.eval()
return model
Reads uploaded image as bytes
Decodes via OpenCV
Applies the same validation transforms as training (VAL_TFMS)
Runs a forward pass and generates:
Heatmap
Overlay
This makes the research accessible to non-technical stakeholders who can visually inspect flooded areas without needing to run the notebook.
Python – Core language for data processing and model training
PyTorch – Deep learning framework for U-Net model implementation
Segmentation Models PyTorch (smp) – High-level segmentation architectures (U-Net, encoder backbones)
Albumentations – Powerful augmentation library for image transforms
OpenCV – Image loading and manipulation
NumPy – Numeric operations and array handling
Matplotlib – Graphs for loss and IoU curves; visualizations of predictions
tqdm – Progress bars for training and evaluation loops
Streamlit – For the interactive web application
Google Colab – Training environment with GPU support
Google Drive – Storage for images, masks, and model checkpoints
This flood mapping pipeline can be applied in several domains:
Disaster Response & Management
Rapidly identify flooded areas after extreme rainfall or dam breaks
Support rescue planning and resource allocation
Urban Planning & Infrastructure
Analyze flood-prone regions for new construction projects
Inform drainage system design and flood mitigation measures
Environmental Monitoring
Track changes in water extent over time
Study the impact of climate change on flood patterns
Insurance & Risk Assessment
Assess flood risk for properties
Support premium calculation and damage estimation
Agriculture
Detect flooded farmland
Estimate crop damage and plan recovery and compensation
Dataset Size & Diversity
Generalization
Threshold Sensitivity
Real-time Constraints
Planned and potential improvements:
Improve Model Performance
Experiment with different encoder architectures (e.g., ResNet-50, EfficientNet)
Explore other loss functions (Focal Loss, Tversky Loss)
Expand and Enrich Dataset
Add more diverse geographic regions and seasons
Include multi-spectral or radar (SAR) data for better robustness
Post-processing Techniques
Real-time & Scalable Deployment
Package the model as an API or microservice
Integrate with cloud platforms for near real-time inference
Multi-source Fusion
Report too big, cant fit conclusion and references