imgaug數據增強庫使用

原文鏈接:https://blog.csdn.net/qq_38451119/article/details/82428612

imgaug是一個封裝好的用來進行圖像augmentation的python庫,支持關鍵點(keypoint)和bounding box一起變換。項目主頁: imgaug doc

1. 安裝和卸載

# 通過github安裝
sudo pip install git+https://github.com/aleju/imgaug

# 通過pypi安裝
sudo pip install imgaug

# 本地安裝, 下面的VERSION變成自己想要安裝的version, 例如: imgaug-0.2.5.tar.gz
python setup.py sdist && sudo pip install dist/imgaug-VERSION.tar.gz

# 卸載
sudo pip uninstall imgaug

2. 基本使用

首先定義一個變換序列,然後直接將圖像batch傳入即可:

from imgaug import augmenters as iaa

seq = iaa.Sequential([
    iaa.Crop(px=(0, 16)), # crop images from each side by 0 to 16px (randomly chosen)
    iaa.Fliplr(0.5), # 0.5 is the probability, horizontally flip 50% of the images
    iaa.GaussianBlur(sigma=(0, 3.0)) # blur images with a sigma of 0 to 3.0
])

for batch_idx in range(1000):
    # 'images' should be either a 4D numpy array of shape (N, height, width, channels)
    # or a list of 3D numpy arrays, each having shape (height, width, channels).
    # Grayscale images must have shape (height, width, 1) each.
    # All images must have numpy's dtype uint8. Values are expected to be in
    # range 0-255.
    images = load_batch(batch_idx)
    images_aug = seq.augment_images(images)
    train_on_images(images_aug)

3. Augmenters常用函數

先導入Augmenters類:

from imgaug import augmenters as iaa

3.1 iaa.Sequential()

產生一個處理圖片的Sequential 
函數原型:

iaa.Sequential(children=None,
               random_order=False,
               name=None,
               deterministic=False,
               random_state=None)

參數:

  • children: 想要應用在圖像上的Augmenter或者Augmenter集合。默認None
  • random_order: bool類型, 默認False。是否對每個batch的圖片應用不同順序的Augmenter list。當設置爲True時,不同batch之間圖片的處理順序都會不一樣,但是同一個batch內順序相同。
  • deterministic: bool類型, 默認False。

3.2 iaa.someOf()

將Augmenter中的部分變換應用在圖片處理上,而不是應用所有的Augmenter。例如:可以定義20種變換,但每次只選擇其中的5個。但是不支持固定選擇某一個Augmenter。

函數原型:

iaa.SomeOf(n=None,
           children=None,
           random_order=False,
           name=None,
           deterministic=False,
           random_state=None)

參數:

  • n: 從總的Augmenters中選擇多少個。可以是一個int, tuple, list或者隨機值。
  • random_order: 是否每次順序不一樣。 
    例子:
# 每次選擇一個翻轉方式
seq = iaa.SomeOf(1, [
     iaa.Fliplr(1.0),
     iaa.Flipud(1.0)
 ])
imgs_aug = seq.augment_images(imgs)

# 每次使用1~3個Augmenter來處理圖片,每個batch中的Augmenters順序一樣。
seq = iaa.SomeOf((1, 3), [
     iaa.Fliplr(1.0),
     iaa.Flipud(1.0),
     iaa.GaussianBlur(1.0)
 ])
imgs_aug = seq.augment_images(imgs)

# 每次使用1到多個Augmenter來處理圖片,每個batch中的Augmenters順序不一樣。
seq = iaa.SomeOf((1, None), [
    iaa.Fliplr(1.0),
     iaa.Flipud(1.0),
     iaa.GaussianBlur(1.0)
 ], random_order=True)
imgs_aug = seq.augment_images(imgs)

3.3 iaa.OneOf()

每次從一系列Augmenters中選擇一個來變換。

iaa.OneOf(children,
          name=None,
          deterministic=False,
          random_state=None)

