[深度学习] imgaug库使用笔记

imgaug是一款非常有用的python图像增强库,非常值得推荐应用于深度学习图像增强。其包含许多增强技术,支持图像分类,目标检测,语义分割,热图、关键点检测等一系列任务的图像增强。本文主要介绍imgaug基本使用,以及应用关键点和边界框增强。

  • 官方代码仓库:imgaug
  • 官方入门文档:imgaug doc
  • 增强效果预览:overview of augmenters
  • Api:imgaug dpi
# 安装imgaug模块
# pip install imgaug

文章目录

  • 1 加载和增强图片
    • 1.1 读图
    • 1.2 增强一张图片
    • 1.3 增强多张图片
    • 1.4 多个增强器使用
    • 1.5 不同尺寸的图片随机增强
    • 1.6 保存图片
  • 2 关键点图片增强
    • 2.1 基础实例
    • 2.2 关键点投影
    • 2.3 关键点平移
    • 2.4 关键点绘制
    • 2.5 关键点与numpy数组
  • 3 边界框增强
    • 3.1 基础实例
    • 3.2 图像旋转带来的问题
    • 3.3 绘图
    • 3.4 提取图像内容,移动边界框
    • 3.5 交并比Intersection, Union and IoU
    • 3.6 将边界框投影到其他图像上
  • 4 参考

1 加载和增强图片

1.1 读图

import imageio
import imgaug as ia
# 图片地址
# https://gitee.com/luohenyueji/article_picture_warehouse/raw/master/private/halayu_avatar/1.jpg
image = imageio.imread("1.jpg")

print("Original:")
ia.imshow(image)

# 改变图形尺寸,(240,120)为图形高宽
image_resize = ia.imresize_single_image(image, (240, 120))
print("Resize:")
ia.imshow(image_resize)
Original:
Resize:

[深度学习] imgaug库使用笔记_第1张图片

[深度学习] imgaug库使用笔记_第2张图片

1.2 增强一张图片

使用该技术将图像旋转-25度至25度之间的随机值,我们也可以直接设置rotate为180,则图片固定旋转180度

from imgaug import augmenters as iaa
# 设定随机数
ia.seed(42)

# 设定角度
rotate = iaa.Affine(rotate=(-25, 25))
image_aug = rotate(image=image)

print("Augmented:")
ia.imshow(image_aug)
Augmented:

[深度学习] imgaug库使用笔记_第3张图片

1.3 增强多张图片

直接将原始图像复制几次,然后进行扩增,得到四张不同效果的扩增图片。通常图片大小不同,用列表最为合适,如果是同样大小,按(N, H, W, [C])顺序输入一个numpy数组也行,N是图像个数,H,W为图像高宽,C为图像通道数。

import numpy as np

images = [image, image, image, image]
images_aug = rotate(images=images)

print("image count: {}".format(len(images_aug)))
print("image size: {}".format(images_aug[0].shape))
print("Augmented batch:")
ia.imshow(np.hstack(images_aug))
image count: 4
image size: (320, 320, 3)
Augmented batch:

[深度学习] imgaug库使用笔记_第4张图片

1.4 多个增强器使用

通过Sequential将不同的增强器组合到一个管道中,然后将它们全部应用到单个增强调用中。如下面例子我们使用仿射旋转(Affine),添加一些高斯噪声(AdditiveGaussianNoise)并通过从每个图像侧面(Crop)删除0%到20%来裁剪图像。不同增强器的接口见Overview of Augmenters

要注意的是Crop函数剪切图片后,图像尺寸不变,非原图区域用黑色填充。如果想要更改图像大小修改Crop为,Crop(…, keep_size=False)

seq = iaa.Sequential([
    iaa.Affine(rotate=(-25, 25)),
    iaa.AdditiveGaussianNoise(scale=(10, 60)),
    iaa.Crop(percent=(0, 0.2),keep_size=True)
])

images_aug = seq(images=images)

for i,img in enumerate(images_aug):
    print("img{} size is{}".format(i,img.shape))

print("Augmented:")
ia.imshow(np.hstack(images_aug))
img0 size is(320, 320, 3)
img1 size is(320, 320, 3)
img2 size is(320, 320, 3)
img3 size is(320, 320, 3)
Augmented:

