策劃 | 劉燕做者 | 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)