1. RoIAlign的产生背景
首先设想一个场景,假设从一个图像中锚定了一个人的边界框
图1 锚定一个目标人物的边界框
这个时候,要提取边界框中的人的特征,显然应该用 CNN 网络来做这个工作。CNN 处理之后会形成一个特征图。按照一般的处理方式,会使用 RoI Pooling 来缩小特征图的尺寸。但是在 Mask-RCNN 中提出了一个 RoIAlign 的方式,使得得到的小特征图可以更加的精确和信息完整。
2. RoI Pooling
举例来说,如果我们现在得到了一个特征图,特征图尺寸是
5
×
7
5×7
5×7,要求将此区域缩小为
2
×
2
2×2
2×2。此时,因为
5
/
2
=
2.5
{5}/{2}=2.5
5/2=2.5,是个非整数,所以此时系统会对其进行取整的分割,即将 “
5
5
5 ”分割成 “
3
+
2
3+2
3+2 ”,将 “
7
7
7 ” 分割成 “
3
+
4
3+4
3+4 ”,然后取每个区域的最大值作为本区域的值,整个过程如下所示:
图2 整个RoI Pooling 的过程
3. RoI Align
可以知道,使用 R o I P o o l i n g RoI Pooling RoIPooling 存在一个很大的问题:
- 很粗糙地选用了一个值来代替一个区域的值,而且每个区域的尺寸还有很大的差距。
R
o
I
A
l
i
g
n
RoI Align
RoIAlign 的过程如下:
图3 整个RoI Align 的过程
- 因为最终要将这个
5
×
7
5×7
5×7 的特征图处理成
2
×
2
2×2
2×2 的特征图。所以先将要进行
R
o
I
A
l
i
g
n
RoI Align
RoIAlign 的过程转换成
2
×
2
2×2
2×2 个相同规模的范围,这个过程中不做任何量化处理。
- 将这
4
4
4 个模块(①,②,③,④)内部同样进行这样的处理,再细分成
4
4
4 个规模相同的区域(图中虚线表示)。
- 然后对于每一个最小的区域(包含不止一个像素点)确定其中心点(图中的红色
×
×
× )然后使用双线性插值法得到这个
×
×
× 号所在位置的值作为 最小格子区域 的值。
- 对于每一个 小区域(①,②,③,④)都会有 4 4 4 个这样的值,把这 4 4 4 个值取他们的最大值作为每个 小区域(①,②,③,④) 的值。这样最终就可以得到 4 4 4 个小区域的 4 4 4 个值,作为最终的特征图输出结果。
R o I A l i g n RoI Align RoIAlign 提出的这种方式可以避免过程中丢失原特征图的信息,中间过程全程不量化来保证最大的信息完整性。
4. 双线性插值
双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。
首先确定几个量:
- 四个像素点 Q 11 , Q 12 , Q 21 , Q 22 Q_{11}, Q_{12},Q_{21},Q_{22} Q11,Q12,Q21,Q22
- 他们的坐标分别是 ( x 1 , y 1 ) , ( x 1 , y 2 ) , ( x 2 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_1,y_2),(x_2,y_1),(x_2,y_2) (x1,y1),(x1,y2),(x2,y1),(x2,y2)
- 他们的像素值分别是 f ( Q 11 ) , f ( Q 12 ) , f ( Q 21 ) , f ( Q 22 ) f(Q_{11}),f(Q_{12}),f(Q_{21}),f(Q_{22}) f(Q11),f(Q12),f(Q21),f(Q22)
- 横向插值插入的两个点 R 1 , R 2 R_1,R_2 R1,R2,其坐标分别为 ( x , y 1 ) , ( x , y 2 ) (x,y_1),(x,y_2) (x,y1),(x,y2)
- 纵向插值插入的一个点
P
P
P,其坐标是
(
x
,
y
)
(x,y)
(x,y)
插值的目的:
图像扩展,由已知的像素点的值来计算出来原本不存在的像素点。当然你也可以把扩展的地方的像素全部用 0 0 0 来表示,但是看起来是一种不太聪明的做法,会让像素的质量下降的很厉害。所以为了尽可能的让扩展的像素不太过于偏离原图像,使用插值的方式。
插值的方法:
- 先横向插,再纵向插
- 先纵向插,再横向插
计算过程:
-
首先来计算横向的插值,由 Q 22 , Q 12 Q_{22},Q_{12} Q22,Q12 得到 R 2 R_2 R2 的过程:
f ( Q 22 ) − f ( Q 12 ) x 2 − x 1 ≈ f ( Q 22 ) − f ( R 2 ) x 2 − x \frac{f(Q_{22})-f(Q_{12})}{x_2-x_1} \approx\frac{f(Q_{22})-f(R_2)}{x_2-x} x2−x1f(Q22)−f(Q12)≈x2−xf(Q22)−f(R2)
交叉相乘:
( f ( Q 22 ) − f ( Q 12 ) ) × ( x 2 − x ) ≈ ( f ( Q 22 ) − f ( R 2 ) ) × ( x 2 − x 1 ) ({f(Q_{22})-f(Q_{12})})×(x_2-x)\approx({f(Q_{22})-f(R_{2})})×(x_2-x_1) (f(Q22)−f(Q12))×(x2−x)≈(f(Q22)−f(R2))×(x2−x1)
化简一下:
f ( R 2 ) ≈ x 2 − x x 2 − x 1 f ( Q 12 ) + x − x 1 x 2 − x 1 f ( Q 22 ) f(R_{2}) \approx \frac{x_2-x}{x_2-x_1}f(Q_{12})+\frac{x-x_1}{x_2-x_1}f(Q_{22}) f(R2)≈x2−x1x2−xf(Q12)+x2−x1x−x1f(Q22)
-
同样地,计算横向插值,由 Q 11 , Q 21 Q_{11},Q_{21} Q11,Q21 得到 R 1 R_1 R1 的过程:
f ( Q 21 ) − f ( Q 11 ) x 2 − x 1 ≈ f ( Q 21 ) − f ( R 1 ) x 2 − x \frac{f(Q_{21})-f(Q_{11})}{x_2-x_1} \approx\frac{f(Q_{21})-f(R_1)}{x_2-x} x2−x1f(Q21)−f(Q11)≈x2−xf(Q21)−f(R1)
计算步骤同上,化简结果:
f ( R 1 ) ≈ x 2 − x x 2 − x 1 f ( Q 11 ) + x − x 1 x 2 − x 1 f ( Q 21 ) f(R_{1}) \approx \frac{x_2-x}{x_2-x_1}f(Q_{11})+\frac{x-x_1}{x_2-x_1}f(Q_{21}) f(R1)≈x2−x1x2−xf(Q11)+x2−x1x−x1f(Q21)
-
然后结合 R 1 , R 2 R_1,R_2 R1,R2 在 y y y 方向插值得到 P P P
f ( R 2 ) − f ( R 1 ) y 2 − y 1 ≈ f ( R 2 ) − f ( P ) y 2 − y \frac{f(R_{2})-f(R_{1})}{y_2-y_1} \approx\frac{f(R_{2})-f(P)}{y_2-y} y2−y1f(R2)−f(R1)≈y2−yf(R2)−f(P)
经过化简:
f ( P ) ≈ y 2 − y y 2 − y 1 f ( R 1 ) + y − y 1 y 2 − y 1 f ( R 2 ) f(P) \approx \frac{y_2-y}{y_2-y_1}f(R_{1})+\frac{y-y_1}{y_2-y_1}f(R_{2}) f(P)≈y2−y1y2−yf(R1)+y2−y1y−y1f(R2)
将得到的 f ( R 1 ) , f ( R 2 ) f(R_{1}),f(R_{2}) f(R1),f(R2) 的化简结果带入到 f ( P ) f(P) f(P) 的公式里面:
f ( P ) ≈ f ( Q 11 ) ( x 2 − x 1 ) ( y 2 − y 1 ) ( x 2 − x ) ( y 2 − y ) + f ( Q 21 ) ( x 2 − x 1 ) ( y 2 − y 1 ) ( x − x 1 ) ( y 2 − y ) + f ( Q 12 ) ( x 2 − x 1 ) ( y 2 − y 1 ) ( x 2 − x ) ( y − y 1 ) + f ( Q 22 ) ( x 2 − x 1 ) ( y 2 − y 1 ) ( x − x 1 ) ( y − y 1 ) f(P) \approx \frac{f(Q_{11})}{(x_2-x_1)(y_2-y_1)}(x_2-x)(y_2-y)+\frac{f(Q_{21})}{(x_2-x_1)(y_2-y_1)}(x-x_1)(y_2-y)+\frac{f(Q_{12})}{(x_2-x_1)(y_2-y_1)}(x_2-x)(y-y_1)+\frac{f(Q_{22})}{(x_2-x_1)(y_2-y_1)}(x-x_1)(y-y_1) f(P)≈(x2−x1)(y2−y1)f(Q11)(x2−x)(y2−y)+(x2−x1)(y2−y1)f(Q21)(x−x1)(y2−y)+(x2−x1)(y2−y1)f(Q12)(x2−x)(y−y1)+(x2−x1)(y2−y1)f(Q22)(x−x1)(y−y1)
所以,最后可以得到 P P P 点的像素值,无论是先进行横向插值还是纵向插值,最后的出的 P P P 点的像素值是一样的。