Python中的数据增强技能
在本文中,将运用imgaug库来探究Python中不同的数据增强技能
什么是图画增强
图画增强是一种强大的技能,用于在现有图画中人为地创立改动以扩展图画数据集。这是经过运用不同的改换技能来完成的,例如缩放、旋转、剪切或裁剪现有图画。方针是创立一组全面的或许图画,代表各种改动。
为什么需求图画增强
图画增强在深度学习卷积神经网络 (CNN) 布景下至关重要,由于它有助于满足有用模型练习对大型且多样化数据集的需求。 CNN 需求很多图画才干有用练习,而图画增强供给了一种人为扩展现有数据集的办法。经过缩放、旋转、剪切或裁剪等技能创立图画改动,图画增强有助于生成更全面的或许图画集。这种多样化的数据集使模型能够更好地泛化,减少过度拟合,并在测验或验证进程中对以前未见过的数据进行评估时进步其功用。因而,图画增强对于进步练习数据的质量和数量至关重要,终究导致更强大和更精确的 CNN 模型。
什么时分运用图画增强
图画增强能够作为练习模型之前的预处理进程,也能够在练习进程中实时运用。当用作预处理进程时,运用增强来增加数据集的巨细,特别是在处理需求扩展的小型练习数据集时。这种办法称为离线或预处理增强,触及生成现有图画的变体以创立更多样化的数据集。运用图画增强时细心考虑问题范畴非常重要,由于某些增强策略或许与特定使命无关或无用。例如,在对不同类型的轿车进行分类时,笔直翻转轿车或许不会为数据集增加价值。因而,图画增强的运用应根据问题范畴的具体要求进行定制。
离线或预处理增强
离线或预处理增强是指运用图画增强作为预处理进程来增加数据集的巨细。这种办法一般在处理需求扩展的小型练习数据集时运用。经过生成现有图画的改动(例如翻转、旋转或缩放),离线增强能够为练习机器学习模型创立愈加多样化的数据集。运用离线增强时,特别是在处理较大的数据集时,考虑磁盘空间非常重要。这种办法答应在练习进程开端之前创立一组全面的或许图画,终究进步练习数据的质量和数量。
在线或实时增强
在线或实时增强触及在练习进程中实时运用增强技能。这种办法一般用于较大的数据集,由于它不需求将增强图画保存在磁盘上。经过实时运用增强,模型在每个时期看到不同的图画,然后有助于练习数据的多样性。实时增强在处理较大的数据集时特别有用,由于它减少了与保存增强图画相关的存储要求。这种办法答应在练习进程中动态运用增强技能,有助于模型从各种图画改动中学习的能力。
我们将运用imgaug类来演示图画增强。imgaug支撑广泛的数据增强技能
基本数据增强技能
-
翻转(Flipping):笔直或水平翻转图画
-
旋转(Rotation):按指定的程度旋转图画
-
剪切(Shearing):像平行四边形一样移动图画的一部分
-
裁剪(Cropping):方针在图画中以不同的份额出现在不同的方位上
-
放大缩小(Zoom in, Zoom out)
-
改动亮度或对比度
现在将运用imgaug库探究这些数据增强技能
实践Imgaug
imgaug是一个用于图画增强的库,包含关键点/地标、鸿沟框、热图和分割图。
- git项目地址:github.com/aleju/imgau…
- 项目文档地址:imgaug.readthedocs.io/en/latest
安装
pip install imageio imgaug
pip install imgaug — upgrade — no-deps # 出现错误时分选用这种
导入相关的依靠包
import imageio
import imgaug as ia
import imgaug.augmenters as iaa
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib
%matplotlib inline
展现原有图画
image = imageio.v2.imread('./Lenna.jpg')
ia.imshow(image)
旋转图画Rotating
能够经过指定旋转度来旋转图画,随机将图画旋转-50度到30度之间,旋转视点能够是负值,表明逆时针旋转,也能够是正值,表明顺时针旋转
rotate = iaa.Affine(rotate=(-50, 30))
rotated_image = rotate.augment_image(image)
ia.imshow(rotated_image)
图画增加噪声Noise
将不同的从高斯分布元素采样的噪声值增加到图画中,参数10
和20
分别表明噪声的均值和标准差。高斯噪声是一种常见的随机噪声,它的数值符合高斯分布(也称为正态分布)。均值参数决议了噪声的中心方位,标准差参数决议了噪声的强度。
gaussian_noise = iaa.AdditiveGaussianNoise(10, 20)
noise_image = gaussian_noise.augment_image(image)
ia.imshow(noise_image)
图画裁剪Cropping
裁剪将删去图画两侧的列/行像素。鄙人面的比如中,将图画的一侧随机裁剪0~30%, 随机的裁剪,使图画具有更多的多样性和改动。裁剪操作能够用于去除图画边际的无用信息、调整图画的组成或者创立更密布的图画副本等。
crop = iaa.Crop(percent=(0, 0.3)) # crop image
corp_image = crop.augment_image(image)
ia.imshow(corp_image)
图画剪切Shearing
剪切图画随机0到40度,错切改换会将图画的一部分按照必定视点进行平移,然后改动图画的形状和内容。能够用于创立透视作用、扭曲图画的形状或者模拟某些特定场景下的形变。
shear = iaa.Affine(shear=(0, 40))
shear_image=shear.augment_image(image)
ia.imshow(shear_image)
图画翻转Flipping
能够笔直地或水平地翻转图画, 这儿展现Fliplr水平翻转图画。水平翻转能够用于纠正图画的方向、增加练习数据的多样性或者模拟镜像对称的场景。
#flipping image horizontally
flip_hr = iaa.Fliplr(p=1.0) # 翻转概率100%, 小于1.0时分是随机翻转,或许不翻转
flip_hr_image = flip_hr.augment_image(image)
ia.imshow(flip_hr_image)
Filpud笔直翻转图画
flip_vr = iaa.Flipud(p=1.0) # 翻转概率为100%
flip_vr_image = flip_vr.augment_image(image)
ia.imshow(flip_vr_image)
图画改动亮度brightness
经过缩放像素值来调整图画的亮度。在Gamma=(0.5, 2.0)范围内的值是合理的。也能够运用符号对比度或线性对比度来改动图画的亮度。伽马对比度增强器会运用一个伽马改换到图画上,经过调整图画的亮度和对比度来改动图画的外观。伽马值决议了改换的强度,较高的伽马值会增加图画的对比度,使得图画的暗部更暗,亮部更亮。
contrast = iaa.GammaContrast(gamma=2.0)
contrast_image =contrast.augment_image(image)
ia.imshow(contrast_image)
图画缩放Scale
能够运用份额尺放大或缩小图画。下面的图画缩放到图画高度/宽度的150%到80%。此外也能够独立地缩放每个轴。函数会随机挑选一个缩放份额,范围在1.0到1.5之间,并分别运用于图画的x和y方向。较小的缩放份额会使图画变小,而较大的缩放份额会使图画变大。缩放改换能够用于调整图画的尺寸、改动物体的份额或者模拟不同间隔下的图画。
scale_im = iaa.Affine(scale={"x": (1.5, 1.0), "y": (1.5, 1.0)})
scale_image = scale_im.augment_image(image)
ia.imshow(scale_image)
对方针检测的增强
为方针检测制作鸿沟框。当增强图画时,希望鸿沟框也被相应地更新。imgaug为鸿沟框供给了支撑。当旋转、剪切或裁剪图画时,方针周围的鸿沟框也会相应地更新。
导入鸿沟框
from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage
原图画出框
bbs = BoundingBoxesOnImage([BoundingBox(x1=80, x2=140, y1=70, y2=150)], shape=image.shape)
ia.imshow(bbs.draw_on_image(image, size=2))
鄙人面的代码中,运用平移百分比来移动图画,扩大鸿沟框,并将其运用到图画上
move = iaa.Affine(translate_percent={"x": 0.1}, scale=0.8)
image_aug, bbs_aug = move(image=image, bounding_boxes=bbs)
ia.imshow(bbs_aug.draw_on_image(image_aug, size=2))
在运用图画增强功用后,处理图画外部的鸿沟框
鸿沟框有时或许会在图画之外,需求额外的代码来处理这样的情况,旋转图画并尝试在方针周围制作鸿沟框。
rotate_bb = iaa.Affine(rotate=(-50, 30))
image_aug, bbs_aug = rotate_bb(image=image, bounding_boxes=bbs)
ia.imshow(bbs_aug.draw_on_image(image_aug, size=2))
鸿沟框的某些部分都在图画的外部。鄙人面的代码中,会看到这些问题:
- 彻底或部分删去图画外部的鸿沟框
- 剪切部分在外部的鸿沟框,使它们彻底在图画内部
创立一个填充功用,用1像素白色和1像素黑色边框填充图画:
# 填充
def pad(image, by):
image_border1 = iaa.size.pad(image, top=1, right=1, bottom=1, left=1, mode="constant", cval=255)
image_border2 = iaa.size.pad(image_border1, top=by-1, right=by-1, bottom=by-1, left=by-1, mode="constant", cval=0)
return image_border2
然后,在图画上制作鸿沟框。首要经过鸿沟像素扩展图画平面,然后在图画平面内符号鸿沟框
def draw_bbs(image, bbs, border):
GREEN = [0, 255, 0]
ORANGE = [255, 140, 0]
RED = [255, 0, 0]
image_border = pad(image, border)
for bb in bbs.bounding_boxes:
if bb.is_fully_within_image(image.shape):
color = GREEN
elif bb.is_partly_within_image(image.shape):
color = ORANGE
else:
color = RED
image_border = bb.shift(left=border, top=border).draw_on_image(image_border, size=2, color=color)
return image_border
现在,对图画运用相同的旋转,并制作鸿沟框
rotate = iaa.Affine(rotate=(-50, 30))
image_aug, bbs_aug = rotate(image=image, bounding_boxes=bbs)
image_after = draw_bbs(image_aug,
bbs_aug.remove_out_of_image().clip_out_of_image(), 100)
ia.imshow(image_after)