參數含義與上面一樣。

3.4 iaa.Sometimes()

對batch中的一部分圖片應用一部分Augmenters,剩下的圖片應用另外的Augmenters。

iaa.Sometimes(p=0.5,
              then_list=None,
              else_list=None,
              name=None,
              deterministic=False,
              random_state=None)
  • p: float。多大比例的圖片會被Augmente。
  • then_list: Augmenter集合。p概率的圖片進行變換的Augmenters。
  • else_list: 1-p概率的圖片會被進行變換的Augmenters。注意變換的圖片應用的Augmenter只能是then_list或者else_list中的一個。

3.5 iaa.WithColorspace()

在某個特定的顏色空間對圖像進行變換。即:先將圖片從一個顏色空間變換到另一個顏色空間,然後在另一個顏色空間中對圖像進行變換,最後再變換回原來的顏色空間。

iaa.WithColorspace(to_colorspace,
                   from_colorspace='RGB',
                   children=None,
                   name=None,
                   deterministic=False,
                   random_state=None)
  • to_colorspace: 要變換的顏色空間。有以下選擇:RGB, BGR, GRAY, CIE, YCrCb, HSV, HLS, Lab, Luv
  • from_colorspace: 原來的顏色空間, 默認RGB。
  • children: 要執行的變換。
# 先將圖片從RGB變換到HSV,然後將H值增加10,然後再變換回RGB。
aug = iaa.WithColorspace(to_colorspace="HSV", from_colorspace="RGB",
                         children=iaa.WithChannels(0, iaa.Add(10)))

3.6 iaa.WithChannels()

從圖片中挑選出一個Channel來進行變換,變換完了之後再將該channel merge回去。

iaa.WithChannels(channels=None,
                 children=None,
                 name=None,
                 deterministic=False,
                 random_state=None)

參數:

  • channels: int或者int list。哪些channel要被用來變換。
  • children: channel被選出來之後要進行哪些變換。

3.7 iaa.Noop()

不進行任何變換。某些情況下只想使用一個Augmenter作爲佔位符,這樣可以繼續調用augment_image()函數,但實際不作變換。例如進行測試的時候可以使用這個。

3.8 iaa.Lambda()

自定義一些變換函數。

iaa.Lambda(func_images,
           func_keypoints,
           name=None,
           deterministic=False,
           random_state=None)

參數:

  • func_images: 對每一個image調用此函數。該函數的形式爲:
function(images, random_state, parents, hooks)

該函數必須返回變換後的圖片。 
+ func_keypoints: 對每個圖像的關鍵點進行變換的函數。該函數形式爲:

function(keypoints_on_images, random_state, parents, hooks)

該函數返回變換後的keypoint。

例子:

def func_images(images, random_state, parents, hooks):
    images[:, ::2, :, :] = 0
    return images

def func_keypoints(keypoints_on_images, random_state, parents, hooks):
    return keypoints_on_images

aug = iaa.Lambda(
    func_images=func_images,
    func_keypoints=func_keypoints
)

將每張圖片沒隔兩行的像素點變成黑色的條帶,關鍵點保留。

3.9 iaa.AssertShape()

assert要變換的圖片和keypoint的shape。如果不滿足就拋出異常。

iaa.AssertShape(shape,
                check_images=True,
                check_keypoints=True,
                name=None,
                deterministic=False,
                random_state=None)

參數:

  • shape: 元組,通常形式爲(N, H, W, C)。元組中每個元素的值可以爲:None, int, 兩個int類型的tuple或者一個int類型的list。如果是None,表示所有值都可以接受。如果是int,則只有對應的位置是該值纔會被接受。如果是int類型的tuple,例如(a,b),則對應位置的值必須是a<=x
# 檢查輸入的每張圖片是否是32×32×3的,如果是則執行水平翻轉,否則報錯
seq = iaa.Sequential([
    iaa.AssertShape((None, 32, 32, 3)),
    iaa.Fliplr(0.5)
])

