訓練Object Detection模型SSD完畢之后進入test階段,每張圖像在進入輸入層之前需要進行resize操作,以滿足CNN模型對輸入層size的要求。本文首先介紹了Caffe實現的SSD模型對輸入圖像的變換規定,引出了OpenCV中的resize
方法,最后介紹該方法中的插值參數cv.INTER_LINEAR
和該插值方法的原理。
caffe_ssd
caffe_ssd在test階段,對圖像的變換設置如下:
test_transform_param = {
'mean_value': [104, 117, 123],
'force_color': True,
'resize_param': {
'prob': 1,
'resize_mode': P.Resize.WARP,
'height': resize_height,
'width': resize_width,
'interp_mode': [P.Resize.LINEAR],
},
}
以上設定來自ssd_coco.py。
-
'mean_value': [104, 117, 123]
是ImageNet圖像BGR
三個通道的均值。每張圖像分別需要減去相應通道的均值,實現中心化。 -
'force_color': True
強制采用彩色BGR
圖像模式,防止灰度圖像維度與SSD模型輸入層維度不一致。 -
resize_param
屬性在caffe.proto的ResizeParameter中有說明
其中的// Message that stores parameters used by data transformer for resize policy message ResizeParameter { //Probability of using this resize policy optional float prob = 1 [default = 1]; enum Resize_mode { WARP = 1; FIT_SMALL_SIZE = 2; FIT_LARGE_SIZE_AND_PAD = 3; } optional Resize_mode resize_mode = 2 [default = WARP]; optional uint32 height = 3 [default = 0]; optional uint32 width = 4 [default = 0]; // A parameter used to update bbox in FIT_SMALL_SIZE mode. optional uint32 height_scale = 8 [default = 0]; optional uint32 width_scale = 9 [default = 0]; enum Pad_mode { CONSTANT = 1; MIRRORED = 2; REPEAT_NEAREST = 3; } // Padding mode for BE_SMALL_SIZE_AND_PAD mode and object centering optional Pad_mode pad_mode = 5 [default = CONSTANT]; // if specified can be repeated once (would fill all the channels) // or can be repeated the same number of times as channels // (would use it them to the corresponding channel) repeated float pad_value = 6; enum Interp_mode { //Same as in OpenCV LINEAR = 1; AREA = 2; NEAREST = 3; CUBIC = 4; LANCZOS4 = 5; } //interpolation for for resizing repeated Interp_mode interp_mode = 7; }
interp_mode
采用LINEAR模式對圖像進行Resize操作,與Opencv中的resize一致。
接下來,我們具體介紹一下OpenCV中的resize
方法。
resize方法的簽名
C++:
void cv::resize (InputArray src,
OutputArray dst,
Size dsize,
double fx = 0,
double fy = 0,
int interpolation = INTER_LINEAR
)
Python:
dst = cv.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
參數說明:
src 輸入圖像.
dst 輸出圖像; 其size為dsize,或由src.size()、fx與fy計算而得; dst類型與src保持一致.
dsize 輸出圖像的size; 如果設為0,或(0, 0), 計算方式為:
?????????? = ????????(??????????(????*??????.????????), ??????????(????*??????.????????))
dsize和(fx, fy)必須有一組不為0. 如果都為0,無法確定被resize后的圖像大小
fx 水平軸縮放因子; 等于0時,計算方式為:
(????????????)??????????.??????????/??????.????????
fy 豎直軸縮放因子; 等于0時,計算方式為:
(????????????)??????????.????????????/??????.????????
interpolation 差值方法, 方法見InterpolationFlags
InterpolationFlags
縮小圖像時,一般INTER_AREA
插值效果較好。放大圖像時, INTER_CUBIC
(slow)更好些,或INTER_LINEAR
(faster but still looks OK)。
Resize Image Example
import cv2 as cv
img = cv.imread('./lena.jpg')
h, w = img.shape[:2]
# 縮小圖像到原來一半大小,方法一,設置dsize
dst = cv.resize(img, (h//2, w//2), None, 0, 0, cv.INTER_LINEAR)
cv.imwrite('./lena1.jpg', dst)
# 縮小圖像到原來一半大小,方法二,設置fx和fy
dst = cv.resize(src=img, dsize=None, fx=0.5, fy=0.5, interpolation=cv.INTER_LINEAR)
cv.imwrite('./lena2.jpg', dst)
cv.INTER_LINEAR的原理
resize
方法提供了9種插值參數,Caffe中支持的5種分別是
- 最近鄰插值法 cv.INTER_NEAREST
- 雙線性插值法 cv.INTER_LINEAR
- 雙三次插值法 cv.INTER_CUBIC
- 區域插值法 cv.INTER_AREA
- 蘭索斯插值法 cv.INTER_LANCZOS4
下面具體介紹一下雙線性插值法
,這種插值方法最易于理解,也應用最多。
x軸方向線性插值
y軸方向線性插值
雙線性插值的矩陣變換表達