天天看點

[深度學習] 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庫使用筆記
[深度學習] imgaug庫使用筆記

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庫使用筆記

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庫使用筆記

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庫使用筆記

不同尺寸的結果

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庫使用筆記
[深度學習] imgaug庫使用筆記
img2 size is(264, 262, 3)           
[深度學習] imgaug庫使用筆記
img3 size is(260, 249, 3)           
[深度學習] imgaug庫使用筆記

此外,我們可以設定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:           
[深度學習] imgaug庫使用筆記

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庫使用筆記
Image 1 (input shape: (320, 320, 3), output shape: (320, 320, 3))           
[深度學習] imgaug庫使用筆記

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庫使用筆記

然後我們放置并可視化一些關鍵點

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庫使用筆記
[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庫使用筆記

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庫使用筆記
Large image (778, 518, 3) with keypoints optimized for the small image size:           
[深度學習] imgaug庫使用筆記
Large image (778, 518, 3) with keypoints projected onto that size:           
[深度學習] imgaug庫使用筆記

當然輸出投影後的關鍵點資訊也可以用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庫使用筆記
[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庫使用筆記

此外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庫使用筆記

以下代碼顯示如何單獨設定各個關鍵點的顔色

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庫使用筆記

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庫使用筆記

下一步是定義我們要應用的增強方法。我們選擇一個簡單的對比度增強(僅影響圖像)和仿射變換(影響圖像和邊界框)。

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庫使用筆記

如果想要儲存資料到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庫使用筆記

您現在可能傾向于說這些增強功能看起來有些錯誤,并且某些地方一定出錯了。但是輸出實際上是正确的,并且顯示了邊界框擴充的特殊情況,為什麼要避免旋轉。問題源于非對象像素是邊界框的一部分。旋轉後,必須繪制一個新的邊界框,其中包含了這些非對象像素。以下示例将問題可視化。可以看到旋轉後原來的對象一部分在圖像外了,是以盡可能不要旋轉圖像。

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)           
<matplotlib.image.AxesImage at 0x7f36ac06f690>           
[深度學習] imgaug庫使用筆記

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庫使用筆記

如果我們向邊界框添加标簽,它們也會自動繪制

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庫使用筆記

如果要在邊界框上設定标簽但不繪制它們,請在每個邊界框上手動調用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庫使用筆記
[深度學習] imgaug庫使用筆記

3.4 提取圖像内容,移動邊界框

使用邊界框時,另一種常見操作是提取其相應的圖像區域。當邊界框完全位于圖像平面内時,這很容易。如果它全部或部分位于圖像平面之外,則操作将變得更加複雜。BoundingBox提供extract_from_image(image),避免了處理此類問題。如果邊界框未完全位于圖像中,則将結果零填充,以達到邊界框的高度和寬度。

bird = bbs.bounding_boxes[1].extract_from_image(image)
ia.imshow(bird)           
[深度學習] imgaug庫使用筆記

通過結合.extend()和.extract_from_image()可以提取更大的圖像區域

bird = bbs.bounding_boxes[1].extend(all_sides=10, left=100).extract_from_image(image)
ia.imshow(bird)           
[深度學習] imgaug庫使用筆記

現在,我們将邊界框部分移到圖像的外部,然後提取其内容

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庫使用筆記
[深度學習] imgaug庫使用筆記

如您在第二張圖像中看到的,圖像外部的像素填充有零。如果您不希望這樣做,則可以添加參數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庫使用筆記
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庫使用筆記
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庫使用筆記

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庫使用筆記
BoundingBox with project(from, to):           
[深度學習] imgaug庫使用筆記

也可以用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庫使用筆記
BoundingBoxesOnImage with on(shape):           
[深度學習] imgaug庫使用筆記

4 參考

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

繼續閱讀