Python 第三方模块之 imgaug (图像增强)
imgaug是一個封裝好的用來進(jìn)行圖像augmentation的python庫,支持關(guān)鍵點(diǎn)(keypoint)和bounding box一起變換。
- 項(xiàng)目主頁: 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 imgaug2. 示例
2.1 基本使用
首先定義一個變換序列,然后直接將圖像batch傳入即可:
from imgaug import augmenters as iaaseq = 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 imagesiaa.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)2.2 包含常用的變換示例
import cv2 import numpy as np from imgaug import augmenters as iaa import imgaug as ia# 定義一個lambda表達(dá)式,以p=0.5的概率去執(zhí)行sometimes傳遞的圖像增強(qiáng) sometimes = lambda aug: iaa.Sometimes(0.5, aug) # 建立一個名為seq的實(shí)例,定義增強(qiáng)方法,用于增強(qiáng) aug = iaa.Sequential([iaa.Fliplr(0.5), # 對50%的圖像進(jìn)行鏡像翻轉(zhuǎn)iaa.Flipud(0.2), # 對20%的圖像做左右翻轉(zhuǎn)sometimes(iaa.Crop(percent=(0, 0.1))),# 這里沿襲我們上面提到的sometimes,對隨機(jī)的一部分圖像做crop操作# crop的幅度為0到10%# 或者 sometimes(iaa.Crop(px=(0, 16))),隨機(jī)在距離邊緣的0-16像素中選擇crop范圍# 對一部分圖像做仿射變換sometimes(iaa.Affine(scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}, # 圖像縮放為80%到120%之間translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}, # 平移±20%之間rotate=(-45, 45), # 旋轉(zhuǎn)±45度之間shear=(-16, 16), # 剪切變換±16度,(矩形變平行四邊形)order=[0, 1], # 使用最鄰近差值或者雙線性差值cval=(0, 255), # 全白全黑填充mode=ia.ALL # 定義填充圖像外區(qū)域的方法)),# 使用下面的0個到5個之間的方法去增強(qiáng)圖像。注意SomeOf的用法iaa.SomeOf((0, 5),[# 將部分圖像進(jìn)行超像素的表示。o(╥﹏╥)o用超像素增強(qiáng)作者還是第一次見,比較孤陋寡聞sometimes(iaa.Superpixels(p_replace=(0, 1.0),n_segments=(20, 200))),# 用高斯模糊,均值模糊,中值模糊中的一種增強(qiáng)。注意OneOf的用法iaa.OneOf([iaa.GaussianBlur((0, 3.0)),iaa.AverageBlur(k=(2, 7)), # 核大小2~7之間,k=((5, 7), (1, 3))時,核高度5~7,寬度1~3iaa.MedianBlur(k=(3, 11)),]),# 銳化處理iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)),# 浮雕效果iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)),# 邊緣檢測,將檢測到的賦值0或者255然后疊在原圖上sometimes(iaa.OneOf([iaa.EdgeDetect(alpha=(0, 0.7)),iaa.DirectedEdgeDetect(alpha=(0, 0.7), direction=(0.0, 1.0)),])),# 加入高斯噪聲iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05 * 255), per_channel=0.5),# 將1%到10%的像素設(shè)置為黑色# 或者將3%到15%的像素用原圖大小2%到5%的黑色方塊覆蓋iaa.OneOf([iaa.Dropout((0.01, 0.1), per_channel=0.5),iaa.CoarseDropout((0.03, 0.15), size_percent=(0.02, 0.05),per_channel=0.2),]),# 5%的概率反轉(zhuǎn)像素的強(qiáng)度,即原來的強(qiáng)度為v那么現(xiàn)在的就是255-viaa.Invert(0.05, per_channel=True),# 每個像素隨機(jī)加減-10到10之間的數(shù)iaa.Add((-10, 10), per_channel=0.5),# 像素乘上0.5或者1.5之間的數(shù)字.iaa.Multiply((0.5, 1.5), per_channel=0.5),# 將整個圖像的對比度變?yōu)樵瓉淼囊话牖蛘叨秈aa.ContrastNormalization((0.5, 2.0), per_channel=0.5),# 將RGB變成灰度圖然后乘alpha加在原圖上iaa.Grayscale(alpha=(0.0, 1.0)),# 把像素移動到周圍的地方。這個方法在mnist數(shù)據(jù)集增強(qiáng)中有見到sometimes(iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.25)),# 扭曲圖像的局部區(qū)域sometimes(iaa.PiecewiseAffine(scale=(0.01, 0.05)))],random_order=True # 隨機(jī)的順序把這些操作用在圖像上)],random_order=True # 隨機(jī)的順序把這些操作用在圖像上 )# 數(shù)據(jù)增強(qiáng),針對單張圖片 image = cv2.imread('1.jpg', 0) h = image.shape[0] w = image.shape[1] enhance_num = 32aug_example_img = aug.augment_image(image=image) print(image.shape, aug_example_img.shape)# 生成一個圖片列表example_images = np.array([image for _ in range(enhance_num)],dtype=np.uint8 ) aug_imgs = aug(images=example_images) # images_aug = aug.augment_images(images=img_array) # 顯示圖片 ia.show_grid(aug_imgs, rows=4, cols=8) # 保存圖片 for i in range(aug_imgs.shape[0]):img = aug_imgs[i]cv2.imwrite("aug_%d.jpg" % i, img)# 保存為一張圖片 img_array = np.array([image] * enhance_num, dtype=np.uint8) write_img = np.zeros(shape=(h, (w+10) * enhance_num, 3), dtype=np.uint8) for j, item in enumerate(aug_imgs):write_img[:, j * (w + 10): j * (w + 10) + w, :] = item3 Augmenters常用函數(shù)
先導(dǎo)入Augmenters類
from imgaug import augmenters as iaa3.1 iaa.Sequential()
產(chǎn)生一個處理圖片的 Sequential 函數(shù)原型:
from imgaug import augmenters as iaa iaa.Sequential(children=None,random_order=False,name=None,deterministic=False,random_state=None)參數(shù):
- children: 想要應(yīng)用在圖像上的Augmenter或者Augmenter集合。默認(rèn)None
- random_order: bool類型, 默認(rèn)False。是否對每個batch的圖片應(yīng)用不同順序的Augmenter list。當(dāng)設(shè)置為True時,不同batch之間圖片的處理順序都會不一樣,但是同一個batch內(nèi)順序相同。
- deterministic: bool類型, 默認(rèn)False。
3.2 iaa.someOf()
將Augmenter中的部分變換應(yīng)用在圖片處理上,而不是應(yīng)用所有的Augmenter。例如:可以定義20種變換,但每次只選擇其中的5個。但是不支持固定選擇某一個Augmenter。
函數(shù)原型:
from imgaug import augmenters as iaa iaa.SomeOf(n=None,children=None,random_order=False,name=None,deterministic=False,random_state=None)參數(shù):
- n: 從總的Augmenters中選擇多少個。可以是一個int, tuple, list或者隨機(jī)值。
- random_order: 是否每次順序不一樣。
例子:
# 每次選擇一個翻轉(zhuǎn)方式 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)參數(shù)含義與上面一樣。
3.4 iaa.Sometimes()
對batch中的一部分圖片應(yīng)用一部分Augmenters,剩下的圖片應(yīng)用另外的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概率的圖片進(jìn)行變換的Augmenters。
- else_list: 1-p概率的圖片會被進(jìn)行變換的Augmenters。注意變換的圖片應(yīng)用的Augmenter只能是then_list或者else_list中的一個。
3.5 iaa.WithColorspace()
在某個特定的顏色空間對圖像進(jìn)行變換。即:先將圖片從一個顏色空間變換到另一個顏色空間,然后在另一個顏色空間中對圖像進(jìn)行變換,最后再變換回原來的顏色空間。
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: 原來的顏色空間, 默認(rèn)RGB。
- children: 要執(zhí)行的變換。
3.6 iaa.WithChannels()
從圖片中挑選出一個Channel來進(jìn)行變換,變換完了之后再將該channel merge回去。
iaa.WithChannels(channels=None,children=None,name=None,deterministic=False,random_state=None)參數(shù):
- channels: int或者int list。哪些channel要被用來變換。
- children: channel被選出來之后要進(jìn)行哪些變換。
3.7 iaa.Noop()
不進(jìn)行任何變換。某些情況下只想使用一個Augmenter作為占位符,這樣可以繼續(xù)調(diào)用augment_image()函數(shù),但實(shí)際不作變換。例如進(jìn)行測試的時候可以使用這個。
3.8 iaa.Lambda()
自定義一些變換函數(shù)。
iaa.Lambda(func_images,func_keypoints,name=None,deterministic=False,random_state=None)參數(shù):
- func_images: 對每一個image調(diào)用此函數(shù)。該函數(shù)必須返回變換后的圖片。該函數(shù)的形式為:
- func_keypoints: 對每個圖像的關(guān)鍵點(diǎn)進(jìn)行變換的函數(shù)。該函數(shù)返回變換后的keypoint。該函數(shù)形式為:
例子:
def func_images(images, random_state, parents, hooks):images[:, ::2, :, :] = 0return imagesdef func_keypoints(keypoints_on_images, random_state, parents, hooks):return keypoints_on_imagesaug = iaa.Lambda(func_images=func_images,func_keypoints=func_keypoints )將每張圖片沒隔兩行的像素點(diǎn)變成黑色的條帶,關(guān)鍵點(diǎn)保留。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-1v7ziLsX-1621334062341)(/img/imgaug/1621331938-3d7ee6949c9fc3215207fc7170f29b20.jpg)]
3.9 iaa.AssertShape()
assert要變換的圖片和keypoint的shape。如果不滿足就拋出異常。
iaa.AssertShape(shape,check_images=True,check_keypoints=True,name=None,deterministic=False,random_state=None)參數(shù):
- shape: 元組,通常形式為(N, H, W, C)。元組中每個元素的值可以為:None, int, 兩個int類型的tuple或者一個int類型的list。如果是None,表示所有值都可以接受。如果是int,則只有對應(yīng)的位置是該值才會被接受。如果是int類型的tuple,例如(a,b),則對應(yīng)位置的值必須是a<=x
3.10 iaa.Scale()
將圖像縮放到固定大小。
iaa.Scale(size,interpolation='cubic',name=None,deterministic=False,random_state=None)參數(shù):
- size: 字符串”keep”,此時保持圖像原大小不坐縮放。如果是一個整數(shù)n,則縮放成(n, n)。如果是一個float v,則每張圖片會被縮放成(H*v, W*v),此時每張圖像大小仍然不一樣。如果是一個tuple類型(a, b), 如果a、b中至少有一個小數(shù),則從[a,b]中挑選一個數(shù)作為縮放比例。如果a、b都是整數(shù),則從[a,b]中挑選一個整數(shù)作為縮放后的大小。如果是1個list,則list中的數(shù)要么全是整數(shù),要么全是小數(shù)(不能混用)。如果是一個dict類型,則該dict必須有兩個key: height和width。每個key的值仍然可以按照上面的方法選取。此外, key的值還可以是”keep-aspect-ratio”, 表示按照比例縮放。
- interpolation: 縮放方法。如果是All, 則會隨機(jī)從下面挑選一個: nearest、linear、area、cubic,注意每張圖片可能不一樣。如果是int,則應(yīng)該是下面的一種:cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_AREA,cv2.INTER_CUBIC。如果是string,則該種方法會被一直使用,必須是下面的一種: nearest, linear, area, cubic。如果是int list或者string list, 則每張圖片會從中隨機(jī)選取一個。
3.11 iaa.CropAndPad()
截取(crop)或者填充(pad),填充時,被填充區(qū)域?yàn)楹谏?/p> 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)
參數(shù):
- px: 想要crop(negative values)的或者pad(positive values)的像素點(diǎn)。注意與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。當(dāng)pad_mode=constant的時候選擇填充的值。
- keep_size: bool類型。經(jīng)過crop后,圖像大小會改變。如果該值設(shè)置為1,則在crop或者pad后再縮放成原來的大小。
- sample_independently : bool類型。如果設(shè)置為False,則每次從px或者percent中選出來的值會作用在四個方位。
3.12 iaa.Pad()
與iaa.CropAndPad()相同,只接受positive values。
3.13 iaa.Crop()
與iaa.CropAndPad()相同,只接受negative values。
3.14 iaa.Fliplr()
水平鏡面翻轉(zhuǎn)。
iaa.Fliplr(p=0, name=None, deterministic=False, random_state=None)參數(shù):
- p: int或者float,每張圖片唄翻轉(zhuǎn)的概率
3.15 Flipud()
上下翻轉(zhuǎn),與上面相同。
3.16 iaa.ChangeColorspace()
改變圖像空間。
iaa.ChangeColorspace(to_colorspace, from_colorspace='RGB', alpha=1.0, name=None, deterministic=False, random_state=None)參數(shù):
- 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)參數(shù):
- alpha: 覆蓋舊的顏色空間時,新顏色空間的Alpha值。
3.18 iaa.GaussianBlur()
高斯擾動。
iaa.GaussianBlur(sigma=0, name=None, deterministic=False, random_state=None)參數(shù):
- sigma: 高斯變換的標(biāo)準(zhǔn)差。可為float, float tuple。常見的有0,不擾動。3,強(qiáng)擾動。
3.19 iaa.AverageBlur()
從最鄰近像素中取均值來擾動。
iaa.AverageBlur(k=1, name=None, deterministic=False, random_state=None)參數(shù):
- k:窗口大小。可為int, int tuple。當(dāng)為int tuple時,如果每個元素也是tuple,每個元素分別作為height和width,窗口大小不一致。
3.20 iaa.MedianBlur()
通過最近鄰中位數(shù)來擾動。
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()
隨機(jī)加上一個值。
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()
給圖像中的每個像素點(diǎn)乘一個值使得圖片更亮或者更暗。
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()
隨機(jī)去掉一些像素點(diǎn), 即把這些像素點(diǎn)變成0。
iaa.Dropout(p=0, per_channel=False, name=None, deterministic=False, random_state=None)3.32 iaa.CoarseDropout()
將矩形框的值設(shè)置為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)、旋轉(zhuǎn)(Rotation)、放縮(zoom)、錯切(shear)。仿設(shè)變換通常會產(chǎn)生一些新的像素點(diǎn),我們需要指定這些新的像素點(diǎn)的生成方法,這種指定通過設(shè)置cval和mode兩個參數(shù)來實(shí)現(xiàn)。參數(shù)order用來設(shè)置插值方法。
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)參數(shù):
- scale: 圖像縮放因子。1表示不縮放,0.5表示縮小到原來的50%。此參數(shù)可以是float, float tuple, dict。如果是float, 則所有圖片按照這種比例縮放。如果是float tuple, 則隨機(jī)選取一個值來進(jìn)行縮放,此時x-axis和y-axis的縮放比例相同。如果是一個dict,則應(yīng)該有兩個key:x, y,每個x或y的值都可以是float, float tuple,此時x-axis和y-axis的縮放比例不一樣。
- translate_percent: 平移比例,0表示不平移,0.5表示平移50%。可以是float, float tuple, dict,具體含義與scale相同。用正負(fù)來表示平移方向。
- translate_px: 按照像素來進(jìn)行平移。可以是int, int tuple, dict,具體含義與translate_percent相同。
- rotate: 平移角度,0~360度之間,正負(fù)也可以表示方向。可以為float, float tuple。
- shear: 錯切的程度,0~360度之間,正負(fù)表示方向。可以為float, int, float tuple, int tuple。
- order: 插值順序,與skimage中定義相同。下面0和1方法快,3比較慢,4、5特別慢。可以是int, int list, ia.ALL。如果是ia.ALL,則每次從所有的插值方法中隨機(jī)選取。
- 0:最鄰近插值。
- 1: 雙線性插值(默認(rèn))。
- 2: 雙二次插值(不推薦)。
- 3:雙三次插值。
- 4: Bi-quartic。
- 5:Bi-quintic。
- cval: 當(dāng)平移后使用常量填充的時候指定填充的常量值,只有在mode=constant的時候才會生效。可以是int, float, tuple, ia.ALL。如果是ia.ALL,則會從[0,255]之間隨機(jī)選取一個值填充。
- mode: 采用何種方式填充經(jīng)過變換后空白的像素點(diǎn)。可以是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()
隨機(jī)放置一些規(guī)則的網(wǎng)格點(diǎn)然后移動這些點(diǎn)的周圍的像素。這回導(dǎo)致局部的扭曲。
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支持在圖像變換的同時變換圖像中的關(guān)鍵點(diǎn)。例子如下:
import imgaug as ia from imgaug import augmenters as iaaiaa.seed(1)image=ia.quokka(size=(256,256))# 定義4個關(guān)鍵點(diǎn) 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)), # 改變亮度,不影響關(guān)鍵點(diǎn)iaa.Affine(rotate=10,scale=(0.5, 0.7)) # 旋轉(zhuǎn)10度然后縮放,會影響關(guān)鍵點(diǎn) ])# 固定變換序列,之后就可以先變換圖像然后變換關(guān)鍵點(diǎn),這樣可以保證兩次的變換完全相同。 # 如果調(diào)用次函數(shù),需要在每次batch的時候都調(diào)用一次,否則不同的batch執(zhí)行相同的變換。 seq_det = seq.to_deterministic()# 轉(zhuǎn)換成list或者batch來變換。由于只有一張圖片, 因此用[0]來取出該圖和關(guān)鍵點(diǎn)。 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))# 將關(guān)鍵點(diǎn)畫在圖片上。 # 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進(jìn)行變換
- 將bounding box畫在圖像上
- 移動bounding box的位置,將變換后的bounding box映射到圖像上,計算bounding box的IoU。
5.1 基本變換
例子如下:
import imgaug as ia from imgaug import augmenters as iaaia.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 boxiaa.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]# 打印坐標(biāo) # 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
調(diào)用shift函數(shù)即可。
import imgaug as ia from imgaug import augmenters as iaaia.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)得到的圖像為:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-eWwQmj92-1621334062344)(/img/imgaug/1621331938-01a26f5d29055cb83709b34efa0802eb.jpg)]
5.3 圖像有縮放時bounding box的映射
調(diào)用on函數(shù)即可。
import imgaug as ia from imgaug import augmenters as iaaia.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 npia.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 )得到的圖像如下:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Ez6LnQ9r-1621334062346)(/img/imgaug/1621331938-fd161c36361e9c2e8f1d4c8a9f37b22d.jpg)]
6. Stochastic Parameter
在做變換的時候,我們希望每張圖片的變換都不一樣,通過參數(shù)隨機(jī)化選取可以實(shí)現(xiàn)。但是想要復(fù)現(xiàn)之前的變換,需要通過determinism來實(shí)現(xiàn),比較繁瑣。為了避免這種情況,使用Stochastic Parameters來實(shí)現(xiàn)。這個變量通常是一個抽象的概率分布,例如正太分布、均勻分布等等。通常所有的augmenter都能接受這個參數(shù),這樣就很方便控制變量范圍。他們都可以和determinism結(jié)合。
例子:
from imgaug import augmenters as iaa from imgaug import parameters as iapseq = 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 正態(tài)分布
Normal(loc, scale): 均值為loc,標(biāo)準(zhǔn)差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)[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Y99ms8sd-1621334062356)(/img/imgaug/1621331938-dbbb6ac5efb90a1424b5781513c72330.jpg)]
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)[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-JQmL3Fl2-1621334062358)(/img/imgaug/1621331938-7e1866ebd7cde4503ac363bec5a07cce.jpg)]
6.3 其他連續(xù)概率分布還有:
- 卡方分布(ChiSquare)
- 韋伯分布(Weibull)
- 均勻分布(Uniform )
- Beta分布
6.4 離散概率分布
- 二項(xiàng)分布(Binomial)
- 離散均勻分布(DiscreteUniform)
- 泊松分布(Poisson distribution)
6.5 對分布的數(shù)學(xué)運(yùn)算
imgaug支持隨機(jī)參數(shù)的算術(shù)運(yùn)算。 允許修改從分布中抽取的值或者將幾個分布相互組合。支持的操作有:
- Add
- Subtract
- Multiply
- Divide
- Power
6.6 特殊參數(shù)
支持的操作有:
- Deterministic
- Choice
- Clip
- Discretize
- Absolute
- RandomSign
- ForceSign
- Positive
- Negative
- FromLowerResolution
具體含義和用法見文檔。
7. Blending/Overlaying images
augment會直接改變圖片而把原圖舍棄掉了。有時我們需要改變圖像的局部,或者將原來的圖片跟新變換的圖片結(jié)合起來。這可以通過給變換前后的圖片配上一定的權(quán)重(αα參數(shù))或者使用一個pixel-wise的mask。
一個例子如下:
得到的圖片為:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-En1fXAVL-1621334062359)(/img/imgaug/1621331938-ec2ecb79a733cfd85deafb1086e2e6b9.png)]
具體用法見文檔。
總結(jié)
以上是生活随笔為你收集整理的Python 第三方模块之 imgaug (图像增强)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CAD卸载方法,如何完全彻底卸载删除清理
- 下一篇: Python 第三方库之 Celery