[深度学习] imgaug库使用笔记_第5张图片

不同尺寸的结果

seq = iaa.Sequential([
    iaa.Affine(rotate=(-25, 25)),
    iaa.AdditiveGaussianNoise(scale=(10, 60)),
    iaa.Crop(percent=(0, 0.2),keep_size=False)
])

images_aug = seq(images=images)

for i,img in enumerate(images_aug):
    print("img{} size is{}".format(i,img.shape))
    ia.imshow(img)
img0 size is(241, 258, 3)
img1 size is(251, 267, 3)

[深度学习] imgaug库使用笔记_第6张图片

[深度学习] imgaug库使用笔记_第7张图片

img2 size is(264, 262, 3)

[深度学习] imgaug库使用笔记_第8张图片

img3 size is(260, 249, 3)

[深度学习] imgaug库使用笔记_第9张图片

此外,我们可以设置random_order=True,以随机排序使用各种增强技术,具体如下所示

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))
Augmented:

1.5 不同尺寸的图片随机增强

这个例子我们将增强不同大小的图像

seq = iaa.Sequential([
    # crop and pad images 裁剪并填充图形
    iaa.CropAndPad(percent=(-0.2, 0.2), pad_mode="edge"),  
    # change their color 更改颜色
    iaa.AddToHueAndSaturation((-60, 60)),  
    # water-like effect 添加水体般的效果
    iaa.ElasticTransformation(alpha=90, sigma=9),  
    # replace one squared area within the image by a constant intensity value 用一个单色框随机填充区域
    iaa.Cutout()  
], random_order=True)

