Categories
程式開發

Python中的圖像增強技術


圖像增強是一種非常強大的技術,針對現有圖像人為創建各種變化以擴展圖像數據集,例如縮放現有圖像、將現有圖像旋轉幾度、剪切或裁剪圖像等等。在本文中,我們將使用imgaug庫探索Python中的圖像增強技術。

我們為什麼需要圖像增強?

深度學習卷積神經網絡(CNN)需要大量圖像才能有效訓練模型。通過更好的增強有助於提高模型的性能,從而減少過度擬合。可用於分類和對象檢測數據集的最流行的數據集具有數千到數百萬個圖像。

歸納是指在模型訓練期間根據以前從未見過的數據進行評估模型的性能測試或驗證。由於CNN具有不變性,即使在不同大小,方向或不同照明下可見時,它也可以對對象進行分類。因此,我們可以獲取圖像的小型數據集,並通過放大或縮小,垂直或水平翻轉它們或更改亮度來改變對象的大小。這樣,我們可以創建豐富、多樣化的圖像數據集。

圖像增強可以從一小組圖像中創建豐富多樣的圖像集,以進行圖像分類,目標檢測或圖像分割。
在仔細了解問題域之後,需要採用增加訓練數據集大小的增強策略。

什麼時候需要應用圖像增強?

在我們訓練模型之前,可以將圖像增強用作預處理。

  • 離線或預處理增強

增強被用作預處理步驟,以增加數據集的大小。通常,當我們有一個小的訓練數據集要擴展時,便可以完成此操作。

在較小的數據集上生成擴充很有幫助,但在應用於較大的數據集時,我們需要考慮磁盤空間。

  • 在線或實時增強

顧名思義,增強是實時應用的。這通常適用於較大的數據集,因為我們不需要將增強的映像保存在磁盤上。

在這種情況下,我們在小批量中應用轉換,然後將其輸入模型。

在線增強模型將在每個時期看到不同的圖像。在“離線增強”中,增強圖像是訓練集的一部分,它會根據時期數多次查看增強圖像。

該模型可通過在線增強更好地推廣,因為它在通過在線數據增強進行訓練期間會看到更多樣本。

我們將使用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)

Python中的圖像增強技術 1

旋轉影像

我們可以通過指定旋轉角度來旋轉圖像。我們將圖像旋轉-50度到30度

rotate=iaa.Affine(rotate=(-50, 30))
rotated_image=rotate.augment_image(image)
ia.imshow(rotated_image)

Python中的圖像增強技術 2

給圖像添加噪點

我們將從高斯分佈採樣的不同噪聲值添加到圖像。

gaussian_noise=iaa.AdditiveGaussianNoise(10,20)
noise_image=gaussian_noise.augment_image(image)
ia.imshow(noise_image)

Python中的圖像增強技術 3

裁剪圖像

修剪會刪除圖像側面的像素列/行。在下面的示例中,我們將圖像的一側裁剪了30%

crop = iaa.Crop(percent=(0, 0.3)) # crop image
corp_image=crop.augment_image(image)
ia.imshow(corp_image)

Python中的圖像增強技術 4

扭曲圖像

設置0到40度

shear = iaa.Affine(shear=(0,40))
shear_image=shear.augment_image(image)
ia.imshow(shear_image)

Python中的圖像增強技術 5

翻轉圖像

我們可以垂直或水平翻轉圖像。 Fliplr水平翻轉圖像

#flipping image horizontally
flip_hr=iaa.Fliplr(p=1.0)
flip_hr_image= flip_hr.augment_image(image)
ia.imshow(flip_hr_image)

Python中的圖像增強技術 6

垂直翻轉圖像

flip_vr=iaa.Flipud(p=1.0)
flip_vr_image= flip_vr.augment_image(image)
ia.imshow(flip_vr_image)

Python中的圖像增強技術 7

改變圖像的亮度

我們使用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)

Python中的圖像增強技術 8

縮放圖像

我們可以使用縮放來放大或縮小圖像。我們已將圖像縮放到圖像高度/寬度的150%至80%。我們可以獨立縮放每個軸

Python中的圖像增強技術 9

增強物體檢測

我們繪製邊界框以進行對象檢測。當我們放大圖像時,我們希望包圍盒也相應地更新。

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

Python中的圖像增強技術 10

在下面的代碼中,我們使用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))

Python中的圖像增強技術 11

應用圖像增強後在圖像外部處理邊界框

邊框有時可能會超出圖像,因此我們需要其他代碼來處理這種情況

我們旋轉圖像,並嘗試在對象周圍繪製邊框

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

Python中的圖像增強技術 12

邊界框的部分在圖像外部。在下面的代碼中,我們將

  • 將邊框完全或部分移出圖像
  • 裁剪部分位於外部的邊界框,使其完全位於圖像內部

我們創建一個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)

Python中的圖像增強技術 13

延伸閱讀:

https://towardsdatascience.com/data-augmentation-techniques-in-python-f216ef5eed69