欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-15 10:34:41
...

前言

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

结合nDSM的dataloader(pytorch)

本节的主要思想是首先用DSM和DTM相减得出nDSM,以numpy形式保存, 然后将其作为第四波段叠加到影像数据上,继而进行数据增强等一系列操作。将相关数据可视化,效果如下:
如何将nDSM等高程数据用于语义分割
如何将nDSM等高程数据用于语义分割
如何将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.

相关标签: 语义分割