转自AI Studio,原文链接:第十一届 “软件杯”:遥感建筑变化检测Demo - 飞桨AI Studio
第十一届 “中国软件杯”大学生软件设计大赛 A组
作为本次比赛唯一算法考核项目,变化检测,聚焦于建筑的变化检测任务,即给定某地区的双时相遥感图像,要求获得该区域的建筑变化。相关数据由北航LEVIR 团队提供,模型和基线相关技术支持由深度学习技术平台部提供,一站式AI开发平台AI Studio由百度AI技术生态部提供。
任务说明
变化检测部分要求参赛者利用提供的训练数据,实现对多时相图像中的建筑变化检测。具体而言,多时相遥感图像建筑物变化检测任务是给定两张不同时间拍摄的相同位置(地理配准)的遥感图像,要求定位出其中建筑变化的区域。
参考链接:什么是遥感影像变化检测?
数据集介绍
项目原作者:geoyee
项目链接:基于UNet++的遥感建筑变化检测
参考论文:基于Faster R-CNN的高分辨率遥感影像变化检测
安装PaddleSeg
In [1]
!pip install paddleseg==2.2.0
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting paddleseg==2.2.0 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/fa/f8/2a02bf24b2048a92e4a268562019333a233ca68bff88c13b2d898cb713db/paddleseg-2.2.0-py3-none-any.whl (186 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 186.1/186.1 KB 5.9 MB/s eta 0:00:00 Requirement already satisfied: flake8 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (4.0.1) Requirement already satisfied: yapf==0.26.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (0.26.0) Requirement already satisfied: tqdm in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (4.36.1) Requirement already satisfied: prettytable in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (0.7.2) Requirement already satisfied: opencv-python in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (4.1.1.26) Requirement already satisfied: visualdl>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (2.2.0) Requirement already satisfied: scipy in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (1.6.3) Requirement already satisfied: filelock in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (3.0.12) Requirement already satisfied: pyyaml>=5.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (5.1.2) Requirement already satisfied: pre-commit in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddleseg==2.2.0) (1.21.0) Requirement already satisfied: Flask-Babel>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (1.0.0) Requirement already satisfied: requests in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (2.27.1) Requirement already satisfied: protobuf>=3.11.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (3.14.0) Requirement already satisfied: matplotlib in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (2.2.3) Requirement already satisfied: six>=1.14.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (1.16.0) Requirement already satisfied: shellcheck-py in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (0.7.1.1) Requirement already satisfied: pandas in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (1.1.5) Requirement already satisfied: numpy in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (1.20.3) Requirement already satisfied: Pillow>=7.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (7.1.2) Requirement already satisfied: flask>=1.1.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (1.1.1) Requirement already satisfied: bce-python-sdk in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->paddleseg==2.2.0) (0.8.53) Requirement already satisfied: pycodestyle<2.9.0,>=2.8.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8->paddleseg==2.2.0) (2.8.0) Requirement already satisfied: mccabe<0.7.0,>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8->paddleseg==2.2.0) (0.6.1) Requirement already satisfied: importlib-metadata<4.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8->paddleseg==2.2.0) (4.2.0) Requirement already satisfied: pyflakes<2.5.0,>=2.4.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8->paddleseg==2.2.0) (2.4.0) Requirement already satisfied: aspy.yaml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->paddleseg==2.2.0) (1.3.0) Requirement already satisfied: nodeenv>=0.11.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->paddleseg==2.2.0) (1.3.4) Requirement already satisfied: cfgv>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->paddleseg==2.2.0) (2.0.1) Requirement already satisfied: toml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->paddleseg==2.2.0) (0.10.0) Requirement already satisfied: virtualenv>=15.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->paddleseg==2.2.0) (16.7.9) Requirement already satisfied: identify>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->paddleseg==2.2.0) (1.4.10) Requirement already satisfied: click>=5.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->paddleseg==2.2.0) (7.0) Requirement already satisfied: Werkzeug>=0.15 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->paddleseg==2.2.0) (0.16.0) Requirement already satisfied: Jinja2>=2.10.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->paddleseg==2.2.0) (3.0.0) Requirement already satisfied: itsdangerous>=0.24 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->paddleseg==2.2.0) (1.1.0) Requirement already satisfied: Babel>=2.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.0.0->paddleseg==2.2.0) (2.9.1) Requirement already satisfied: pytz in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.0.0->paddleseg==2.2.0) (2022.1) Requirement already satisfied: zipp>=0.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata<4.3->flake8->paddleseg==2.2.0) (3.7.0) Requirement already satisfied: typing-extensions>=3.6.4 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata<4.3->flake8->paddleseg==2.2.0) (4.1.1) Requirement already satisfied: pycryptodome>=3.8.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl>=2.0.0->paddleseg==2.2.0) (3.9.9) Requirement already satisfied: future>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl>=2.0.0->paddleseg==2.2.0) (0.18.0) Requirement already satisfied: python-dateutil>=2.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->paddleseg==2.2.0) (2.8.2) Requirement already satisfied: cycler>=0.10 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->paddleseg==2.2.0) (0.10.0) Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->paddleseg==2.2.0) (3.0.7) Requirement already satisfied: kiwisolver>=1.0.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->paddleseg==2.2.0) (1.1.0) Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->paddleseg==2.2.0) (2021.10.8) Requirement already satisfied: charset-normalizer~=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->paddleseg==2.2.0) (2.0.12) Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->paddleseg==2.2.0) (1.26.9) Requirement already satisfied: idna<4,>=2.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->paddleseg==2.2.0) (3.3) Requirement already satisfied: MarkupSafe>=2.0.0rc2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Jinja2>=2.10.1->flask>=1.1.1->visualdl>=2.0.0->paddleseg==2.2.0) (2.0.1) Requirement already satisfied: setuptools in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from kiwisolver>=1.0.1->matplotlib->visualdl>=2.0.0->paddleseg==2.2.0) (56.2.0) Installing collected packages: paddleseg Successfully installed paddleseg-2.2.0
一、数据准备
1.1 解压数据
数据集详情
本比赛提供所实现遥感图像建筑变化检测数据集,一共包含1000个样本,数据主要来源于北航LEVIR 团队的公开论文 。
示例数据
本数据集中的遥感图像大小为1024×1024,像元分辨率为0.5米。标签图与图像等大,像素值为0或255,其中0代表没有建筑变化,255代表存在建筑变化。提供的训练数据集样例如下图所示,每个样本包括前时向图(Image 1),后时相图(Image 2)和标签图(Ground Truth)。
In [2]
# fork后只运行一次
! mkdir -p datasets
! unzip -q /home/aistudio/data/data134796/train_data.zip -d datasets/
! unzip -q /home/aistudio/data/data134796/test_data.zip -d datasets/
1.2 生成数据列表
In [3]
# 划分训练集/验证集,并生成文件名列表,fork后只运行一次
# 训练的时候保证训练集、验证集不变。
import random
import os.path as osp
from glob import glob
# 随机数生成器种子
RNG_SEED = 114514
# 调节此参数控制训练集数据的占比
TRAIN_RATIO = 0.95
# 数据集路径
DATA_DIR = '/home/aistudio/datasets/'
def write_rel_paths(phase, names, out_dir, prefix=''):
"""将文件相对路径存储在txt格式文件中"""
with open(osp.join(out_dir, phase+'.txt'), 'w') as f:
for name in names:
f.write(
' '.join([
osp.join(prefix, 'A', name),
osp.join(prefix, 'B', name),
osp.join(prefix, 'label', name)
])
)
f.write('\n')
random.seed(RNG_SEED)
# 随机划分训练集/验证集
names = list(map(osp.basename, glob(osp.join(DATA_DIR, 'train', 'label', '*.png'))))
# 对文件名进行排序,以确保多次运行结果一致
names.sort()
random.shuffle(names)
len_train = int(len(names)*TRAIN_RATIO) # 向下取整
write_rel_paths('train_list', names[:len_train], DATA_DIR, prefix='datasets/train')
write_rel_paths('val_list', names[len_train:], DATA_DIR, prefix='datasets/train')
write_rel_paths(
'test_list',
map(osp.basename, glob(osp.join(DATA_DIR, 'test', 'A', '*.png'))),
DATA_DIR,
prefix='datasets/test'
)
print("数据集划分已完成。")
数据集划分已完成。
1.3 构建数据集
这里主要是自定义数据Dataset,这里是选择继承paadle.io中的Dataset,而没有使用PaddleSeg中的Dataset,有以下几个问题需要注意
- 在PaddleSeg中label必须转换成0-1二值化图像否则啥也学不到
In [4]
# 构建数据集
import os
import cv2
import numpy as np
import paddle
from paddle.io import Dataset
from paddleseg.transforms import Compose, Resize
import paddleseg.transforms as T
class MyDataset(Dataset):
# 这里的transforms、num_classes和ignore_index需要,避免PaddleSeg在Eval时报错
def __init__(self, dataset_path, mode, transforms=[], num_classes=2, ignore_index=255):
list_path = os.path.join(dataset_path, (mode + '_list.txt'))
self.data_list = self.__get_list(list_path)
self.mode = mode
self.data_num = len(self.data_list)
self.transforms = Compose(transforms, to_rgb=False) # 一定要设置to_rgb为False,否则这里有6个通道会报错
self.is_aug = False if len(transforms) == 0 else True
self.num_classes = num_classes # 分类数
self.ignore_index = ignore_index # 忽视的像素值
def __getitem__(self, index):
A_path, B_path, lab_path = self.data_list[index]
A_img = cv2.cvtColor(cv2.imread(A_path), cv2.COLOR_BGR2RGB)
B_img = cv2.cvtColor(cv2.imread(B_path), cv2.COLOR_BGR2RGB)
image = np.concatenate((A_img, B_img), axis=-1) # 将两个时段的数据concat在通道层
label = cv2.imread(lab_path, cv2.IMREAD_GRAYSCALE)
if self.is_aug:
image, label = self.transforms(im=image, label=label)
image = paddle.to_tensor(image).astype('float32')
else:
image = paddle.to_tensor(image.transpose(2, 0, 1)).astype('float32')
if self.mode != 'test':
label = label.clip(max=1) # 这里把0-255变为0-1,否则啥也学不到,计算出来的Kappa系数还为负数
label = paddle.to_tensor(label[np.newaxis, :]).astype('int64')
return image, label
def __len__(self):
return self.data_num
# 这个用于把list.txt读取并转为list
def __get_list(self, list_path):
data_list = []
with open(list_path, 'r') as f:
data = f.readlines()
for d in data:
data_list.append(d.replace('\n', '').split(' '))
return data_list
dataset_path = 'datasets'
# 完成两个数据的创建
transforms = [Resize([1024, 1024])]
train_data = MyDataset(dataset_path, 'train', transforms)
val_data = MyDataset(dataset_path, 'val', transforms)
二、 模型训练
2.1 搭建模型及训练
- 模型:尝试了UNet++和UNet+++
- 损失函数:BCELoss + LovaszSoftmaxLoss
- 优化器:AdamW
- 学习率变化:CosineAnnealingDecay
UNet++训练更快
UNet+++训练有点慢,然后测试效果的时候显存炸了
In [5]
import paddle
from paddleseg.models import UNetPlusPlus,UNet3Plus
from paddleseg.models.losses import BCELoss,MixedLoss,LovaszSoftmaxLoss
from paddleseg.core import train
# 参数、优化器及损失
batch_size = 2
epochs = 100
log_iters = int(len(train_data)/batch_size /3) #日志打印间隔
iters = int(len(train_data)/batch_size) * epochs #训练次数
save_interval = int(len(train_data)/batch_size) * 5 #保存的间隔次数
base_lr= 2e-4
model = UNetPlusPlus(in_channels=6, num_classes=2, use_deconv=True)
# model = UNet3Plus(in_channels=6, num_classes=2)
lr = paddle.optimizer.lr.CosineAnnealingDecay(base_lr, T_max=(iters // 3), last_epoch=0.5)
optimizer = paddle.optimizer.AdamW(lr, parameters=model.parameters())
mixtureLosses = [BCELoss(),LovaszSoftmaxLoss()]
mixtureCoef = [0.8,0.2]
losses = {}
losses['types'] = [MixedLoss(mixtureLosses,mixtureCoef)]
losses['coef'] = [1]
W0413 22:32:40.105726 162 device_context.cc:404] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 10.1, Runtime API Version: 10.1 W0413 22:32:40.110945 162 device_context.cc:422] device: 0, cuDNN Version: 7.6.
In [ ]
# 训练
train(
model=model,
train_dataset=train_data,
val_dataset=val_data,
optimizer=optimizer,
save_dir='output',
iters=iters,
batch_size=batch_size,
save_interval=save_interval,
log_iters=log_iters,
num_workers=0,
losses=losses,
use_vdl=True)
- UNet++收敛的很快,iters到达18000 mIou 收敛到0.9
2.2 模型测试
In [7]
import paddle
from paddleseg.models import UNetPlusPlus,UNet3Plus
import matplotlib.pyplot as plt
model_path = 'output1/best_model/model.pdparams' # 加载得到的最好参数
model = UNetPlusPlus(in_channels=6, num_classes=2, use_deconv=True)
# model = UNet3Plus(in_channels=6, num_classes=2)
para_state_dict = paddle.load(model_path)
model.set_dict(para_state_dict)
for idx, (img, lab) in enumerate(val_data): # 从test_data来读取数据
if idx == 6:
m_img = img.reshape((1, 6, 1024, 1024))
m_pre = model(m_img)
s_img = img.reshape((6, 1024, 1024)).numpy().transpose(1, 2, 0)
# 拆分6通道为两个3通道的不同时段图像
s_A_img = s_img[:,:,0:3]
s_B_img = s_img[:,:,3:6]
lab_img = lab.reshape((1024, 1024)).numpy()
pre_img = paddle.argmax(m_pre[0], axis=1).reshape((1024, 1024)).numpy()
plt.figure(figsize=(10, 10))
plt.subplot(2,2,1);plt.imshow(s_A_img.astype('int64'));plt.title('Time 1')
plt.subplot(2,2,2);plt.imshow(s_B_img.astype('int64'));plt.title('Time 2')
plt.subplot(2,2,3);plt.imshow(lab_img);plt.title('Label')
plt.subplot(2,2,4);plt.imshow(pre_img);plt.title('Change Detection')
plt.show()
break
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/image.py:425: DeprecationWarning: np.asscalar(a) is deprecated since NumPy v1.16, use a.item() instead a_min = np.asscalar(a_min.astype(scaled_dtype)) /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/image.py:426: DeprecationWarning: np.asscalar(a) is deprecated since NumPy v1.16, use a.item() instead a_max = np.asscalar(a_max.astype(scaled_dtype))
<Figure size 720x720 with 4 Axes>
三、模型推理
3.1 构建测试数据集
In [13]
# 构建数据集
import os
import cv2
import numpy as np
import paddle
from paddle.io import Dataset
from paddleseg.transforms import Compose, Resize
import paddleseg.transforms as T
class MyDataset(Dataset):
# 这里的transforms、num_classes和ignore_index需要,避免PaddleSeg在Eval时报错
def __init__(self, dataset_path, mode, transforms=[], num_classes=2, ignore_index=255):
list_path = os.path.join(dataset_path, (mode + '_list.txt'))
self.data_list = self.__get_list(list_path)
self.mode = mode
self.data_num = len(self.data_list)
self.transforms = Compose(transforms, to_rgb=False) # 一定要设置to_rgb为False,否则这里有6个通道会报错
self.is_aug = False if len(transforms) == 0 else True
self.num_classes = num_classes # 分类数
self.ignore_index = ignore_index # 忽视的像素值
def __getitem__(self, index):
A_path, B_path, lab_path = self.data_list[index]
A_img = cv2.cvtColor(cv2.imread(A_path), cv2.COLOR_BGR2RGB)
B_img = cv2.cvtColor(cv2.imread(B_path), cv2.COLOR_BGR2RGB)
image = np.concatenate((A_img, B_img), axis=-1) # 将两个时段的数据concat在通道层
image = paddle.to_tensor(image.transpose(2, 0, 1)).astype('float32')
return image
def __len__(self):
return self.data_num
# 这个用于把list.txt读取并转为list
def __get_list(self, list_path):
data_list = []
with open(list_path, 'r') as f:
data = f.readlines()
for d in data:
data_list.append(d.replace('\n', '').split(' '))
return data_list
dataset_path = 'datasets'
# 完成测试数据的创建
transforms = [Resize([1024, 1024])]
test_data = MyDataset(dataset_path, 'test', transforms)
3.2 图像变化检测
In [ ]
!mkdir submisson
import paddle
from paddleseg.models import UNetPlusPlus,UNet3Plus
import matplotlib.pyplot as plt
model_path = 'output1/best_model/model.pdparams' # 加载得到的最好参数
model = UNetPlusPlus(in_channels=6, num_classes=2, use_deconv=True)
# model = UNet3Plus(in_channels=6, num_classes=2)
para_state_dict = paddle.load(model_path)
model.set_dict(para_state_dict)
for idx, img in enumerate(test_data): # 从test_data来读取数据
index = test_data.data_list[idx][0].split('/')[3].split('.')[0]
m_img = img.reshape((1, 6, 1024, 1024))
m_pre = model(m_img)
pre_img = paddle.argmax(m_pre[0], axis=1).reshape((1024, 1024)).numpy()
pre_img = ((pre_img-np.min(pre_img))/(np.max(pre_img)-np.min(pre_img))*255).astype('uint8') # 转换成0-255
cv2.imwrite('submisson/' + index + '.png', pre_img)
mkdir: 无法创建目录"submisson": 文件已存在
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:17: RuntimeWarning: invalid value encountered in true_divide
将打包好的submisson.zip
下载即可提交
In [ ]
# 压缩当前路径所有文件,输出zip文件
path='submisson'
import zipfile,os
zipName = 'submisson.zip' #压缩后文件的位置及名称
f = zipfile.ZipFile( zipName, 'w', zipfile.ZIP_DEFLATED )
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
print(filename)
f.write(os.path.join(dirpath,filename))
f.close()
4. 结语
只是使用PaddleSeg跑通第十一届 “中国软件杯”百度遥感赛项:变化检测功能数据。
推荐使用PaddleRS 完成本次任务。
PaddleRS官方Baseline: 【官方】第十一届 “中国软件杯”百度遥感赛项:变化检测功能
再次声明
项目原作者:geoyee
项目链接:基于UNet++的遥感建筑变化检测