我正在尝试进行不同种类的(图像)数据增强以训练神经网络。
我知道tf.image提供了一些增强函数,但它们太简单了 - 例如,我只能将图像旋转90度,而不能设置任意角度。
我也知道tf.keras.preprocessing.image提供了随机旋转、随机剪切、随机移位和随机缩放。但这些方法只适用于numpy数组,而不是张量。
我知道我可以先读取图像,使用tf.keras.preprocessing.image的函数进行增强,然后将这些增强的numpy数组转换为张量。
但是,我想知道是否有一种方法可以实现张量级的增强,这样我就不需要麻烦的“图像文件->张量->numpy数组->张量”过程。
我知道tf.image提供了一些增强函数,但它们太简单了 - 例如,我只能将图像旋转90度,而不能设置任意角度。
我也知道tf.keras.preprocessing.image提供了随机旋转、随机剪切、随机移位和随机缩放。但这些方法只适用于numpy数组,而不是张量。
我知道我可以先读取图像,使用tf.keras.preprocessing.image的函数进行增强,然后将这些增强的numpy数组转换为张量。
但是,我想知道是否有一种方法可以实现张量级的增强,这样我就不需要麻烦的“图像文件->张量->numpy数组->张量”过程。
如果您想知道如何应用变换,请参考以下更新:
如需详细的源代码,请查看tf.contrib.image.transform和tf.contrib.image.matrices_to_flat_transforms。
这是我的代码:
def transformImg(imgIn,forward_transform):
t = tf.contrib.image.matrices_to_flat_transforms(tf.linalg.inv(forward_transform))
# please notice that forward_transform must be a float matrix,
# e.g. [[2.0,0,0],[0,1.0,0],[0,0,1]] will work
# but [[2,0,0],[0,1,0],[0,0,1]] will not
imgOut = tf.contrib.image.transform(imgIn, t, interpolation="BILINEAR",name=None)
return imgOut
基本上,以上代码是在做以下操作:
例如,沿x轴平移的剪切变换如下所示:
因此,我们可以像这样实现剪切变换(使用上面定义的transformImg()
函数):def shear_transform_example(filename,shear_lambda):
image_string = tf.read_file(filename)
image_decoded = tf.image.decode_jpeg(image_string, channels=3)
img = transformImg(image_decoded, [[1.0,shear_lambda,0],[0,1.0,0],[0,0,1.0]])
return img
img = shear_transform_example("white_square.jpg",0.1)
(请注意,img
是一个张量,转换张量为图像文件的代码未包含在内。)
P.S.
以上代码适用于tensorflow 1.10.1版本,可能无法适用于未来的版本。
说实话,我真的不知道为什么他们设计tf.contrib.image.transform的方式,我们还需要使用另一个函数(tf.linalg.inv)才能得到我们想要的结果。我真的希望他们可以改变tf.contrib.image.transform以更加直观的方式工作。