\u200E
万丈高楼平地起——基于飞桨PaddleGAN与PaddleRS实现建筑物样本扩充工具
发布日期:2022-08-24T12:02:56.000+0000 浏览量:798次


项目背景与意义

我国利用卫星遥感监测数据开展土地卫片执法检查的历史可追溯到本世纪初。自2000年起,国土资源部启动了该方向的试点工作。到2010年为止,已经实现全国2859个城市全覆盖。2019年起,自然资源部增加了建筑物变化图斑的提取,每季度下发到各级执法部门,督促进行整改查处。作为遥感土地监测的主要技术之一,长期以来,建筑物变化检测在生产、生活中扮演至关重要的角色。

传统的遥感建筑物变化检测主要通过手动或半自动的方式进行,人工成本高,效率较低。随着人工智能技术的不断成熟和新模型的不断涌现,以人工智能手段辅助建筑物变化检测已经成为主流应用趋势。然而,基于深度学习的建筑物变化检测模型在很大程度上依赖于经过标注的大型数据集,而由于建筑物变化样本的稀有性和稀疏性,收集包含建筑物变化的大规模双时态图像既费时又费力。

为了解决这一问题,有研究者使用生成对抗网络(Generative Adversarial Network, GAN)对建筑物变化检测数据集进行数据生成相关的技术研究,从数量[1]和多样性[2]上对数据集进行扩展,以支撑下游任务,并取得令人瞩目的效果提升。

本项目基于飞桨生成对抗网络开发套件PaddleGAN提供的Pix2Pix模型实现对建筑物变化检测数据集的扩充,利用飞桨高性能遥感影像处理开发套件PaddleRS提供的RealSR、ESRGAN与LESRCNN模型实现对生成遥感影像的超分辨率重建。


Pix2Pix模型简介

数据处理与代码实现


模型简介

Pix2Pix[3]是CGAN的一个变体,能够实现从标签(labels)到图像的映射。在原文中,作者利用CGAN完成了从标签到街景图像、立面图像和遥感影像的图像重建任务,也实现了图像上色、边缘重建图像以及从黑夜到白天的风格迁移。

图1. Pix2Pix[3]模型在各场景下图像重建效果

Pix2Pix网络由一个生成器G(U-Net结构)与一个判别器D(用于分类的全卷积网络结构),其训练过程可分为两部分:

  • 将Label(一般是图像熵较低的数据)输入生成器G,输出重建后的图像Image-fake。在Image-fake与Image-Gt间计算L1损失并优化,以缩小两幅图像间的逐像素差距。
  • 将Image-fake与Label、Image-Gt与Label分别组成图像对并输入判别器D,判别器D输出Image-fake或Image-Gt为真实图像的概率。使用Image-fake、Image-Gt、Label以及判别器D的输出计算GAN损失并优化,使生成器G生成图像的分布逼近真实影像的分布。GAN损失的公式为:

其中,x是输入的网络的原始图像(Label),z是高斯噪声,G(x,z)是Image-fake,y是要生成的图像(Image-Gt)。

图2. Pix2Pix[3]网络的训练、预测过程

由于采用了L1损失,Pix2Pix网络在图像细节的还原度上相比之前的算法有了极大的提高。然而,Pix2Pix的训练机制对数据集有较高的要求,即数据集中必须有成对的标签和真实影像。


数据处理

明确了模型对数据集的要求,接下来是准备数据。

 基础数据集

本项目的目的是对数据集进行数据扩充(data augmentation,即数据增强),希望训练数据集具有充足的数据体量、丰富的数据多样性、以及足够的空间分辨率。经过综合考虑,选定开源的WHU Building Dataset/Satellite datasetⅡ(East Asia)作为建筑物生成任务的基础数据集。数据集包含三个文件夹:切片(crop)过的数据、建筑物的矢量文件、切片之前的完整正射影像,如下图:

图3. 数据集内容展示

处理思路