# 先檢查圖片的高度是否是32<=H<64, 寬度是否是32, channel是否是1或者3。如果都滿足則執行水平翻轉,否則報錯。
seq = iaa.Sequential([
    iaa.AssertShape((None, (32, 64), 32, [1, 3])),
    iaa.Fliplr(0.5)
])

3.10 iaa.Scale()

將圖像縮放到固定大小。

iaa.Scale(size,
          interpolation='cubic',
          name=None,
          deterministic=False,
          random_state=None)

參數:

  • size: 字符串”keep”,此時保持圖像原大小不坐縮放。如果是一個整數n,則縮放成(n, n)。如果是一個float v,則每張圖片會被縮放成(H*v, W*v),此時每張圖像大小仍然不一樣。如果是一個tuple類型(a, b), 如果a、b中至少有一個小數,則從[a,b]中挑選一個數作爲縮放比例。如果a、b都是整數,則從[a,b]中挑選一個整數作爲縮放後的大小。如果是1個list,則list中的數要麼全是整數,要麼全是小數(不能混用)。如果是一個dict類型,則該dict必須有兩個key: height和width。每個key的值仍然可以按照上面的方法選取。此外, key的值還可以是”keep-aspect-ratio”, 表示按照比例縮放。
  • interpolation: 縮放方法。如果是All, 則會隨機從下面挑選一個: nearest、linear、area、cubic,注意每張圖片可能不一樣。如果是int,則應該是下面的一種:cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_AREA,cv2.INTER_CUBIC。如果是string,則該種方法會被一直使用,必須是下面的一種: nearest, linear, area, cubic。如果是int list或者string list, 則每張圖片會從中隨機選取一個。

3.11 iaa.CropAndPad()

截取(crop)或者填充(pad),填充時,被填充區域爲黑色。

iaa.CropAndPad(px=None,
               percent=None,
               pad_mode='constant',
               pad_cval=0,
               keep_size=True,
               sample_independently=True,
               name=None,
               deterministic=False,
               random_state=None)

參數:

  • px: 想要crop(negative values)的或者pad(positive values)的像素點。注意與percent不能同時存在。如果是None, pixel級別的crop不會被使用。int或者int list與上面相同。如果是一個4個元素的tuple,那麼4個元素分別代表(top, right, bottom, left),每個元素可以是int或者int tuple或者int list。
  • percent:按比例來crop或者pad, 與px相同。但是兩者不能同時存在。
  • pad_mode: 填充方式。可以是All, string, string list。可選的填充方式有: constant, edge, linear_ramp, maximum, median, minimum, reflect, symmetric, wrap。具體含義可查numpy文檔。
  • pad_cval: float、int、float tuple、int tuple、float list、int list。當pad_mode=constant的時候選擇填充的值。
  • keep_size: bool類型。經過crop後,圖像大小會改變。如果該值設置爲1,則在crop或者pad後再縮放成原來的大小。
  • sample_independently : bool類型。如果設置爲False,則每次從px或者percent中選出來的值會作用在四個方位。

3.12 iaa.Pad()

與iaa.CropAndPad()相同,只接受positive values。

3.13 iaa.Crop()

與iaa.CropAndPad()相同,只接受negative values。

3.14 iaa.Fliplr()

水平鏡面翻轉。

iaa.Fliplr(p=0, name=None, deterministic=False, random_state=None)

參數: 
p: int或者float,每張圖片唄翻轉的概率

3.15 Flipud()

上下翻轉,與上面相同。

3.16 iaa.ChangeColorspace()

改變圖像空間。

iaa.ChangeColorspace(to_colorspace, from_colorspace='RGB', alpha=1.0, name=None, deterministic=False, random_state=None)

參數:

  • to_colorspace: 見上。
  • from_colorspace: 見上。
  • alpha: 覆蓋舊的顏色空間時,新顏色空間的Alpha值。爲int, float, int tuple, float tuple

