Pytorch機器學習(六)——YOLOV5中的自適應圖片縮放letterbox
目錄
Pytorch機器學習(六)——YOLOV5中的自適應圖片縮放letterbox
前言
一、letterbox自適應圖片縮放技術
一,計算收縮比
二,計算收縮后圖片的長寬
三,計算需要填充的像素
四,最后resize圖片并填充像素
二、代碼總和
二、使用步驟
1.引入庫
2.讀入資料
總結
前言
YOLOV5中相比于之前的版本,有很多小trick,導致其性能和應用比較好,本文先講講在將圖片輸入網路前,對圖片進行預處理的letterbox的自適應圖片縮放技術
一、letterbox自適應圖片縮放技術
在目標檢測中,輸入的圖片尺寸有大有小,根據前人的實驗結果,輸入網路的尺寸統一縮放到同一個尺寸時,檢測效果會更好(train中放入的圖片并不經過letterbox,而是檢測的時候使用letterbox)
但這時就有個問題,如果是簡單的使用resize,就會造成圖片的失真,所以提出了letterbox自適應圖片縮放技術,
下圖即是經過letterbox處理的圖片,圖片被resize到640*640,且通過的是灰邊來補齊缺邊,很好的保留了圖片的特征,


而其實letterbox的實作也十分簡單,以下將結合代碼講解步驟(下面所有的例子都以縮放到640*640為例,
一,計算收縮比
shape = im.shape[:2] # current shape [height, width]
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
這里的收縮比取的是長寬方向上變化范圍最小的一個,
二,計算收縮后圖片的長寬
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
三,計算需要填充的像素
這里其實就是在計算那個需要收縮比大的那一邊需要填充的像素
# 計算需要填充的邊的像素
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]
# stride表示的即是模型下采樣次數的2的次方,這個涉及感受野的問題,在YOLOV5中下采樣次數為5
# 則stride為32
dw, dh = np.mod(dw, stride), np.mod(dh, stride)
dw /= 2 # 除以2即最終每邊填充的像素
dh /= 2
四,最后resize圖片并填充像素
if shape[::-1] != new_unpad: # resize
im = cv.resize(im, new_unpad, interpolation=cv.INTER_LINEAR)
# round(dw,dh - 0.1)直接讓小于1的為0
top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
# 添加灰邊
im = cv.copyMakeBorder(im, top, bottom, left, right, cv.BORDER_CONSTANT, value=color)
二、代碼總和
def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, stride=32):
# Resize and pad image while meeting stride-multiple constraints
shape = im.shape[:2] # current shape [height, width]
if isinstance(new_shape, int):
new_shape = (new_shape, new_shape)
# Scale ratio (new / old)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
# Compute padding
ratio = r, r # width, height ratios
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding
if auto: # minimum rectangle
dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding
dw /= 2 # divide padding into 2 sides
dh /= 2
print(dw, dh)
if shape[::-1] != new_unpad: # resize
im = cv.resize(im, new_unpad, interpolation=cv.INTER_LINEAR)
top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
im = cv.copyMakeBorder(im, top, bottom, left, right, cv.BORDER_CONSTANT, value=color) # add border
return im, ratio, (dw, dh)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297412.html
標籤:AI
