python目標(biāo)檢測(cè)數(shù)據(jù)增強(qiáng)的代碼參數(shù)解讀及應(yīng)用
數(shù)據(jù)增強(qiáng)做了什么
數(shù)據(jù)增強(qiáng)是非常重要的提高目標(biāo)檢測(cè)算法魯棒性的手段,學(xué)習(xí)一下對(duì)身體有好處!
數(shù)據(jù)增強(qiáng)其實(shí)就是讓圖片變得更加多樣。比如說原圖是一個(gè)電腦
如果不使用數(shù)據(jù)增強(qiáng)的話這個(gè)電腦就只是一個(gè)電腦,每次訓(xùn)練的電腦都是這樣的樣子的,但是我們實(shí)際生活中電腦是多樣的。
因此我們可以通過改變亮度,圖像扭曲等方式使得圖像變得更加多種多樣,如下圖所示,盡管亮度,形態(tài)發(fā)生了細(xì)微改變,但本質(zhì)上,這些東西都依然是電腦。
改變后的圖片放入神經(jīng)網(wǎng)絡(luò)進(jìn)行訓(xùn)練可以提高網(wǎng)絡(luò)的魯棒性,降低各方面額外因素對(duì)識(shí)別的影響。
目標(biāo)檢測(cè)中的圖像增強(qiáng)
在目標(biāo)檢測(cè)中如果要增強(qiáng)數(shù)據(jù),并不是直接增強(qiáng)圖片就好了,還要考慮到圖片扭曲后框的位置。
也就是框的位置要跟著圖片的位置進(jìn)行改變。
如果大家對(duì)我的目標(biāo)檢測(cè)代碼有少許研究的話,應(yīng)該都可以看到。我特別喜歡用這個(gè)數(shù)據(jù)增強(qiáng)代碼:
def get_random_data(annotation_line, input_shape, random=True, max_boxes=20, jitter=.5, hue=.1, sat=1.5, val=1.5, proc_img=True): '''random preprocessing for real-time data augmentation''' line = annotation_line.split() image = Image.open(line[0]) iw, ih = image.size h, w = input_shape box = np.array([np.array(list(map(int,box.split(',')))) for box in line[1:]]) # 對(duì)圖像進(jìn)行縮放并且進(jìn)行長(zhǎng)和寬的扭曲 new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter) scale = rand(.25, 2) if new_ar < 1: nh = int(scale*h) nw = int(nh*new_ar) else: nw = int(scale*w) nh = int(nw/new_ar) image = image.resize((nw,nh), Image.BICUBIC) # 將圖像多余的部分加上灰條 dx = int(rand(0, w-nw)) dy = int(rand(0, h-nh)) new_image = Image.new('RGB', (w,h), (128,128,128)) new_image.paste(image, (dx, dy)) image = new_image # 翻轉(zhuǎn)圖像 flip = rand()<.5 if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT) # 色域扭曲 hue = rand(-hue, hue) sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat) val = rand(1, val) if rand()<.5 else 1/rand(1, val) x = rgb_to_hsv(np.array(image)/255.) x[..., 0] += hue x[..., 0][x[..., 0]>1] -= 1 x[..., 0][x[..., 0]<0] += 1 x[..., 1] *= sat x[..., 2] *= val x[x>1] = 1 x[x<0] = 0 image_data = hsv_to_rgb(x) # numpy array, 0 to 1 # 將box進(jìn)行調(diào)整 box_data = np.zeros((max_boxes,5)) if len(box)>0: np.random.shuffle(box) box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy if flip: box[:, [0,2]] = w - box[:, [2,0]] box[:, 0:2][box[:, 0:2]<0] = 0 box[:, 2][box[:, 2]>w] = w box[:, 3][box[:, 3]>h] = h box_w = box[:, 2] - box[:, 0] box_h = box[:, 3] - box[:, 1] box = box[np.logical_and(box_w>1, box_h>1)] # discard invalid box if len(box)>max_boxes: box = box[:max_boxes] box_data[:len(box)] = box return image_data, box_data
里面有一些比較重要的參數(shù)如:
scale = rand(.25, 2)jitter=.5;hue=.1;sat=1.5;val=1.5;
其中:
1、scale代表原圖片的縮放比率,rand(.25, 2)表示在0.25到2之間縮放。
2、jitter代表原圖片的寬高的扭曲比率,jitter=.5表示在0.5到1.5之間扭曲。
3、hue=.1,sat=1.5,val=1.5;分別代表hsv色域中三個(gè)通道的扭曲,分別是:色調(diào)(H),飽和度(S),明度(V)。
實(shí)際效果如下:
原圖:
增強(qiáng)后:
全部代碼
全部代碼構(gòu)成如下:
from PIL import Image, ImageDraw import numpy as np from matplotlib.colors import rgb_to_hsv, hsv_to_rgb def rand(a=0, b=1): return np.random.rand()*(b-a) + a def get_random_data(annotation_line, input_shape, random=True, max_boxes=20, jitter=.5, hue=.1, sat=1.5, val=1.5, proc_img=True): '''random preprocessing for real-time data augmentation''' line = annotation_line.split() image = Image.open(line[0]) iw, ih = image.size h, w = input_shape box = np.array([np.array(list(map(int,box.split(',')))) for box in line[1:]]) # 對(duì)圖像進(jìn)行縮放并且進(jìn)行長(zhǎng)和寬的扭曲 new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter) scale = rand(.25,2) if new_ar < 1: nh = int(scale*h) nw = int(nh*new_ar) else: nw = int(scale*w) nh = int(nw/new_ar) image = image.resize((nw,nh), Image.BICUBIC) # 將圖像多余的部分加上灰條 dx = int(rand(0, w-nw)) dy = int(rand(0, h-nh)) new_image = Image.new('RGB', (w,h), (128,128,128)) new_image.paste(image, (dx, dy)) image = new_image # 翻轉(zhuǎn)圖像 flip = rand()<.5 if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT) # 色域扭曲 hue = rand(-hue, hue) sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat) val = rand(1, val) if rand()<.5 else 1/rand(1, val) x = rgb_to_hsv(np.array(image)/255.) x[..., 0] += hue x[..., 0][x[..., 0]>1] -= 1 x[..., 0][x[..., 0]<0] += 1 x[..., 1] *= sat x[..., 2] *= val x[x>1] = 1 x[x<0] = 0 image_data = hsv_to_rgb(x) # numpy array, 0 to 1 # 將box進(jìn)行調(diào)整 box_data = np.zeros((max_boxes,5)) if len(box)>0: np.random.shuffle(box) box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy if flip: box[:, [0,2]] = w - box[:, [2,0]] box[:, 0:2][box[:, 0:2]<0] = 0 box[:, 2][box[:, 2]>w] = w box[:, 3][box[:, 3]>h] = h box_w = box[:, 2] - box[:, 0] box_h = box[:, 3] - box[:, 1] box = box[np.logical_and(box_w>1, box_h>1)] # discard invalid box if len(box)>max_boxes: box = box[:max_boxes] box_data[:len(box)] = box return image_data, box_data def normal_(annotation_line, input_shape): '''random preprocessing for real-time data augmentation''' line = annotation_line.split() image = Image.open(line[0]) box = np.array([np.array(list(map(int,box.split(',')))) for box in line[1:]]) return image, box if __name__ == "__main__": with open("2007_train.txt") as f: lines = f.readlines() a = np.random.randint(0,len(lines)) line = lines[a] image_data, box_data = normal_(line,[416,416]) img = image_data for j in range(len(box_data)): thickness = 3 left, top, right, bottom = box_data[j][0:4] draw = ImageDraw.Draw(img) for i in range(thickness): draw.rectangle([left + i, top + i, right - i, bottom - i],outline=(255,255,255)) img.show() image_data, box_data = get_random_data(line,[416,416]) print(box_data) img = Image.fromarray((image_data*255).astype(np.uint8)) for j in range(len(box_data)): thickness = 3 left, top, right, bottom = box_data[j][0:4] draw = ImageDraw.Draw(img) for i in range(thickness): draw.rectangle([left + i, top + i, right - i, bottom - i],outline=(255,255,255)) img.show() # img = Image.open(r"F:\Collection\yolo_Collection\keras-yolo3-master\Mobile-yolo3-master/VOCdevkit/VOC2007/JPEGImages/00000.jpg") # left, top, right, bottom = 527,377,555,404 # draw = ImageDraw.Draw(img) # draw.rectangle([left, top, right, bottom]) # img.show()
以上就是python目標(biāo)檢測(cè)數(shù)據(jù)增強(qiáng)的代碼參數(shù)解讀及應(yīng)用的詳細(xì)內(nèi)容,更多關(guān)于python數(shù)據(jù)增強(qiáng)參數(shù)解讀的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python對(duì)圖片進(jìn)行resize、裁剪、旋轉(zhuǎn)、翻轉(zhuǎn)問題
這篇文章主要介紹了Python對(duì)圖片進(jìn)行resize、裁剪、旋轉(zhuǎn)、翻轉(zhuǎn)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05妙用itchat! python實(shí)現(xiàn)久坐提醒功能
python編寫的久坐提醒,給最愛的那個(gè)她,這篇文章主要為大家分享了python久坐提醒功能的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11python使用docx模塊讀寫docx文件的方法與docx模塊常用方法詳解
這篇文章主要介紹了python使用docx模塊讀寫docx文件的方法與docx模塊常用方法詳解,需要的朋友可以參考下2020-02-02Python中導(dǎo)入自定義模塊的幾種方法總結(jié)
這篇文章主要介紹了Python中導(dǎo)入自定義模塊的幾種方法總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01Jupyter notebook 更改文件打開的默認(rèn)路徑操作
這篇文章主要介紹了Jupyter notebook 更改文件打開的默認(rèn)路徑操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-05-05安裝pytorch報(bào)錯(cuò)torch.cuda.is_available()=false問題的解決過程
最近想用pytorch,因此裝了pytorch,但是碰到了問題,下面這篇文章主要給大家介紹了關(guān)于安裝pytorch報(bào)錯(cuò)torch.cuda.is_available()=false問題的解決過程,需要的朋友可以參考下2022-05-05Python圖像運(yùn)算之圖像點(diǎn)運(yùn)算與灰度化處理詳解
這篇文章主要介紹了圖像點(diǎn)運(yùn)算的灰度化處理的相關(guān)知識(shí),包括各種灰度算法的實(shí)現(xiàn),以及灰度線性變換和灰度非線性變換。需要的可以參考一下2022-02-02python腳本監(jiān)聽域名證書過期時(shí)間并通知消息到釘釘(最新推薦)
這篇文章主要介紹了python腳本監(jiān)聽域名證書過期時(shí)間并通知消息到釘釘(最新推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-11-11