3.17 iaa.Grayscale()

變成灰度圖。

iaa.Grayscale(alpha=0, from_colorspace='RGB', name=None, deterministic=False, random_state=None)

參數:

  • alpha: 覆蓋舊的顏色空間時,新顏色空間的Alpha值。

3.18 iaa.GaussianBlur()

高斯擾動。

iaa.GaussianBlur(sigma=0, name=None, deterministic=False, random_state=None)

參數:

  • sigma: 高斯變換的標準差。可爲float, float tuple。常見的有0,不擾動。3,強擾動。

3.19 iaa.AverageBlur()

從最鄰近像素中取均值來擾動。

iaa.AverageBlur(k=1, name=None, deterministic=False, random_state=None)

參數:

  • k:窗口大小。可爲int, int tuple。當爲int tuple時,如果每個元素也是tuple,每個元素分別作爲height和width,窗口大小不一致。

3.20 iaa.MedianBlur()

通過最近鄰中位數來擾動。

iaa.MedianBlur(k=1, name=None, deterministic=False, random_state=None)

與上面相同。

3.21 iaa.Convolve()

對圖像使用卷積。

iaa.Convolve(matrix=None, name=None, deterministic=False, random_state=None)
  • matrix: 卷積矩陣。

3.22 iaa.Sharpen()

銳化。

iaa.Sharpen(alpha=0, lightness=1, name=None, deterministic=False, random_state=None)

3.23 iaa.Emboss()

浮雕效果。

iaa.Emboss(alpha=0, strength=1, name=None, deterministic=False, random_state=None)

3.24 iaa.EdgeDetect()

邊緣檢測。

iaa.EdgeDetect(alpha=0, name=None, deterministic=False, random_state=None)

3.25 iaa.DirectedEdgeDetect()

特定方向的邊緣檢測。

iaa.DirectedEdgeDetect(alpha=0, direction=(0.0, 1.0), name=None, deterministic=False, random_state=None)

3.26 iaa.Add()

隨機加上一個值。

