我正在尝试进行不同类型的(图像)数据增强来训练我的神经网络 .
我知道tf.image提供了一些增强功能,但它们太简单了 - 例如,我只能将图像旋转90度,而不是任何程度 .
我也知道tf.keras.preprocessing.image提供随机旋转,随机剪切,随机移位和随机缩放 . 但是这些方法只能应用于numpy数组,而不是张量 .
我知道我可以先读取图像,使用tf.keras.preprocessing.image中的函数进行扩充,然后将这些扩充的numpy数组转换为张量 .
但是,我只是想知道是否有一种方法可以实现张量增强,因此我不需要打扰“图像文件 - >张量 - > numpy数组 - >张量”程序 .
Update for those who want to know how to apply your transform:
有关详细的源代码,您可能需要检查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
基本上,上面的代码正在做
为 imgIn
中的每个点(x,y) .
例如,与x轴平行的shear transform是
因此,我们可以像这样实现剪切变换(使用上面定义的 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在a more intuitive way中工作 .
2 回答
看看tf.contrib.image.transform . 它可以将一般投影变换应用于图像 .
您还需要查看tf.contrib.image.matrices_to_flat_transforms将您的仿射矩阵转换为
tf.contrib.image.transform
接受的投影格式 .我通常使用
tf.data.Dataset
和Dataset.map
和tf.py_func
.Dataset.prefetch
意味着您可能需要重新考虑多个GPU的操作,但以下在单GPU系统上适用于我 .为简单起见,我'll assume you have all your images on disk in separate files, though it can easily be adapted for zip archives or other formats like hdf5 (won' t工作
.tar
文件 - 不知道为什么,但我怀疑它无论如何都是个好主意 . )您也可以在tensorflow中进行解码并直接在
py_func
中使用any_cv2_or_numpy_augmentations
(尽管您不会注意到性能差异 .检查this answer以获取更多选项 .