解决卫星遥感水体图像分割任务:
unet++,transunet实现
包含遥感水体分割数据集
(Satellite_Images_of_Water_Bodies)
用于对陆地上的水体区域进行图像分割。
包含原图(3841张)和对应的分割mask(3841张)
提供深度学习网络或改进网络实现分割。
可为顾客解决遥感图像的水体区域分割任务
卫星遥感水体图像分割数据集介绍
名称
卫星遥感水体图像分割数据集 (Satellite_Images_of_Water_Bodies)
规模
- 图像数量:3841张原图及对应的3841张分割mask。
- 数据量:未明确提供,但通常包含高分辨率图像的数据集可能达到数百MB到几GB。
类别
- 水体区域 (Water Bodies)
- 非水体区域 (Non-Water Areas)
数据特点
- 高质量图像:所有图像均为高分辨率的卫星遥感图像,提供了丰富的细节信息,有助于提高分割精度。
- 多样化样本:涵盖了不同地区、不同季节和不同光照条件下的水体图像,确保模型能够适应多种复杂的场景。
- 详细标注:每张图像都附有详细的像素级分割标注(mask),标明了水体区域的位置。
- 适用性强:数据集适用于多种深度学习框架和模型,便于进行语义分割任务。
应用场景
- 环境监测:帮助环保部门实时监测陆地上的水体变化情况,及时发现和处理环境污染问题。
- 城市规划:支持城市规划部门在进行水资源管理和土地利用规划时考虑水体的位置和分布。
- 灾害管理:在洪水等自然灾害发生时,快速识别受影响的水体区域,协助应急响应和救援工作。
- 农业灌溉:优化农田灌溉系统的设计和管理,提高水资源利用效率。
- 研究与教育:用于科研机构的研究以及相关院校的教学,帮助学生和研究人员更好地了解遥感图像分割技术。
数据集结构
假设数据集的文件结构如下:
satellite_images_of_water_bodies/
├── images/
│ ├── 0001.jpg
│ ├── 0002.jpg
│ └── ...
├── masks/
│ ├── 0001.png
│ ├── 0002.png
│ └── ...
└── metadata.csv
metadata.csv
文件内容示例:
image_id, split
0001.jpg, train
0002.jpg, train
...
masks/0001.png
示例(像素级标注):
- 每个像素值对应一个类别:
- 0: 非水体区域
- 1: 水体区域
使用UNet++ 和 TransUNet 实现水体图像分割
下面是一个完整的Python脚本示例,展示如何加载数据集、使用预训练的UNet++ 和 TransUNet 模型进行水体图像分割,并可视化分割结果。我们将使用PyTorch和相关的分割库。
1. 安装依赖库
首先,确保安装了必要的依赖库。可以在项目目录中的requirements.txt
文件中列出这些依赖库,然后运行以下命令进行安装:
pip install -r requirements.txt
requirements.txt
文件内容示例:
torch==1.10.0
torchvision==0.11.1
opencv-python-headless==4.5.4.60
segmentation-models-pytorch==0.2.1
albumentations==1.1.0
2. 加载数据集和预训练模
import os
import cv2
import torch
import numpy as np
from segmentation_models_pytorch import UnetPlusPlus, TransUnet
from albumentations import Compose, Resize, Normalize
from albumentations.pytorch import ToTensorV2
# 设置设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 加载预训练模型
unetpp_model_path = 'path_to_your_model_directory/unetpp_water_segmentation.pth'
transunet_model_path = 'path_to_your_model_directory/transunet_water_segmentation.pth'
# UNet++
unetpp_model = UnetPlusPlus(encoder_name='resnet34', classes=2, activation=None)
unetpp_model.load_state_dict(torch.load(unetpp_model_path, map_location=device))
unetpp_model.to(device)
unetpp_model.eval()
# TransUNet
transunet_model = TransUnet(encoder_name='resnet34', classes=2, activation=None)
transunet_model.load_state_dict(torch.load(transunet_model_path, map_location=device))
transunet_model.to(device)
transunet_model.eval()
# 图像预处理
def get_preprocessing(preprocessing_fn):
"""构建预处理函数"""
_transform = [
Resize(height=256, width=256, interpolation=cv2.INTER_LINEAR),
Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
ToTensorV2()
]
return Compose(_transform)
preprocessing = get_preprocessing(None)
# 加载图像
def load_image(image_path):
img = cv2.imread(image_path)
if img is None:
print(f"Failed to load image: {image_path}")
return None
return img
# 进行推理
def segment_image(img, model, preprocessing, device):
# 预处理图像
sample = preprocessing(image=img)
img = sample['image'].unsqueeze(0).to(device)
# 推理
with torch.no_grad():
pred = model(img)
pred = torch.softmax(pred, dim=1).argmax(dim=1).squeeze().cpu().numpy()
return pred
# 可视化分割结果
def visualize_segmentation(img, mask, class_colors):
h, w, _ = img.shape
mask = cv2.resize(mask, (w, h), interpolation=cv2.INTER_NEAREST)
colored_mask = np.zeros_like(img)
for i in range(len(class_colors)):
colored_mask[mask == i] = class_colors[i]
overlay = cv2.addWeighted(img, 0.7, colored_mask, 0.3, 0)
return overlay
# 主函数
def main(image_dir, unetpp_model, transunet_model, preprocessing, device):
class_colors = {
0: [0, 0, 0], # 非水体区域
1: [0, 0, 255] # 水体区域
}
for image_name in os.listdir(image_dir):
if image_name.endswith('.jpg'):
image_path = os.path.join(image_dir, image_name)
img = load_image(image_path)
if img is not None:
# 使用UNet++进行分割
unetpp_pred = segment_image(img, unetpp_model, preprocessing, device)
unetpp_result = visualize_segmentation(img, unetpp_pred, class_colors)
# 使用TransUNet进行分割
transunet_pred = segment_image(img, transunet_model, preprocessing, device)
transunet_result = visualize_segmentation(img, transunet_pred, class_colors)
# 显示结果
combined_result = np.hstack((unetpp_result, transunet_result))
cv2.imshow('Water Body Segmentation', combined_result)
cv2.setWindowTitle('Water Body Segmentation', f'Image: {image_name}')
if cv2.waitKey(0) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
# 假设图像存储在'image'目录下
image_dir = 'path_to_your_image_directory'
# 运行主函数
main(image_dir, unetpp_model, transunet_model, preprocessing, device)
说明
- 路径设置:请根据实际的数据集路径调整
path_to_your_image_directory
和path_to_your_model_directory
。 - 文件命名:假设图像文件名分别为
.jpg
。如果实际命名规则不同,请相应修改代码。 - 可视化:通过绘制分割掩码并叠加到原图上,可以直观地看到图像中的水体区域。
进一步的应用
- 训练深度学习模型:可以使用这个数据集来进一步训练或微调UNet++ 和 TransUNet 模型,以提高分割精度。
- 数据增强:为了增加数据集的多样性和鲁棒性,可以使用数据增强技术(如旋转、翻转、缩放等)生成更多的训练样本。
- 评估与优化:通过交叉验证和测试集评估模型性能,并不断优化模型参数,以提高分割准确率。
这个数据集对于卫星遥感水体图像分割具有重要的实用价值,可以帮助相关部门及时发现和处理水体变化问题,提升环境管理和资源利用效率。