# load images with different sizes
# 不同尺寸图像
images_different_sizes = [
    # https://upload.wikimedia.org/wikipedia/commons/e/ed/BRACHYLAGUS_IDAHOENSIS.jpg
    imageio.imread("https://upload.wikimedia.org/wikipedia/commons/e/ed/BRACHYLAGUS_IDAHOENSIS.jpg"),
    imageio.imread("1.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]]))
Image 0 (input shape: (257, 286, 3), output shape: (257, 286, 3))

[深度学习] imgaug库使用笔记_第10张图片

Image 1 (input shape: (320, 320, 3), output shape: (320, 320, 3))

[深度学习] imgaug库使用笔记_第11张图片

1.6 保存图片

直接循环结果列表通过imageio.imwrite即可保存图片

for index,image in enumerate(images_aug):
    # imwrite == imsave
    imageio.imwrite("result{}.jpg".format(index),image)

2 关键点图片增强

关键点为图像上的点,通常以像素点的坐标位置表示。又称为landmarks,常用于人体姿势估计,人脸识别等。imgaug进行关键点增强所用到的api为KeypointsOnImage,KeypointsOnImage实例化关键点类,将关键点列表与图像形状组合在一起

2.1 基础实例

import imageio
import imgaug as ia

# https://upload.wikimedia.org/wikipedia/commons/e/e6/Macropus_rufogriseus_rufogriseus_Bruny.jpg
image = imageio.imread("https://upload.wikimedia.org/wikipedia/commons/e/e6/Macropus_rufogriseus_rufogriseus_Bruny.jpg")
# 重置图片大小
image = ia.imresize_single_image(image, (389, 259))
ia.imshow(image)

[深度学习] imgaug库使用笔记_第12张图片

然后我们放置并可视化一些关键点

from imgaug.augmentables.kps import Keypoint, KeypointsOnImage
kps = [
    Keypoint(x=99, y=81),   # left eye (from camera perspective)
    Keypoint(x=125, y=80),  # right eye
    Keypoint(x=112, y=102), # nose
    Keypoint(x=102, y=210), # left paw
    Keypoint(x=127, y=207)  # right paw
]
# 实例化关键点类,将关键点列表与图像形状组合在一起
# https://imgaug.readthedocs.io/en/latest/source/api_augmentables_kps.html?highlight=KeypointsOnImage#imgaug.augmentables.kps.KeypointsOnImage.from_xy_array
kpsoi = KeypointsOnImage(kps, shape=image.shape)

ia.imshow(kpsoi.draw_on_image(image, size=7))

# 打印关键点
print(kpsoi.keypoints)

[深度学习] imgaug库使用笔记_第13张图片

[Keypoint(x=99.00000000, y=81.00000000), Keypoint(x=125.00000000, y=80.00000000), Keypoint(x=112.00000000, y=102.00000000), Keypoint(x=102.00000000, y=210.00000000), Keypoint(x=127.00000000, y=207.00000000)]

接下来我们将应用平移和仿射变化改变图片和关键点

import imgaug.augmenters as iaa
ia.seed(3)

seq = iaa.Sequential([
    iaa.Affine(translate_px={"x": (10, 30)}, rotate=(-10, 10)),
    # color jitter, only affects the image 色彩抖动只影响图片,不影响关键点。
    iaa.AddToHueAndSaturation((-50, 50))  
])

# 输入图形和关键点参数,得到变换后的图形和关键点参数
# 如果是处理多张图像,给出图像列表和对应的关键点列表
image_aug, kpsoi_aug = seq(image=image, keypoints=kpsoi)

# 可视化变换前后关键点效果
import numpy as np
ia.imshow(
    np.hstack([
        kpsoi.draw_on_image(image, size=7),
        kpsoi_aug.draw_on_image(image_aug, size=7)
    ])
)

[深度学习] imgaug库使用笔记_第14张图片

2.2 关键点投影

使用关键点时,您可能有时必须更改图像大小。KeypointsOnImage.on(image or shape)更改图像大小后,该方法可用于重新计算关键点坐标。它将关键点投影到新图像上相同的相对位置上

# 扩大图像为原来的两倍
image_larger = ia.imresize_single_image(image, 2.0)

print("Small image %s with keypoints optimized for the size:" % (image.shape,))
ia.imshow(kpsoi.draw_on_image(image, size=7))

print("Large image %s with keypoints optimized for the small image size:" % (image_larger.shape,))
ia.imshow(kpsoi.draw_on_image(image_larger, size=7))

print("Large image %s with keypoints projected onto that size:" % (image_larger.shape,))
ia.imshow(kpsoi.on(image_larger).draw_on_image(image_larger, size=7))
Small image (389, 259, 3) with keypoints optimized for the size:

[深度学习] imgaug库使用笔记_第15张图片

Large image (778, 518, 3) with keypoints optimized for the small image size:

[深度学习] imgaug库使用笔记_第16张图片

Large image (778, 518, 3) with keypoints projected onto that size:

[深度学习] imgaug库使用笔记_第17张图片

当然输出投影后的关键点信息也可以用KeypointsOnImage.on

# 打印关键点
print(kpsoi.keypoints)
# 打印关键点
print(kpsoi.on(image_larger).keypoints)
[Keypoint(x=99.00000000, y=81.00000000), Keypoint(x=125.00000000, y=80.00000000), Keypoint(x=112.00000000, y=102.00000000), Keypoint(x=102.00000000, y=210.00000000), Keypoint(x=127.00000000, y=207.00000000)]
[Keypoint(x=198.00000000, y=162.00000000), Keypoint(x=250.00000000, y=160.00000000), Keypoint(x=224.00000000, y=203.99998474), Keypoint(x=204.00000000, y=420.00000000), Keypoint(x=254.00000000, y=414.00003052)]

2.3 关键点平移

前面提到的on()可以在调整大小的图像的情况下提供帮助,但是在填充图像时则无济于事,因为在这些情况下,关键点在图像上的相对位置会发生变化。可以使用KeypointsOnImage.shift(x=, y=)来补偿这种填充,其中x描述了向左/向右和y向顶部/底部的移动。

image_pad = ia.pad(image, left=100)
kpsoi_pad = kpsoi.shift(x=100)
ia.imshow(kpsoi_pad.draw_on_image(image_pad, size=7))
# 打印关键点
print(kpsoi.shift(x=100).keypoints)
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/imgaug/imgaug.py:106: DeprecationWarning: Using imgaug.imgaug.pad is deprecated. Use imgaug.augmenters.size.pad instead.
  warn(msg, category=DeprecationWarning, stacklevel=stacklevel)

[深度学习] imgaug库使用笔记_第18张图片

[Keypoint(x=199.00000000, y=81.00000000), Keypoint(x=225.00000000, y=80.00000000), Keypoint(x=212.00000000, y=102.00000000), Keypoint(x=202.00000000, y=210.00000000), Keypoint(x=227.00000000, y=207.00000000)]

2.4 关键点绘制

KeypointsOnImage.draw_on_image()可以在图像上绘制关键点,size控制关键点大小,color控制关键点颜色。

ia.imshow(np.hstack([
    kpsoi.draw_on_image(image, size=1, color=(0, 255, 0)),
    kpsoi.draw_on_image(image, size=3, color=(0, 0, 255)),
    kpsoi.draw_on_image(image, size=5, color=(255, 128, 255)),
    kpsoi.draw_on_image(image, size=7, color=(255, 255, 255))
]))

[深度学习] imgaug库使用笔记_第19张图片

此外draw_on_image()方法还提供了一个copy参数,可以将其设置为False直接修改图像

image_draw = np.copy(image)
kpsoi.draw_on_image(image_draw, size=5, color=(0, 255, 0), copy=False)
kpsoi.shift(x=-70).draw_on_image(image_draw, size=5, color=(255, 255, 255), copy=False)
kpsoi.shift(x=70).draw_on_image(image_draw, size=5, color=(0, 0, 0), copy=False)
ia.imshow(image_draw)

[深度学习] imgaug库使用笔记_第20张图片

以下代码显示如何单独设置各个关键点的颜色

colors = [(0, 255, 0),
          (255, 255, 255),
          (128, 255, 64),
          (128, 64, 255),
          (128, 128, 0)]
image_drawn = np.copy(image)
for kp, color in zip(kpsoi.keypoints, colors):
    image_drawn = kp.draw_on_image(image_drawn, color=color, size=9, copy=False)
ia.imshow(image_drawn)

[深度学习] imgaug库使用笔记_第21张图片

2.5 关键点与numpy数组

KeypointsOnImage可以轻松转换为(N, 2)xy坐标形式的float32 numpy数组

arr = kpsoi.to_xy_array()
print("Keypoints as objects:", kpsoi.keypoints)
print("Keypoints as array:", arr)
print("Shape:", arr.shape)
Keypoints as objects: [Keypoint(x=99.00000000, y=81.00000000), Keypoint(x=125.00000000, y=80.00000000), Keypoint(x=112.00000000, y=102.00000000), Keypoint(x=102.00000000, y=210.00000000), Keypoint(x=127.00000000, y=207.00000000)]
Keypoints as array: [[ 99.  81.]
 [125.  80.]
 [112. 102.]
 [102. 210.]
 [127. 207.]]
Shape: (5, 2)

同样numpy数组也可以直接转换为KeypointsOnImage,但必须要提供图像尺寸

xy = np.float32([
    [10, 20],
    [50, 17],
    [27.54, 49.13]
])
image_height = 50
image_width = 100
kpsoi_new = ia.KeypointsOnImage.from_xy_array(xy, shape=(image_height, image_width, 3))
print(kpsoi_new)
KeypointsOnImage([Keypoint(x=10.00000000, y=20.00000000), Keypoint(x=50.00000000, y=17.00000000), Keypoint(x=27.54000092, y=49.13000107)], shape=(50, 100, 3))

3 边界框增强

常用api如下:

  1. imgaug.augmentables.bbs.BoundingBox(x1, y1, x2, y2, label=None): 单个边界框的容器,根据其左上角和右下角定义,每个角均以x和y像素坐标给出,label为标签
  2. imgaug.augmentables.bbs.BoundingBoxesOnImage(bounding_boxes, shape): 包含放置在图像上的边界框列表的容器。shape变量表示放置边界框的图像的形状。

3.1 基础实例

让我们尝试一个简单的边界框增强示例。我们加载一张图像,在其上放置两个边界框,然后使用仿射变换来扩充数据。首先,我们加载并可视化数据。

import imageio
import imgaug as ia
from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage

ia.seed(42)

image = imageio.imread("https://upload.wikimedia.org/wikipedia/commons/8/8e/Yellow-headed_caracara_%28Milvago_chimachima%29_on_capybara_%28Hydrochoeris_hydrochaeris%29.JPG")
# 重置图像大小
image = ia.imresize_single_image(image, (298, 447))

# 设置边界框
bbs = BoundingBoxesOnImage([
    # 边界框的左上角和右下角坐标
    BoundingBox(x1=0.2*447, x2=0.85*447, y1=0.3*298, y2=0.95*298),
    BoundingBox(x1=0.4*447, x2=0.65*447, y1=0.1*298, y2=0.4*298)
], shape=image.shape)

ia.imshow(bbs.draw_on_image(image, size=2))

[深度学习] imgaug库使用笔记_第22张图片

下一步是定义我们要应用的增强方法。我们选择一个简单的对比度增强(仅影响图像)和仿射变换(影响图像和边界框)。

from imgaug import augmenters as iaa 
ia.seed(1)

seq = iaa.Sequential([
    iaa.GammaContrast(1.5),
    iaa.Affine(translate_percent={"x": 0.1}, scale=0.8)
])

现在,我们同时增强图像和其上的边框。我们可以使用seq.augment(…)它或它的快捷方式seq(…)。请注意,如果我们想扩充几张图片,则可以使用seq(images=[image1, image2, …], bounding_boxes=[bbs1, bbs2, …])。该方法相当灵活,并且还可以处理不同于的边界框BoundingBoxesOnImage

# 输入增强前的图像和边框,得到增强后的图像和边框
image_aug, bbs_aug = seq(image=image, bounding_boxes=bbs)
# 可视化,size边框的宽度
ia.imshow(bbs_aug.draw_on_image(image_aug, size=2))

[深度学习] imgaug库使用笔记_第23张图片

如果想要保存数据到xml,直接循环提取信息即可

for index,bb in enumerate(bbs):
    print("index is {}".format(index))
    print("x1 is {}".format(bb.x1))
    print("y1 is {}".format(bb.y1))
    print("x2 is {}".format(bb.x2))
    print("y2 is {}".format(bb.y2))
    print("label is {}".format(bb.label))
    print("-"*50)
index is 0
x1 is 89.4
y1 is 89.39999999999999
x2 is 379.95
y2 is 283.09999999999997
label is None
--------------------------------------------------
index is 1
x1 is 178.8
y1 is 29.8
x2 is 290.55
y2 is 119.2
label is None
--------------------------------------------------

3.2 图像旋转带来的问题

让我们尝试另一种增强技术。这次我们应用仅包含旋转的仿射变换。

image_aug, bbs_aug = iaa.Affine(rotate=45)(image=image, bounding_boxes=bbs)
ia.imshow(bbs_aug.draw_on_image(image_aug))

[深度学习] imgaug库使用笔记_第24张图片

您现在可能倾向于说这些增强功能看起来有些错误,并且某些地方一定出错了。但是输出实际上是正确的,并且显示了边界框扩展的特殊情况,为什么要避免旋转。问题源于非对象像素是边界框的一部分。旋转后,必须绘制一个新的边界框,其中包含了这些非对象像素。以下示例将问题可视化。可以看到旋转后原来的对象一部分在图像外了,所以尽可能不要旋转图像。

import numpy as np
import matplotlib.pyplot as plt

# highlight the area of each bounding box
# 深度复制图像
image_points = np.copy(image)
colors = [(0, 255, 0), (128, 128, 255)]
# 设置每个边框面积颜色
for bb, color in zip(bbs.bounding_boxes, colors):
    image_points[bb.y1_int:bb.y2_int:4, bb.x1_int:bb.x2_int:4] = color

# rotate the image with the highlighted bounding box areas
# 旋转图像
rot = iaa.Affine(rotate=45)
image_points_aug, bbs_aug = rot(image=image_points, bounding_boxes=bbs)

# visualize
# 可视化
side_by_side = np.hstack([
    bbs.draw_on_image(image_points, size=2),
    bbs_aug.draw_on_image(image_points_aug, size=2)
])
fig, ax = plt.subplots(figsize=(20, 20))
ax.imshow(side_by_side)

[深度学习] imgaug库使用笔记_第25张图片

3.3 绘图

常见的操作是在图像上绘制边框。上面的示例中已经使用了执行此操作的方法。它提供参数来控制绘制的边界框的颜色,size(即边框厚度)和alpha(即透明度)。以下示例显示了它们的用法。

image_bbs = np.copy(image)
image_bbs = bbs.bounding_boxes[0].draw_on_image(image_bbs, color=[255, 0, 0], size=3)
image_bbs = bbs.bounding_boxes[1].draw_on_image(image_bbs, color=[0, 255, 0], size=10, alpha=0.5)
ia.imshow(image_bbs)

[深度学习] imgaug库使用笔记_第26张图片

如果我们向边界框添加标签,它们也会自动绘制

bbs_labeled = bbs.deepcopy()
# 添加标签
bbs_labeled[0].label = "approximately a pig"
bbs_labeled[1].label = "bird"

image_bbs = bbs_labeled.draw_on_image(image, size=2)

ia.imshow(image_bbs)

[深度学习] imgaug库使用笔记_第27张图片

如果要在边界框上设置标签但不绘制它们,请在每个边界框上手动调用draw_box_on_image()或者draw_label_on_image()。那只会画边界框或者标签

bbs_labeled = bbs.deepcopy()
# 添加标签
bbs_labeled[0].label = "approximately a pig"
bbs_labeled[1].label = "bird"

image_bbs = bbs_labeled.bounding_boxes[0].draw_box_on_image(image,size=2)
ia.imshow(image_bbs)
image_bbs = bbs_labeled.bounding_boxes[1].draw_label_on_image(image,size=2)
ia.imshow(image_bbs)

[深度学习] imgaug库使用笔记_第28张图片

[深度学习] imgaug库使用笔记_第29张图片

3.4 提取图像内容,移动边界框

使用边界框时,另一种常见操作是提取其相应的图像区域。当边界框完全位于图像平面内时,这很容易。如果它全部或部分位于图像平面之外,则操作将变得更加复杂。BoundingBox提供extract_from_image(image),避免了处理此类问题。如果边界框未完全位于图像中,则将结果零填充,以达到边界框的高度和宽度。

bird = bbs.bounding_boxes[1].extract_from_image(image)
ia.imshow(bird)

[深度学习] imgaug库使用笔记_第30张图片

通过结合.extend()和.extract_from_image()可以提取更大的图像区域

bird = bbs.bounding_boxes[1].extend(all_sides=10, left=100).extract_from_image(image)
ia.imshow(bird)

[深度学习] imgaug库使用笔记_第31张图片

现在,我们将边界框部分移到图像的外部,然后提取其内容

bb = bbs.bounding_boxes[1].shift(x=200)
ia.imshow(bb.draw_on_image(image, size=2))
ia.imshow(bb.extract_from_image(image))

[深度学习] imgaug库使用笔记_第32张图片

[深度学习] imgaug库使用笔记_第33张图片

如您在第二张图像中看到的,图像外部的像素填充有零。如果您不希望这样做,则可以添加参数pad=False以停用填充。默认情况下,它将仍然填充以防止任何轴变为零,即,您将不会获得(0, 0, 3)输出数组。这样可以防止错误,例如在绘制过程中。如果您希望在这种情况下获得零大小的数组,只需添加prevent_zero_size=False。

3.5 交并比Intersection, Union and IoU

在处理边界框时,计算IoU值(联合上的交集)是最常见的任务之一。imgaug提供了一种方法可用于计算边界框的交集和并集。让我们从相交处开始,可以使用相交进行估算BoundingBox.intersection(other_bounding_box)并返回一个新的边界框。

# 例子中两个边框的交集
bb_intersection = bbs.bounding_boxes[0].intersection(bbs.bounding_boxes[1])
ia.imshow(bb_intersection.draw_on_image(image))
print("The intersection has a height of %.4f, width of %.4f and an area of %.4f" % (
    bb_intersection.height, bb_intersection.width, bb_intersection.area))

[深度学习] imgaug库使用笔记_第34张图片

The intersection has a height of 29.8000, width of 111.7500 and an area of 3330.1500

现在,使用BoundingBox.union(other_bounding_box)计算并集

bb_union = bbs.bounding_boxes[0].union(bbs.bounding_boxes[1])
ia.imshow(bb_union.draw_on_image(image, size=2))
print("The union has a height of %.4f, width of %.4f and an area of %.4f." % (
    bb_union.height, bb_union.width, bb_union.area))

[深度学习] imgaug库使用笔记_第35张图片

The union has a height of 253.3000, width of 290.5500 and an area of 73596.3150.

最后是IoU值,计算为BoundingBox.iou(other_bounding_box)。在下面的代码块中,我们为标准示例边界框计算一次,然后在移动两个框之一以使其重叠的情况下计算一次。在后一种情况下,IoU较高。

# Shift one BB down so that the BBs overlap
# 平移图像,以重叠图像
bbs_shifted = ia.BoundingBoxesOnImage([
    bbs.bounding_boxes[0],
    bbs.bounding_boxes[1].shift(y=100),
], shape=bbs.shape)

# Compute IoU without shift
# 平移前的交并比
iou = bbs.bounding_boxes[0].iou(bbs.bounding_boxes[1])
print("The IoU of the bounding boxes is: %.4f." % (iou,))

# Compute IoU after shift
# 平移后的交并比
iou_shifted = bbs.bounding_boxes[0].iou(bbs_shifted.bounding_boxes[1])
print("The IoU of the bounding boxes after shifting one box is: %.4f." % (iou_shifted,))

# Visualize unshifted and shifted BBs
ia.imshow(
    np.hstack([
        bbs.draw_on_image(image, size=3),
        bbs_shifted.draw_on_image(image, size=3),
    ])
)
The IoU of the bounding boxes is: 0.0529.
The IoU of the bounding boxes after shifting one box is: 0.1775.

[深度学习] imgaug库使用笔记_第36张图片

3.6 将边界框投影到其他图像上

有时可能需要将边界框从一个图像投影到另一个图像。这在调整图像大小时尤其重要。在这种情况下,您可以使用BoundingBox.project(from_shape, to_shap)和BoundingBoxesImage.on(new_image)。如下所示。如果您必须补偿填充,请使用BoundingBox.shift([top]、[right]、[bottom]、[left])或相同的BoundingBoxesImage方法。对于BoundingBoxesImage,请确保在填充后使用新的图像形状更新.shape属性。

# we limit the example here to the bounding box of the bird
# #我们将这里的例子局限于鸟的边界框
bb_bird = bbs.bounding_boxes[1]
bbsoi_bird = ia.BoundingBoxesOnImage([bbs.bounding_boxes[1]], shape=image.shape)

# lets resize the original image to twice its width
# 扩大图像的宽为原来的两倍
image_larger = ia.imresize_single_image(image, (1.0, 2.0))

# we draw what would happen without any change to the bounding box
# 原始框绘制
print("BoundingBox without changes:")
ia.imshow(bb_bird.draw_on_image(image_larger, size=3))

# now the change it using project()
# 使用project扩充绘制框
print("BoundingBox with project(from, to):")
ia.imshow(bb_bird.project(from_shape=image.shape, to_shape=image_larger.shape).draw_on_image(image_larger, size=3))

BoundingBox without changes:

[深度学习] imgaug库使用笔记_第37张图片

BoundingBox with project(from, to):

[深度学习] imgaug库使用笔记_第38张图片

也可以用on方法绘制框

# and now we do the same two steps for BoundingBoxesOnImage, though here the method is called .on()
print("BoundingBoxesOnImage without changes:")
ia.imshow(bbsoi_bird.draw_on_image(image_larger, size=3))

print("BoundingBoxesOnImage with on(shape):")
ia.imshow(bbsoi_bird.on(image_larger.shape).draw_on_image(image_larger, size=3))
BoundingBoxesOnImage without changes:

[深度学习] imgaug库使用笔记_第39张图片

BoundingBoxesOnImage with on(shape):

[深度学习] imgaug库使用笔记_第40张图片

4 参考

  • imgaug
  • imgaug doc
  • overview of augmenters
  • imgaug dpi

你可能感兴趣的:(图像处理,深度学习,Python,1024程序员节)