1、keras 自带的 keras_proprecessing.image 只支持三种模式图片(color_mode in ['grey', 'RGB', 'RGBA'])的随机扩增。
2、遥感数据除了一景影像大,不能一次性扩增外,有的高光谱卫星波段多,如 Landsat8 就有8个波段,无法直接用 keras_proprecessing.image 的 flow_from_directory 和 flow_from_dataframe 进行数据扩增。
3、看了 image 的源码后发现,不能用这两个函数的原因不是因为不能对多波段数据进行扩增,而是因为这两个函数要调用读取图片的函数,而读取图片是用 PIL 读的,因此无法支持多波段遥感影像 tif。
4、而如果已经获得了数据的 numpy array 格式,就可以直接用 flow 生成增强后的数据。因为内部图片的仿射变换是利用了 scipy 中的仿射变换函数 scipy.ndimage.interpolation.affine_transform,它是对2维数据进行变换的,对图片的增强只是简单的对维度进行遍历,每一维的数据进行相同变换后就得到了新的图片,因此和波段数没有关系,支持任意波段数的数据。
5、但我不需要对整个大图片进行增强,我希望是对里面的小 patch 进行逐个扩增,所以也不方便用 flow。flow 需要我已经得到了用于增强的数组,但我希望是一边获得数据一边进行扩增(其实也可以先都获得了然后直接用flow,后面可以试试看能不能直接用 flow 做 image 和 mask 的扩增)
6、所以就在 ImageDataGenerator 类里加了个函数同时对 image 和 mask 进行变换
def random_trans_bothxy(self, img , mask, seed=None): ''' modified by cbj at 2019-04-28 19:32 Applies a random transformation to both image and mask synchronously # Arguments img: 3D tensor, single image. mask: 3D tensor, the corresponding image mask(label. seed: Random seed. # Returns A randomly transformed version of the input (same shape). ''' params = self.get_random_transform(img.shape, seed) return self.apply_transform(img, params),self.apply_transform(mask, params)