用于语义分割的tf.keras图像数据生成器:将y值保留为整数

zlwx9yxi  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(143)

"简而言之"
我想使用易于使用的tf.keras.preprocessing.image.ImageDataGenerator来加载批量的Xy图像,以训练CNN进行语义分割。
不幸的是,y图像的值在这个过程中被改变了,这是不应该的,因为这些值是编码类的整数。

    • 目前使用的数据和代码**

我有Xy数据,它们都是.tif的图像:

  • X图像是RGB图像,尺寸为128 x 128 x 3(3个色带),dtype=uint8中的值理论上在0到255之间。
  • y图像是尺寸为128 x 128 x 1和dtype=uint8的单波段(灰度)图像。它们将33个类编码为整数。

我设置了ImageDataGenerator来批量加载这些图像:

args_col = {"data_format" : "channels_last",
            "featurewise_std_normalization" : False,
            "brightness_range" : [0.5, 1.5]
            }
args_aug = {"rotation_range" : 365,
            "width_shift_range" : 0.25,
            "height_shift_range" : 0.25,
            "horizontal_flip" : True,
            "vertical_flip" : True,
            "fill_mode" : "constant",
            "featurewise_center" : False
            }
args_flow = {"class_mode" : None,
             "batch_size" : 10,
             "target_size" : (128, 128),
             "seed" : 42
             }

X_generator = ks.preprocessing.image.ImageDataGenerator(rescale = 1.0/255.0,
                                                        **args_aug,
                                                        **args_col)
X_gen = X_generator.flow_from_directory(directory = "/path/to/X",
                        color_mode = "rgb",
                        **args_flow)

y_generator = ks.preprocessing.image.ImageDataGenerator(**args_aug,
                                                        cval = NoDataValue,
                                                        dtype = "uint8")
y_gen = y_generator.flow_from_directory(directory = "/path/to/y",
                        color_mode = "grayscale",
                        interpolation = "nearest",
                        **args_flow)

train_generator = zip(X_gen, y_gen)

正如你所看到的,我设置了一个seed值,以获得匹配的图像和遮罩对。X图像被重新缩放,它们的亮度被改变,而y图像不是这样。
输出如下所示:

因此,图块是匹配的,乍一看一切都很好。但是,当我加载一对图像并查看数据格式(通过运行以下代码)时,我将得到dtype=float32

sample_image, sample_mask = next(train_generator)

sample_mask

尽管我为y生成器设置了dtype = "uint8",但这是不可能的。更糟糕的是:不仅数据类型发生了变化,值也发生了变化:

mask_array = np.array(sample_mask)
np.unique(mask_array)

退货:

Out[218]: 
array([ 3.       ,  3.0429225,  3.0458798, ..., 31.99783  , 31.999964 ,
       32.       ], dtype=float32)

(Note小数点分隔符后面的数字!)
显然,在旋转图像时一定存在某种插值。我将.flow_from_directory部分中的interpolation设置为"nearest",因为我认为这将解决问题,并使用 * 最近邻 * 方法选择输出的像素值。不幸的是,情况并非如此(至少在某个点上,有插值正在进行,我的整数类被平均)。
那么,我如何防止这种情况呢?如果可能的话,我想继续使用ImageDataGenerator,因为它使代码易于阅读。

    • 编辑:**

我还尝试将preprocessing_function = toINT与一个函数一起使用

def toINT(filename):
    imgINT = filename.astype("uint8")
    return imgINT

然而,这也不起作用。可能在预处理结束时,值被更改为浮动的...

kmbjn2e3

kmbjn2e31#

您应该在进行模型训练之前对掩码进行编码

相关问题