[2]类似,本项目提取数据集中的建筑物,以每个建筑物作为一个实例(instance),用作增强数据集的素材。每一次将原始遥感影像中的一个建筑物实例抹除,即将建筑物区域内像素调整为(0,0,0),作为x(输入图像)。接着,将原遥感影像作为y(生成图像),构成一个样本对。重复此过程,直到处理完原始建筑物数据集中的所有影像。需要再次强调的是,本项目采取实例级别的数据增强思路,即由每个独立的建筑物均可生成一个样本对。

图4. 建筑物实例级别擦除,构建训练样本

从代码层面来说,有两种具体的实现思路:

思路一:

  • 使用GDAL库读取矢量数据;

  • 遍历每条矢量数据,根据第i个建筑物Bi坐标提取其周围的遥感影像块(尺寸为512*512),将其采样为栅格图,得到Gt;

  • 将Gt中目标建筑物Bi范围内像素值设置为(0,0,0)。

思路二:
  • 遍历切片后的二值化标注,使用OpenCV查找标注中的白色多边形;
  • 对多边形进行筛选,删除面积过小的区域或位于图像边界处的区域;
  • 以每一个多边形区域Ci作为一个实例,将与二值化标注对应的遥感影像Image作为Gt,Ci范围内像素设置为(0,0,0),得到Label。

代码实现

考虑到计算开销,本项目采用思路二,即基于切片后的栅格数据进行处理。切片后的每个影像块空间尺寸为 512*512像素。数据集中的部分样本展示如下图:

图5. 数据集切片效果展示

实现关键代码如下:
def get_filePath_fileName_fileExt(fileUrl):
    """
    获取文件路径, 文件名, 后缀名
    :param fileUrl:
    :return:
    """

    filepath, tmpfilename = os.path.split(fileUrl)
    shotname, extension = os.path.splitext(tmpfilename)
    return filepath, shotname, extension


