赞
踩
imgaug是一个很好用的图像增广库。学习的最好文档就是官方文档,因此本系列专栏是翻译imgaug库的官方教程文档,全部翻译完后会附增广原图+标签的代码及常用增广图像函数整理~
输入数据格式要求:使用imgaug增广图像只需要几行代码。但在此之前,我们首先要加载图像。Imgaug期望图像是numpy数组,且最好格式为dtype uint8,即当数组的值在0到255的范围内。通道轴总是被期望是最后一个轴,并且对于灰度图像可以不写通道轴。对于非灰度图像,期望的输入颜色空间是RGB。
非uint8数据:需要查看文档中增广图像函数的具体要求,请记住uint8是最受考验的格式。
图像加载函数:因为imgaug只处理增强,而不是图像输入/输出,我们将需要另一个库来加载我们的图像。在python中,一个常见的选择是imageio,我们将在下面使用它。另一个常见的选择是OpenCV通过它的函数cv2.imread()。但是请注意cv2.imread()返回BGR色彩空间中的图像而不是RGB,这意味着您将不得不重新排序通道轴,例如通过cv2.imread(path)[:,:,::-1]。你也可以将每个依赖于颜色空间的增强器更改为BGR(例如灰度或任何改变色相和/或饱和度的增强器)。请参阅API了解每个增强器的详细信息。后一种方法的缺点是,所有可视化函数(例如下面的imog .imshow())仍然需要RGB数据,因此BGR图像看起来会很糟糕。
第一个例子,我们将使用imageio.imread()来加载图像并对其进行增强。在下面的代码块中,我们调用imagio.imread(uri)来直接从维基百科加载图像,但我们也可以从文件路径加载它,例如通过imagio.imread(“/path/to/the/file.jpg”)或Windows imagio.imread(“C:\path\to\the\file.jpg”)。imageio.imread(uri)返回一个numpy数组,包含dtype uint8, shape (height, width, channel)和RGB colorspace。这正是我们所需要的。加载图像后,我们使用imgauge .imshow(array)对加载的图像进行可视化。
import imageio
import imgaug as ia
%matplotlib inline
image = imageio.imread("https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png")
print("Original:")
ia.imshow(image)
现在我们已经加载了图像,让我们来扩充它。imgaug以派生自Augmenter父类的类的形式包含许多增强技术。要使用一种增强技术,我们必须用一组超参数实例化它,然后在以后多次应用它。我们的第一个增广技术将是仿射Affine,即仿射变换。我们简单使用该技术在-25°和+25°之间随机旋转图像。
from imgaug import augmenters as iaa
ia.seed(4)
rotate = iaa.Affine(rotate=(-25, 25))
image_aug = rotate(image=image)
print("Augmented:")
ia.imshow(image_aug)
我们可以只是将参数image更改为images就实现批量增强。通常,对一批图像进行增强比对每一张图像进行单独增强要快得多。
为了简单起见,我们在这里创建了一个批处理,只需复制原始图像几次,然后通过旋转增强器将其输入。为了可视化结果,我们使用numpy的hstack()函数,该函数通过将增强批处理中的图像水平地放在一起,将它们组合成一个大图像。
import numpy as np
images = [image, image, image, image]
images_aug = rotate(images=images)
print("Augmented batch:")
ia.imshow(np.hstack(images_aug))
可以看到,批处理中的所有图像都自动旋转了不同的数量。这是因为当通过rotate = iaa.Affine(rotate=(- 25,25))实例化我们的仿射变换时,我们对旋转用一个给定区间(- 25,25),表示旋转度数均匀分布在(-25,25)。我们还可以选择常量rotate=-25来始终旋转-25°,或者选择列表rotate=[-25, -15, 0]来旋转-25°、-15°或0°。我们也可以选择很多其他的概率分布,比如高斯分布或泊松分布。需要查阅相关文档。
图像列表or单个数组:注意,在上面的示例中,我们使用了一个列表将图像组合为一批。我们还可以提供一个形状(N, H, W, [C])的单一numpy数组,其中N表示图像的数量,H表示高度,W表示宽度,C(可选)表示通道轴。通常首选使用numpy数组,因为它们可以节省内存,而且扩充图像速度更快一些。然而,如果你的图像有不同的高度,宽度或通道的数量,它们不能组合到一个单一的数组,则必须使用列表。
只执行仿射旋转是相当有限的。因此,在下一个例子中,我们将结合几种方法,并将它们同时应用于图像。为此,我们可以实例化每一种技术,并通过多次调用augmenter(images=…)逐个应用它们。或者,我们可以使用Sequential将不同的增强器组合到一个管道中,然后在单个增强调用中应用它们。我们将使用下面的Sequential来应用仿射旋转(affine),添加一些高斯噪声(AdditiveGaussianNoise),并通过从图像的每一侧删除0%到20%来裁剪图像(crop)。
seq = iaa.Sequential([
iaa.Affine(rotate=(-25, 25)),
iaa.AdditiveGaussianNoise(scale=(10, 60)),
iaa.Crop(percent=(0, 0.2))
])
images_aug = seq(images=images)
print("Augmented:")
ia.imshow(np.hstack(images_aug))
注意到一些图片是放大的,这个是因为Crop。还要注意所有的图像仍然具有相同的大小。这是因为默认情况下,Crop会保留输入图像的大小,即,在移除像素后,它会将剩余的图像调整回输入大小。如果你不喜欢调整回原来的图像大小,实例化Crop时写为 Crop(…, keep_size=False),其中keep_size表示“在输入和输出之间保持图像大小不变”。
在上面,我们使用Sequential来组合几种增强技术。在实践中,我们也可以将每种技术保存在一个列表中,并手动遍历该列表以单独应用每种技术。虽然Sequential简化了事情,但它并没有多大帮助。然而,它确实有一个我们还没有用到的方便的能力那就是随机增广。如果被激活,它会以随机的顺序应用扩展,极大地增加了可能扩展的空间,让我们不必自己去实现它。
在下一个例子中,我们将使用这种能力。为了更明显,我们增加了一些增强的强度,并显示更多的图像。还要注意,我们是如何通过循环将输入图像增强八次,而不是对整个批处理使用单个调用的增强。这是因为随机顺序是每批采样一次,而不是每个批中图像采样一次。为了在这里看到许多不同的顺序,我们因此增强了多次。
seq = iaa.Sequential([
iaa.Affine(rotate=(-25, 25)),
iaa.AdditiveGaussianNoise(scale=(30, 90)),
iaa.Crop(percent=(0, 0.4))
], random_order=True)
images_aug = [seq(image=image) for _ in range(8)]
print("Augmented:")
ia.imshow(ia.draw_grid(images_aug, cols=4, rows=2))
仔细看上面的图片。有些是在旋转前被裁剪的,有些是旋转后裁剪的。因为其中几张照片的黑色像素添加了高斯噪声,而另一些没有添加高斯噪声。这些无噪声黑色像素是通过仿射旋转Affine填充新创建的像素。因此,没有噪声的黑色像素图像是在旋转前应用高斯噪声增强的。
上面已经提到,imgaug支持包含不同大小图像的批处理,但到目前为止,我们一直使用相同的图像。下面的示例显示了具有不同图像尺寸大小的情况。我们从维基百科加载三张图片,将它们作为单个批处理进行扩充,然后逐个显示每张图片(带有输入和输出形状)。这次我们还使用了一些不同的增强技术。
seq = iaa.Sequential([ iaa.CropAndPad(percent=(-0.2, 0.2), pad_mode="edge"), # crop and pad images iaa.AddToHueAndSaturation((-60, 60)), # change their color iaa.ElasticTransformation(alpha=90, sigma=9), # water-like effect iaa.Cutout() # replace one squared area within the image by a constant intensity value ], random_order=True) # load images with different sizes images_different_sizes = [ imageio.imread("https://upload.wikimedia.org/wikipedia/commons/e/ed/BRACHYLAGUS_IDAHOENSIS.jpg"), imageio.imread("https://upload.wikimedia.org/wikipedia/commons/c/c9/Southern_swamp_rabbit_baby.jpg"), imageio.imread("https://upload.wikimedia.org/wikipedia/commons/9/9f/Lower_Keys_marsh_rabbit.jpg") ] # augment them as one batch images_aug = seq(images=images_different_sizes) # visualize the results print("Image 0 (input shape: %s, output shape: %s)" % (images_different_sizes[0].shape, images_aug[0].shape)) ia.imshow(np.hstack([images_different_sizes[0], images_aug[0]])) print("Image 1 (input shape: %s, output shape: %s)" % (images_different_sizes[1].shape, images_aug[1].shape)) ia.imshow(np.hstack([images_different_sizes[1], images_aug[1]])) print("Image 2 (input shape: %s, output shape: %s)" % (images_different_sizes[2].shape, images_aug[2].shape)) ia.imshow(np.hstack([images_different_sizes[2], images_aug[2]]))
Image 0 (input shape: (257, 286, 3), output shape: (257, 286, 3))
Image 1 (input shape: (536, 800, 3), output shape: (536, 800, 3))
Image 2 (input shape: (289, 520, 3), output shape: (289, 520, 3))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。