python目標檢測數(shù)據(jù)增強的代碼參數(shù)解讀及應用
數(shù)據(jù)增強做了什么
數(shù)據(jù)增強是非常重要的提高目標檢測算法魯棒性的手段,學習一下對身體有好處!
數(shù)據(jù)增強其實就是讓圖片變得更加多樣。比如說原圖是一個電腦

如果不使用數(shù)據(jù)增強的話這個電腦就只是一個電腦,每次訓練的電腦都是這樣的樣子的,但是我們實際生活中電腦是多樣的。
因此我們可以通過改變亮度,圖像扭曲等方式使得圖像變得更加多種多樣,如下圖所示,盡管亮度,形態(tài)發(fā)生了細微改變,但本質(zhì)上,這些東西都依然是電腦。

改變后的圖片放入神經(jīng)網(wǎng)絡進行訓練可以提高網(wǎng)絡的魯棒性,降低各方面額外因素對識別的影響。
目標檢測中的圖像增強
在目標檢測中如果要增強數(shù)據(jù),并不是直接增強圖片就好了,還要考慮到圖片扭曲后框的位置。
也就是框的位置要跟著圖片的位置進行改變。
如果大家對我的目標檢測代碼有少許研究的話,應該都可以看到。我特別喜歡用這個數(shù)據(jù)增強代碼:
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:]])
# 對圖像進行縮放并且進行長和寬的扭曲
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進行調(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色域中三個通道的扭曲,分別是:色調(diào)(H),飽和度(S),明度(V)。
實際效果如下:
原圖:

增強后:

全部代碼
全部代碼構(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:]])
# 對圖像進行縮放并且進行長和寬的扭曲
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進行調(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目標檢測數(shù)據(jù)增強的代碼參數(shù)解讀及應用的詳細內(nèi)容,更多關(guān)于python數(shù)據(jù)增強參數(shù)解讀的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Django中日期時間型字段進行年月日時分秒分組統(tǒng)計
這篇文章主要介紹了Django中日期時間型字段進行年月日時分秒分組統(tǒng)計,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11
Python使用Flask結(jié)合DeepSeek開發(fā)(實現(xiàn)代碼)
文章介紹了如何使用ollama部署DeepSeek大模型,并通過Python Flask和SSE技術(shù)實現(xiàn)一個簡單的對話應用,代碼實現(xiàn)了模型的調(diào)用和結(jié)果展示,并討論了SSE不支持POST請求的問題及解決方案,感興趣的朋友一起看看吧2025-02-02
python使用pandas讀取json文件并進行刷選導出xlsx文件的方法示例
這篇文章主要介紹了python使用pandas讀取json文件并進行刷選導出xlsx文件的方法,結(jié)合實例形式分析了python調(diào)用pandas模塊針對json數(shù)據(jù)操作的相關(guān)使用技巧,需要的朋友可以參考下2023-06-06