def gan_img(img_path, lab_path, save_dir, vis=False):
    lab = cv2.imread(lab_path, -1)
    img = cv2.imread(img_path, -1)
    contours, hierarchy = cv2.findContours(lab, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for i in range(len(contours)):
        # 计算面积,太小的去掉
        area = cv2.contourArea(contours[i])
        if area < 200:
            continue

        # 接边的建筑物去掉,仅保留轮廓完整的建筑物
        if 0 in contours[i]:
            continue

        # 外接矩形框,没有方向角
        x, y, w, h = cv2.boundingRect(contours[i])

        # 可视化,调试用
        if vis == True:
            img_to_draw = img.copy()
            cv2.drawContours(img_to_draw, contours, i, (000), thickness=-1)
            cv2.rectangle(img_to_draw, (x, y), (x + w, y + h), (02550), 2)
            # cv2.rectangle(img_to_draw, (x - 5, y - 5), (x + w + 10, y + h + 10), (0, 255, 0), 2)
            cv2.imshow("img_to_draw", img_to_draw)
            cv2.waitKey(0)

        # 每一个对象绘制一张图
        os.makedirs(save_dir, exist_ok=True)

        img_to_save = img.copy()
        # (0, 0, 0)作为标记,需要生成建筑的部分
        cv2.drawContours(img_to_save, contours, i, (000), thickness=-1)
        # axis=0 按垂直方向,axis=1 按水平方向,左侧为目标图像,右侧为Label
        img_dataset = np.concatenate((img, img_to_save), axis=1)
        f, s, e = get_filePath_fileName_fileExt(img_path)

        os.makedirs(os.path.join(save_dir, "pairs"), exist_ok=True)
        cv2.imwrite(os.path.join(save_dir, "pairs", s + "_" + str(i) + ".jpg"), img_dataset)

        os.makedirs(os.path.join(save_dir, "img"), exist_ok=True)
        os.makedirs(os.path.join(save_dir, "lab"), exist_ok=True)

最终,从每一栋建筑物可以得到一组增强样本对。如下图所示,左侧为Gt,右侧为Image,Image中的黑色图斑是要生成建筑物的区域。可将Gt和Image拼接为facades数据集格式(左边A图右边B图水平拼接成一张宽1024高512的图像,A和B的定义在配置文件中需要明确,输入右图生成左图,因此是B to A)。


   图6. PaddleGAN套件训练Pix2Pix模型样本数据格式



基于PaddleGAN的

Pix2Pix网络训练与推理

首先安利一波:飞桨生成对抗网络开发套件--PaddleGAN为开发者提供经典及前沿的生成对抗网络高性能实现,并支撑开发者快速构建、训练及部署生成对抗网络,以供学术、娱乐及产业应用。

开发套件的一大优势是拿来即用,仅需修改配置文件中少量参数即可实现神经网络的训练。同时,AI Studio可以提供算力支持,每天16GB显存的A100显卡可用16小时,满足绝大多数网络的训练要求。

模型训练

可以根据教程修改配置文件一键启动模型训练,配置文件中重要参数的详细解释可以参考AI Studio项目。运行以下命令行开始训练:
# 开始训练
!python -u PaddleGAN/tools/main.py --config-file work/pix2pix_buildings.yaml

# 中断后重新开始
# !python -u PaddleGAN/tools/main.py --config-file work/pix2pix_buildings.yaml --resume output_d

本项目(链接在文末)在work/pix2pix_buildings.yaml保存了独立的配置文件,对每一个字段进行说明,希望能给大家带来帮助。

模型推理

PaddleGAN中,在tool文件夹下提供了inference.py文件,实现模型的推理,但其中实现pix2pix采用了facades数据集的结构,导致很多新手在使用模型推理时把数据拼接成facades格式后再推理,走了弯路。

其实想实现推理,关键点只有三个:
  • 定义模型;
  • 读取预训练权重;
  • 数据处理(transformer中的方法与参数)。
实现关键代码如下:
from ppgan.models.generators import UnetGenerator
g_net = UnetGenerator(3, 3, 8, 64, 'batch', False) #注释:参数在配置文件中
weight_path = "./work/epoch_200_weight.pdparams"
state_dicts = load(weight_path)['netG']
state_dicts = load(weight_path)['netG'] #注释:权重文件中包含了G与D的参数,这里是关键
g_net.set_state_dict(state_dicts)
g_net.eval()
transform = T.Compose([
    T.Transpose(),
    T.Normalize([127.5, 127.5, 127.5], [127.5, 127.5, 127.5])
]) #注释:参数在配置文件中test部分

推理文件保存于项目./work/predict预测.py路径。运行该文件,实现模型推理:

# p2p推理一下
!cp ./work/predict预测.py PaddleGAN/
!python PaddleGAN/predict预测.py

得到结果如下:

图7. 训练结果展示
结果保存在pair_results文件夹。

项目优化

经过前几步操作,我们已经完成了数据处理以及生成对抗模型的训练与推理。但在实验中,我发现采用上面的步骤得到的效果并不能达到预期。例如,在生成的图像中有绿色的房顶:


图8. 异常结果展示
于是,我对项目重新进行了思考,认为效果不佳的原因有两方面:
  • 生成图像大部分与原图相同,L1损失中包含大量冗余部分;

  • 网络真正需要生成的区域较小,损失难以聚焦在这部分,而这个目标小区域才是我们真正需要的。
基于以上分析,我们采取措施进行调优,对数据进行裁剪,缩小尺寸为256*256,从而让生成建筑物的区域作为图像的主要区域,效果如下:

图9. 优化后的训练数据集

数据生成区域在全图中的面积占比从百分之一左右提升到了十分之一,使用优化后的数据集进行训练,得到效果如下:




图10. 优化后的生成结果

平房的颜色基本正常,是红砖的颜色;结构正常,屋脊清晰可见。综上,经过数据裁剪处理后,算法的生成效果具有明显的提升。


超分辨率增强

pix2pixHD模型是pix2pix的升级版,采用两个生成器G1与G2。简单理解,由G1生成低分辨率图像输入G2,从而得到一个更好的结果。本项目借鉴这个思路,使用飞桨高性能遥感影像处理开发套件PaddleRS提供的预训练的RealSR模型对生成的建筑物遥感影像进行超分辨率重建,以期望能提升影像的清晰度。

第二波安利: PaddleRS是遥感科研院所、相关高校共同基于飞桨开发的遥感处理平台,支持遥感图像分类、目标检测、图像分割以及变化检测等常用遥感任务,能够帮助开发者更便捷地完成从训练到部署全流程遥感深度学习应用。

图11. PaddleRS架构图

模型介绍


图12. DRN[4]模型架构
DRN [4] 模型结构基于U-net结构,在每种特征尺度上各增加了一个输出对应不同分辨率的影像。

图13. DRN[4]模型双重回归训练架构

方法的主要创新是针对超分辨率重建任务的解空间过大和难以获得高清影像对这两个问题,提出了对偶回归策略。模型除了学习低分辨率(Low-Resolution,LR)到高分辨率(High-Resolution,HR)图像的映射外,还学习了额外的对偶回归映射,用于从超分辨率图像估计下采样内核并重建LR图像,从而形成一个能够提供额外监督的闭环。

推理实现

使用work/Super_Resolution_pre.py文件,运行超分辨率方法,将分辨率提升至2w*2h。代码如下:

# 进行图像超分处理
import os
import glob
import paddle
import numpy as np
from PIL import Image
from paddlers.models.ppgan.apps.drn_predictor import DRNPredictor
from paddlers.models.ppgan.apps.lesrcnn_predictor import LESRCNNPredictor
from paddlers.models.ppgan.apps.realsr_predictor import RealSRPredictor
# 输出预测结果的文件夹
output = r'./Super_Resolution_out'
# 待输入的低分辨率影像位置
input_dir = r"./gan_low_solution_sample"
# 设置GPU为推理设备
paddle.device.set_device("gpu:0")
# 实例化
DRNpredictor = DRNPredictor(output)
LESRpredictor = LESRCNNPredictor(output)
RealSRpredictor = RealSRPredictor(output)
# 生成文件列表
list_images = glob.glob(input_dir + "/*.**g")
#遍历文件列表,模型推理
for filename in list_images:
    DRNpredictor.run(filename) # 预测
    LESRpredictor.run(filename) 
    RealSRpredictor.run(filename) 

效果展示:


图14. 超分辨率效果展示

细节方面差挺多的,一看就知道生成的。但如果用于样本扩充是没问题的,毕竟总比直接贴图多样性好一些,可以看做一种神秘的复杂滤波。
像素即是正义!!!

本项目也到此结束,当然训练还要继续!


总结与展望

生成样本的真实性有待提高,需研究更快速、更清晰的数据扩展方法。后续需要验证数据增强能否为下游任务带来明显增益。

参考文献

1.张轶, et al., 一种面向地物变化检测的空间约束条件下生成对抗网络遥感影像样本扩充方法. 2020.

2.Chen, H., W. Li, and Z. Shi, Adversarial Instance Augmentation for Building Change Detection in Remote Sensing Images. IEEE Transactions on Geoscience and Remote Sensing, 2021. PP(99): p. 1-16.

3.Isola, P., et al., Image-to-Image Translation with Conditional Adversarial Networks. IEEE, 2016.

4.Guo, Y., et al., Closed-loop Matters: Dual Regression Networks for Single Image Super-Resolution. IEEE, 2020.

相关地址

  • 本项目地址:

https://aistudio.baidu.com/aistudio/projectdetail/3716885?contributionType=1&shared=1

  • WHU Building Dataset/Satellite dataset Ⅱ (East Asia)数据集下载链接:

https://aistudio.baidu.com/aistudio/datasetdetail/56356

  • 飞桨生成对抗网络开发套件PaddleGAN github地址:
https://github.com/PaddlePaddle/PaddleGAN
  • 飞桨高性能遥感影像处理开发套件PaddleRS github地址:
https://github.com/PaddlePaddle/PaddleRS


关注【飞桨PaddlePaddle】公众号

获取更多技术内容~