策划 | 刘燕做者 | Renu Khandelwal翻译 | 王文刚编辑 | LindaAI 前线导读:图像加强是一种很是强大的技术,针对现有图像人为建立各类变化以扩展图像数据集,例如缩放现有图像、将现有图像旋转几度、剪切或裁剪图像等等。在本文中,咱们将使用 imgaug 库探索 Python 中的图像加强技术。
更多优质内容请关注微信公众号“AI 前线”(ID:ai-front)咱们为何须要图像加强?微信
深度学习卷积神经网络(CNN)须要大量图像才能有效训练模型。经过更好的加强有助于提升模型的性能,从而减小过分拟合。可用于分类和对象检测数据集的最流行的数据集具备数千到数百万个图像。网络
概括是指在模型训练期间根据之前从未见过的数据进行评估模型的性能测试或验证。因为 CNN 具备不变性,即便在不一样大小,方向或不一样照明下可见时,它也能够对对象进行分类。所以,咱们能够获取图像的小型数据集,并经过放大或缩小,垂直或水平翻转它们或更改亮度来改变对象的大小。这样,咱们能够建立丰富、多样化的图像数据集。app
图像加强能够从一小组图像中建立丰富多样的图像集,以进行图像分类,目标检测或图像分割。在仔细了解问题域以后,须要采用增长训练数据集大小的加强策略。ide
何时须要应用图像加强?函数
在咱们训练模型以前,能够将图像加强用做预处理。 性能
离线或预处理加强学习
加强被用做预处理步骤,以增长数据集的大小。一般,当咱们有一个小的训练数据集要扩展时,即可以完成此操做。测试
在较小的数据集上生成扩充颇有帮助,但在应用于较大的数据集时,咱们须要考虑磁盘空间。 url
在线或实时加强spa
顾名思义,加强是实时应用的。这一般适用于较大的数据集,由于咱们不须要将加强的映像保存在磁盘上。
在这种状况下,咱们在小批量中应用转换,而后将其输入模型。
在线加强模型将在每一个时期看到不一样的图像。在“离线加强”中,加强图像是训练集的一部分,它会根据时期数屡次查看加强图像。
该模型可经过在线加强更好地推广,由于它在经过在线数据加强进行训练期间会看到更多样本。
咱们将使用 imgaug 类来演示图像加强。
基本图像处理技术
翻转:垂直或水平翻转图像
旋转:将图像旋转指定的角度。
剪切:像平行四边形同样移动图像的一部分
裁剪:对象以不一样比例出如今图像中的不一样位置
放大,缩小
改变亮度或对比度
如今,咱们将使用 imgaug 库探索这些数据加强技术
Imgaug
imgaug 是一个用于图像加强以及关键点 / 地标,边界框,热图和分段图的库。
pip install imgaug
在某些状况下,咱们会遇到 Shapely 错误,在这种状况下,咱们能够尝试使用如下命令
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
显示原始图像
咱们使用 imageio 显示原始图像
image = imageio.imread(“.\\car2.jpeg”)
ia.imshow(image)
旋转影像
咱们能够经过指定旋转角度来旋转图像。咱们将图像旋转 -50 度到 30 度
rotate=iaa.Affine(rotate=(-50, 30))
rotated_image=rotate.augment_image(image)
ia.imshow(rotated_image)
给图像添加噪点
咱们将从高斯分布采样的不一样噪声值添加到图像。
gaussian_noise=iaa.AdditiveGaussianNoise(10,20)
noise_image=gaussian_noise.augment_image(image)
ia.imshow(noise_image)
裁剪图像
修剪会删除图像侧面的像素列 / 行。在下面的示例中,咱们将图像的一侧裁剪了 30%
crop = iaa.Crop(percent=(0, 0.3)) # crop image
corp_image=crop.augment_image(image)
ia.imshow(corp_image)
扭曲图像
设置 0 到 40 度
shear = iaa.Affine(shear=(0,40))
shear_image=shear.augment_image(image)
ia.imshow(shear_image)
翻转图像
咱们能够垂直或水平翻转图像。Fliplr 水平翻转图像
#flipping image horizontally
flip_hr=iaa.Fliplr(p=1.0)
flip_hr_image= flip_hr.augment_image(image)
ia.imshow(flip_hr_image)
垂直翻转图像
flip_vr=iaa.Flipud(p=1.0)
flip_vr_image= flip_vr.augment_image(image)
ia.imshow(flip_vr_image)
改变图像的亮度
咱们使用 GammaContrast 经过缩放像素值来调整图像亮度。在 gamma =(0.5,2.0)范围内的值彷佛是明智的。咱们也可使用 SigmoidContrast 或 LinearContrast 来更改图像的亮度
image = imageio.imread(“.\\img Aug\\car2.jpeg”)
contrast=iaa.GammaContrast(gamma=2.0)
contrast_image =contrast.augment_image(image)
ia.imshow(contrast_image)
缩放图像
咱们可使用缩放来放大或缩小图像。咱们已将图像缩放到图像高度 / 宽度的 150%至 80%。咱们能够独立缩放每一个轴
加强物体检测
咱们绘制边界框以进行对象检测。当咱们放大图像时,咱们但愿包围盒也相应地更新。
imgaug 支持边界框。当咱们旋转,剪切或裁剪图像时,对象周围的边界框也会相应更新。
从 imgaug 导入边界框
from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage
初始化原始图像周围的边界框
bbs = BoundingBoxesOnImage([
BoundingBox(x1=10, x2=520, y1=10, y2=300)
], shape=image.shape)
在原始图像上方显示边框
ia.imshow(bbs.draw_on_image(image, size=2))
在下面的代码中,咱们使用 translate_percentage 移动图像,扩大边界框并将其应用于图像上
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))
边界框的部分在图像外部。在下面的代码中,咱们将
将边框彻底或部分移出图像
裁剪部分位于外部的边界框,使其彻底位于图像内部
咱们建立一个 padding 函数,以 1 像素的白色边框和 1 像素的黑色边框填充图像:
def pad(image, by):
image_border1 = ia.pad(image, top=1, right=1, bottom=1, left=1,
mode="constant", cval=255)
image_border2 = ia.pad(image_border1, top=by-1, right=by-1,
bottom=by-1, left=by-1,
mode="constant", cval=0)
return image_border2
而后,咱们在图像上绘制边界框。咱们首先将图像平面扩展 BORDER 像素,而后标记图像平面内的边界框
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)