Interp的算法简单来说就是用源图的四个点分别与各自的权重相乘然后再相加得到目标图片的一个值。所以这个算法的关键点有两个:
: ^" M7 K8 _% T" \$ t1. 源图4个像素点的选择;
; Q" |! I2 k. H: I) d$ Y4 n! j
2. 与4个像素点相乘的权重的计算。
8 S6 s* ]( ?& V
实际上,无论是像素点的选择还是权重的计算都依赖源图片和目标图片长和宽像素点的比例关系。根据源图片和目标图片的比例关系可以先算出一个基础系数(Base_Parameter)。但这并不意味着一个2*2的图片扩大成4*4的图片,比例系数就由2/4直接得到,因为双线性插值的的点是指的每个像素点的中心点的值,如下图所示。
& V. W8 _& x4 R, B8 }; h
$ C" v( b+ {* T8 }3 Y
所以实际的比例关系计算应该是中心点距离的总和之间的比例关系,也就是像素点减一之后的比例关系。还是举例说明的话,2*2的图片扩大成4*4的图片应该就是(2-1)/(4-1)这样来得出比例关系。为了证明这个推导的正确性,下面是caffe里面interp层的c++代码,可以从图中看到的是选择像素点的代码,确实是需要进行减一操作的。
: U, b o% Q" O. q) L
; n. g; h6 B; S# D' D1 S
关键点1 像素点选择
3 L6 [' x b4 L, p' q9 R用3*3扩大成4*4的例子来举例说明。根据上面推导出的公式可以得到这个过程中的基础比例系数是(3-1)/(4-1)=0.67。如下图所示,目标图片的第二行第二列的点是由1,2,4,5四个点计算的。因为此时,选择像素点行的参数为0.67*1=0.67没有超过1且选择像素点水平方向和垂直方向的参数为0.67*1=0.67没有超过1。所以,参与计算的源图片像素点。
9 a* Q" S% H! |% i- E: g& ]
是最左最上的2*2矩阵。到计算目标图片的第二行第三列数时,水平方向的参数为0.67*2=1.34,这个值超过了1,所以源图片水平2*2的矩阵要向右移动一个像素的位置。而垂直方向的参数还是0.67,故而垂直方向无需移动。参与运算的数就从1、2、4、5变为了2、3、5、6。
9 C, D z% F. ^, e; |" |" k+ V
9 f n1 [+ `' S
关键点2 权重计算
8 p5 B7 _4 J. w1 h6 Z* @3 q5 I
还是用3*3扩大成4*4的例子来举例说明。现在需要计算0Base下(1,1)的数,也就是图中黄色的像素点。由于它的行坐标和列坐标都为1,所以这层的计算参数需要分别将行和列的基础系数乘1得到,也就是行为0.67,列为0.67。具体计算过程为1*(1-0.67)*(1-0.67) + 2*0.67(1-0.67) + 4*(1-0.67)*0.67 +5*0.67*0.67。其中红字的部分就是权重的计算过程。
, o4 J& ~0 w1 e小结:
9 y5 U$ @/ p* W# }3 r& c. U \
1. 根据输入输出分辨率计算出基础系数。
; w, s/ i3 @/ }( j9 ?4 v2. 根据需要计算的像素点位置计算出计算参数。
7 z. q6 T* |* ~2 d. v$ M
3. 计算参数的整数部分作为index去选择像素点,小数部分作为权重去计算。
8 L! ~6 | ^8 `/ v' e7 k3 H# F+ R+ @2 Y7 S+ B1 A& _$ ?# c
- U7 e& R9 R+ | O" [