如何将nDSM等高程数据用于语义分割

前言

当前基于深度学习的高分遥感影像分类方法存在以下问题:1.高分影像数据波段有限,光谱信息不丰富,在一定程度上限制了模型特征学习的丰富度,造成影像分类精度低;2.存在地物内部错分现象和地物边界残缺等问题。
针对以上问题,本博文将介绍一种结合高程数据的语义分割方法。归一化数字表明模型(normalized digital surface model,nDSM)数据记录了所有高于地面的地物相对于地面的高度信息,能够反映地物的真实高度。该信息在影像分类中对于区分不同类型地物(如建筑与地面、树木与低矮植被等)具有重要作用。

结合nDSM的dataloader(pytorch)

本节的主要思想是首先用DSM和DTM相减得出nDSM,以numpy形式保存, 然后将其作为第四波段叠加到影像数据上,继而进行数据增强等一系列操作。将相关数据可视化,效果如下:
image
mask
nDSM

class RSDataset(torch.utils.data.Dataset):
    """Dataset to concate multiple input images stored in slippy map format.
    """

    def __init__(self, inputs, inputs_ndsm, target, debug = False,test = False):
        super().__init__()

        self.test = test
        if debug == False:
            self.inputs =  Path(inputs).files()
            self.inputs_ndsm = Path(inputs_ndsm).files()
            if self.test == False:
                self.target = Path(target).files()
        else:
            self.inputs =  Path(inputs).files()[:1000]
            self.inputs_ndsm = Path(inputs_ndsm).files()[:1000]
            if self.test == False:
                self.target =  Path(target).files()
        self.test_transform =Compose([ImageToTensor()])
        self.transform1 = iaa.SomeOf((1,4),[
                             iaa.Crop(px=(0, 16)),
                             iaa.Sharpen((0.0, 1.0)),
                             iaa.Fliplr(0.5),
                             iaa.Flipud(0.5),
                             iaa.Affine(rotate=(-90, 90)),  # rotate by -45 to 45 degrees (affects segmaps)
                        ], random_order=True)
        self.transform = JointCompose(
            [
                JointTransform(ImageToTensor(), MaskToTensor())
            ]
        )

    def __len__(self):
#         return len(self.target)
        return len(self.inputs)

    def __getitem__(self, i):
        # at this point all transformations are applied and we expect to work with raw tensors
        images = np.array(io.imread(self.inputs[i]),dtype=np.float32)
        ndsm = np.load(self.inputs_ndsm[i]).astype(np.float32)
        ndsm = (ndsm+1.5)/22*255

        h, w, c = images.shape
        temp = np.zeros((h, w, c + 1))
        temp[:, :, :3] = images
        temp[:, :, 3] = ndsm
        images = temp

        if self.test == False:
            mask = np.array(Image.open(self.target[i]).convert("L"))/255
            mask = np.reshape(mask,(h, w, 1))
            seq_det = self.transform1.to_deterministic()  #
            segmap = ia.SegmentationMapOnImage(mask, shape=mask.shape, nb_classes=2)
            images = seq_det.augment_image(images)
            mask = seq_det.augment_segmentation_maps([segmap])[0].get_arr_int().astype(np.uint8)

            mask = np.reshape(mask,(h, w))
            images, mask = images.copy(), mask.copy()

            images, mask = self.transform(images, mask)
            return images, mask
        else:
            return self.test_transform(images)

关于网络层的修改

通常是将网络的第一层的三通道改为四通道,具体做法可以参照我的另一篇博文

参考资料

许慧敏,齐华,南轲,等.结合 nDSM 的高分辨率遥感影像深度学习分类方法[J].测绘通报,2019( 8) : 63-67.DOI: 10.13474 /j.cnki.11- 2246.2019.0253.

发布了33 篇原创文章 · 获赞 3 · 访问量 5545

猜你喜欢

转载自blog.csdn.net/weixin_42990464/article/details/104338928