iaa.Add(value=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.27 iaa.AddElementwise()

按像素加。

iaa.AddElementwise(value=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.28 iaa.AdditiveGaussianNoise()

添加高斯噪聲。

iaa.AdditiveGaussianNoise(loc=0, scale=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.29 iaa.Multiply()

給圖像中的每個像素點乘一個值使得圖片更亮或者更暗。

iaa.Multiply(mul=1.0, per_channel=False, name=None, deterministic=False, random_state=None)

3.30 iaa.MultiplyElementwise()

按像素值乘。

iaa.MultiplyElementwise(self, mul=1.0, per_channel=False, name=None, deterministic=False, random_state=None)

3.31 iaa.Dropout()

隨機去掉一些像素點, 即把這些像素點變成0。

iaa.Dropout(p=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.32 iaa.CoarseDropout()

將矩形框的值設置爲0。

iaa.CoarseDropout(p=0, size_px=None, size_percent=None, per_channel=False, min_size=4, name=None, deterministic=False, random_state=None)

3.33 iaa.Invert()

將每個像素值p變成255-p。

iaa.Invert(p=0, per_channel=False, min_value=0, max_value=255, name=None, deterministic=False, random_state=None)

3.34 iaa.ContrastNormalization()

改變圖像的對比度。

iaa.ContrastNormalization(alpha=1.0, per_channel=False, name=None, deterministic=False, random_state=None)

3.35 iaa.Affine()

仿射變換。包含:平移(Translation)、旋轉(Rotation)、放縮(zoom)、錯切(shear)。仿設變換通常會產生一些新的像素點,我們需要指定這些新的像素點的生成方法,這種指定通過設置cvalmode兩個參數來實現。參數order用來設置插值方法。

iaa.Affine(scale=1.0,
           translate_percent=None,
           translate_px=None,
           rotate=0.0,
           shear=0.0,
           order=1,
           cval=0,
           mode='constant',
           name=None, deterministic=False, random_state=None)

參數:

  • scale: 圖像縮放因子。1表示不縮放,0.5表示縮小到原來的50%。此參數可以是float, float tuple, dict。如果是float, 則所有圖片按照這種比例縮放。如果是float tuple, 則隨機選取一個值來進行縮放,此時x-axisy-axis的縮放比例相同。如果是一個dict,則應該有兩個key:x, y,每個xy的值都可以是float, float tuple,此時x-axisy-axis的縮放比例不一樣。
  • translate_percent: 平移比例,0表示不平移,0.5表示平移50%。可以是float, float tuple, dict,具體含義與scale相同。用正負來表示平移方向。
  • translate_px: 按照像素來進行平移。可以是int, int tuple, dict,具體含義與translate_percent相同。
  • rotate: 平移角度,0~360度之間,正負也可以表示方向。可以爲float, float tuple
  • shear: 錯切的程度,0~360度之間,正負表示方向。可以爲float, int, float tuple, int tuple
  • order: 插值順序,與skimage中定義相同。下面0和1方法快,3比較慢,4、5特別慢。可以是int, int list, ia.ALL。如果是ia.ALL,則每次從所有的插值方法中隨機選取。 
    • 0:最鄰近插值。
    • 1: 雙線性插值(默認)。
    • 2: 雙二次插值(不推薦)。
    • 3:雙三次插值。
    • 4: Bi-quartic。
    • 5:Bi-quintic。
  • cval: 當平移後使用常量填充的時候指定填充的常量值,只有在mode=constant的時候纔會生效。可以是int, float, tuple, ia.ALL。如果是ia.ALL,則會從[0,255]之間隨機選取一個值填充。
  • mode: 採用何種方式填充經過變換後空白的像素點。可以是string, string list, ia.ALL。基本用法與上面相同。其中字符串的選取範圍是: 
    • constant: 採用一個常量填充。
    • edge: 邊緣填充。
    • symmetric: 鏡面對稱填充。
    • reflect: Pads with the reflection of the vector mirrored on the first and last values of the vector along each axis.
    • wrap: Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning.

3.36 iaa.PiecewiseAffine()

隨機放置一些規則的網格點然後移動這些點的周圍的像素。這回導致局部的扭曲。

iaa.PiecewiseAffine(scale=0,
                    nb_rows=4,
                    nb_cols=4,
                    order=1,
                    cval=0,
                    mode='constant',
                    name=None, deterministic=False, random_state=None)

3.37 iaa.ElasticTransformation()

通過移動局部像素來變換。

iaa.ElasticTransformation(alpha=0,
                          sigma=0,
                          name=None,
                          deterministic=False,
                          random_state=None)

4. keypoint變換

imgaug支持在圖像變換的同時變換圖像中的關鍵點。例子如下:

import imgaug as ia
from imgaug import augmenters as iaa

iaa.seed(1)

image=ia.quokka(size=(256,256))

# 定義4個關鍵點
keypoints=ia.KeypointsOnImage([
    ia.Keypoint(x=65, y=100),
    ia.Keypoint(x=75, y=200),
    ia.Keypoint(x=100, y=100),
    ia.Keypoint(x=200, y=80)
], shape=image.shape)

# 定義一個變換序列
seq=iaa.Sequential([
    iaa.Multiply((1.2, 1.5)), # 改變亮度,不影響關鍵點
    iaa.Affine(
        rotate=10,
        scale=(0.5, 0.7)
    ) # 旋轉10度然後縮放,會影響關鍵點
])

# 固定變換序列,之後就可以先變換圖像然後變換關鍵點,這樣可以保證兩次的變換完全相同。
# 如果調用次函數,需要在每次batch的時候都調用一次,否則不同的batch執行相同的變換。
seq_det = seq.to_deterministic()

# 轉換成list或者batch來變換。由於只有一張圖片, 因此用[0]來取出該圖和關鍵點。
image_aug = seq_det.augment_images([image])[0]
keypoints_aug = seq_det.augment_keypoints([keypoints])[0]

# print coordinates before/after augmentation (see below)
# use after.x_int and after.y_int to get rounded integer coordinates
for i in range(len(keypoints.keypoints)):
    before = keypoints.keypoints[i]
    after = keypoints_aug.keypoints[i]
    print("Keypoint %d: (%.8f, %.8f) -> (%.8f, %.8f)" % (
        i, before.x, before.y, after.x, after.y)
    )

# 將關鍵點畫在圖片上。
# image with keypoints before/after augmentation (shown below)
image_before = keypoints.draw_on_image(image, size=7)
image_after = keypoints_aug.draw_on_image(image_aug, size=7)

fig, axes = plt.subplots(2, 1, figsize=(20, 15))
plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8, top=0.8, hspace=0.3, wspace=0.0)
axes[0].set_title("image before")
axes[0].imshow(image_before)
axes[1].set_title("image after augmentation")
axes[1].imshow(image_after)

plt.show()

5. Bounding Boxes變換

imgaug在圖像變換的同時變換圖像中的bound box。bounding的支持包括:

  • 將bounding box封裝成對象
  • 對bounding box進行變換
  • 將bounding box畫在圖像上
  • 移動bounding box的位置,將變換後的bounding box映射到圖像上,計算bounding box的IoU。

5.1 基本變換

例子如下:

import imgaug as ia
from imgaug import augmenters as iaa

ia.seed(1)

image = ia.quokka(size=(256, 256))

# 定義2個bounding box
bbs = ia.BoundingBoxesOnImage([
    ia.BoundingBox(x1=65, y1=100, x2=200, y2=150),
    ia.BoundingBox(x1=150, y1=80, x2=200, y2=130)
], shape=image.shape)

seq = iaa.Sequential([
    iaa.Multiply((1.2, 1.5)), # 改變亮度, 不影響bounding box
    iaa.Affine(
        translate_px={"x": 40, "y": 60},
        scale=(0.5, 0.7)
    ) # 平移後縮放,會影響bounding box
])

# 固定變換
seq_det = seq.to_deterministic()

# 變換圖像和bounding box
image_aug = seq_det.augment_images([image])[0]
bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]

# 打印座標
# use .x1_int, .y_int, ... to get integer coordinates
for i in range(len(bbs.bounding_boxes)):
    before = bbs.bounding_boxes[i]
    after = bbs_aug.bounding_boxes[i]
    print("BB %d: (%.4f, %.4f, %.4f, %.4f) -> (%.4f, %.4f, %.4f, %.4f)" % (
        i,
        before.x1, before.y1, before.x2, before.y2,
        after.x1, after.y1, after.x2, after.y2)
    )
# 輸出
# BB 0: (65.0000, 100.0000, 200.0000, 150.0000) -> (130.7524, 171.3311, 210.1272, 200.7291)
# BB 1: (150.0000, 80.0000, 200.0000, 130.0000) -> (180.7291, 159.5718, 210.1272, 188.9699)

# image with BBs before/after augmentation (shown below)
image_before = bbs.draw_on_image(image, thickness=2)
image_after = bbs_aug.draw_on_image(image_aug, thickness=2, color=[0, 0, 255])

fig, axes = plt.subplots(2, 1, figsize=(20, 15))
plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8, top=0.8, hspace=0.3, wspace=0.0)
axes[0].set_title("image before")
axes[0].imshow(image_before)
axes[1].set_title("image after augmentation")
axes[1].imshow(image_after)

plt.show()

5.2 平移bounding box

調用shift函數即可。

import imgaug as ia
from imgaug import augmenters as iaa

ia.seed(1)

# Define image and two bounding boxes
image = ia.quokka(size=(256, 256))
bbs = ia.BoundingBoxesOnImage([
    ia.BoundingBox(x1=25, x2=75, y1=25, y2=75),
    ia.BoundingBox(x1=100, x2=150, y1=25, y2=75)
], shape=image.shape)

# 兩個box先右移動25像素,然後第2個box再向下移動25像素
bbs_shifted = bbs.shift(left=25)
bbs_shifted.bounding_boxes[1] = bbs_shifted.bounding_boxes[1].shift(top=25)

# Draw images before/after moving BBs
image = bbs.draw_on_image(image, color=[0, 255, 0], thickness=2, alpha=0.75)
image = bbs_shifted.draw_on_image(image, color=[0, 0, 255], thickness=2, alpha=0.75)

得到的圖像爲: 

5.3 圖像有縮放時bounding box的映射

調用on函數即可。

import imgaug as ia
from imgaug import augmenters as iaa

ia.seed(1)

# Define image with two bounding boxes
image = ia.quokka(size=(256, 256))
bbs = ia.BoundingBoxesOnImage([
    ia.BoundingBox(x1=25, x2=75, y1=25, y2=75),
    ia.BoundingBox(x1=100, x2=150, y1=25, y2=75)
], shape=image.shape)

# Rescale image and bounding boxes
image_rescaled = ia.imresize_single_image(image, (512, 512))
bbs_rescaled = bbs.on(image_rescaled)

# Draw image before/after rescaling and with rescaled bounding boxes
image_bbs = bbs.draw_on_image(image, thickness=2)
image_rescaled_bbs = bbs_rescaled.draw_on_image(image_rescaled, thickness=2)

5.4 計算Intersections, Unions和IoU

import imgaug as ia
from imgaug import augmenters as iaa
import numpy as np

ia.seed(1)

# Define image with two bounding boxes.
image = ia.quokka(size=(256, 256))
bb1 = ia.BoundingBox(x1=50, x2=100, y1=25, y2=75)
bb2 = ia.BoundingBox(x1=75, x2=125, y1=50, y2=100)

# Compute intersection, union and IoU value
# Intersection and union are both bounding boxes. They are here
# decreased/increased in size purely for better visualization.
bb_inters = bb1.intersection(bb2).extend(all_sides=-1)
bb_union = bb1.union(bb2).extend(all_sides=2)
iou = bb1.iou(bb2)

# Draw bounding boxes, intersection, union and IoU value on image.
image_bbs = np.copy(image)
image_bbs = bb1.draw_on_image(image_bbs, thickness=2, color=[0, 255, 0])
image_bbs = bb2.draw_on_image(image_bbs, thickness=2, color=[0, 255, 0])
image_bbs = bb_inters.draw_on_image(image_bbs, thickness=2, color=[255, 0, 0])
image_bbs = bb_union.draw_on_image(image_bbs, thickness=2, color=[0, 0, 255])
image_bbs = ia.draw_text(
    image_bbs, text="IoU=%.2f" % (iou,),
    x=bb_union.x2+10, y=bb_union.y1+bb_union.height//2,
    color=[255, 255, 255], size=13
)

得到的圖像如下: 

6. Stochastic Parameter

在做變換的時候,我們希望每張圖片的變換都不一樣,通過參數隨機化選取可以實現。但是想要復現之前的變換,需要通過determinism來實現,比較繁瑣。爲了避免這種情況,使用Stochastic Parameters來實現。這個變量通常是一個抽象的概率分佈,例如正太分佈、均勻分佈等等。通常所有的augmenter都能接受這個參數,這樣就很方便控制變量範圍。他們都可以和determinism結合。 
例子:

from imgaug import augmenters as iaa
from imgaug import parameters as iap

seq = iaa.Sequential([
    iaa.GaussianBlur(
        sigma=iap.Uniform(0.0, 1.0)
    ),
    iaa.ContrastNormalization(
        iap.Choice(
            [1.0, 1.5, 3.0],
            p=[0.5, 0.3, 0.2]
        )
    ),
    iaa.Affine(
        rotate=iap.Normal(0.0, 30),
        translate_px=iap.RandomSign(iap.Poisson(3))
    ),
    iaa.AddElementwise(
        iap.Discretize(
            (iap.Beta(0.5, 0.5) * 2 - 1.0) * 64
        )
    ),
    iaa.Multiply(
        iap.Positive(iap.Normal(0.0, 0.1)) + 1.0
    )
])

所有可用的概率分佈有:

6.1 正態分佈

Normal(loc, scale): 均值爲loc,標準差scale。

from imgaug import parameters as iap
params = [
    iap.Normal(0, 1),
    iap.Normal(5, 3),
    iap.Normal(iap.Choice([-3, 3]), 1),
    iap.Normal(iap.Uniform(-3, 3), 1)
]
iap.show_distributions_grid(params)

6.2 拉普拉斯分佈

Laplace(loc, scale): 峯值loc, 寬度scale:

from imgaug import parameters as iap
params = [
    iap.Laplace(0, 1),
    iap.Laplace(5, 3),
    iap.Laplace(iap.Choice([-3, 3]), 1),
    iap.Laplace(iap.Uniform(-3, 3), 1)
]
iap.show_distributions_grid(params)

6.3 其他連續概率分佈還有:

  • 卡方分佈(ChiSquare)
  • 韋伯分佈(Weibull)
  • 均勻分佈(Uniform )
  • Beta分佈

6.4 離散概率分佈

  • 二項分佈(Binomial)
  • 離散均勻分佈(DiscreteUniform)
  • 泊松分佈(Poisson distribution)

6.5 對分佈的數學運算

imgaug支持隨機參數的算術運算。 允許修改從分佈中抽取的值或者將幾個分佈相互組合。支持的操作有:

  • Add
  • Subtract
  • Multiply
  • Divide
  • Power

6.6 特殊參數

支持的操作有:

  • Deterministic
  • Choice
  • Clip
  • Discretize
  • Absolute
  • RandomSign
  • ForceSign
  • Positive
  • Negative
  • FromLowerResolution

具體含義和用法見文檔。

7. Blending/Overlaying images

augment會直接改變圖片而把原圖捨棄掉了。有時我們需要改變圖像的局部,或者將原來的圖片跟新變換的圖片結合起來。這可以通過給變換前後的圖片配上一定的權重(參數)或者使用一個pixel-wise的mask。 
一個例子如下:

# First row
iaa.Alpha(
    (0.0, 1.0),
    first=iaa.MedianBlur(11),
    per_channel=True
)

# Second row
iaa.SimplexNoiseAlpha(
    first=iaa.EdgeDetect(1.0),
    per_channel=False
)

# Third row
iaa.SimplexNoiseAlpha(
    first=iaa.EdgeDetect(1.0),
    second=iaa.ContrastNormalization((0.5, 2.0)),
    per_channel=0.5
)

# Forth row
iaa.FrequencyNoiseAlpha(
    first=iaa.Affine(
        rotate=(-10, 10),
        translate_px={"x": (-4, 4), "y": (-4, 4)}
    ),
    second=iaa.AddToHueAndSaturation((-40, 40)),
    per_channel=0.5
)

# Fifth row
iaa.SimplexNoiseAlpha(
    first=iaa.SimplexNoiseAlpha(
        first=iaa.EdgeDetect(1.0),
        second=iaa.ContrastNormalization((0.5, 2.0)),
        per_channel=True
    ),
    second=iaa.FrequencyNoiseAlpha(
        exponent=(-2.5, -1.0),
        first=iaa.Affine(
            rotate=(-10, 10),
            translate_px={"x": (-4, 4), "y": (-4, 4)}
        ),
        second=iaa.AddToHueAndSaturation((-40, 40)),
        per_channel=True
    ),
    per_channel=True,
    aggregation_method="max",
    sigmoid=False
)

得到的圖片爲: 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章