單尺度訓(xùn)練
train_pipeline = [
......
dict(
type='Resize',
img_scale=(1333, 800),
keep_ratio=True),
......
dict(type='Pad', size_divisor=32),
]
max_long_edge = max(img_scale)
max_short_edge = min(img_scale)# 取值方式: 大值/長邊 小值/短邊 誰的比值小 按誰來計算縮放比例
scale_factor = min(max_long_edge / max(h, w), max_short_edge / min(h, w))
假設(shè)我的真實圖片大小是(400, 600),那么按照上面的方式1333/600 = 2.22, 800/400=2,顯然,按照800的縮放系數(shù)更小,因此以800的縮放系數(shù)為基準(zhǔn)resize。那么就有(4002, 6002) -> (800, 1200) ,此時shape(400, 600)的圖片,被resize成了 (800, 1200),這樣操作的好處是圖片在被resize的同時,盡量靠近原圖的大小。
pad_h = int(np.ceil(img.shape[0] / divisor)) * divisor
pad_w = int(np.ceil(img.shape[1] / divisor)) * divisor
經(jīng)過pad操作之后,將(800,1200)變成了(800, 1216),這步操作的目的是避免卷積時,特征損失。
keep_ratio=False時,直接按照config配置中的img_scale來縮放圖片,大值代表長邊,小值代表短邊,不會保持原有圖片比例。
多尺度訓(xùn)練
train_pipeline = [
......
dict(
type='Resize',
img_scale=[(1333, 640), (1333, 800), (600,1080), (1200, 1000), (416,700)],
multiscale_mode='value',
# multiscale_mode='range',
keep_ratio=True),
......
]
value模式相當(dāng)于隨機去一個作為img_scale
elif self.multiscale_mode == 'range':
scale, scale_idx = self.random_sample(self.img_scale)
def random_select(img_scales):
assert mmcv.is_list_of(img_scales, tuple)
scale_idx = np.random.randint(len(img_scales))
img_scale = img_scales[scale_idx]
return img_scale, scale_idx
range模式比較常用,我們一般長邊放開,短邊取個范圍,比如400~800,就是[(1333, 400), (1333, 800)]
elif self.multiscale_mode == 'value':
scale, scale_idx = self.random_select(self.img_scale)
def random_sample(img_scales):
assert mmcv.is_list_of(img_scales, tuple) and len(img_scales) == 2
img_scale_long = [max(s) for s in img_scales]
img_scale_short = [min(s) for s in img_scales]
long_edge = np.random.randint(
min(img_scale_long),
max(img_scale_long) + 1)
short_edge = np.random.randint(
min(img_scale_short),
max(img_scale_short) + 1)
img_scale = (long_edge, short_edge)
return img_scale, None
從以上源代碼可以看出最終的長邊是類似range(1333, 1333),短邊是range(400, 800)
單尺度測試
和單尺度訓(xùn)練一樣
多尺度測試
可參考 https://github.com/open-mmlab/mmdetection/issues/135
test_pipeline = [
......
dict(
type='Resize',
img_scale=[(1333, 640), (1333, 800), (600,1080), (1200, 1000), (416,700)],
multiscale_mode='value',
keep_ratio=True),
......
]
此時就不是隨機選取了,是依次選取的,
選取策略
如果不是特殊情況,train和test都這么設(shè)置,這么設(shè)置是因為一般圖片都是矩形,且圖片大的話對小目標(biāo)有增益,因此短邊可以給幾個和數(shù)據(jù)集短邊差不多的值,可以偏大點,但考慮到train的速度,600到 800比較合適,coco上基本上長邊取1333,如果數(shù)據(jù)集比較很長 沒有極端長寬比,也可以長邊設(shè)為很大比如2000,起到長邊不固定的效果。
img_scale=[(1333, 640), (1333, 672), (1333, 704), (1333, 736),
(1333, 768), (1333, 800)],
multiscale_mode='value'