在介绍双线性插值之前,我们先解释下 插值:百科的定义是插值是离散函数逼近的重要方法,利用函数通过的有限点的取值状况,估算出函数在临近处的近似值。
在图像领域,插值就是用来填充 图像变换时像素之间的空隙。插值算法有许多种,双线性插值只是其中一种。
线性插值
根据百科的介绍:线性插值是指插值函数为一次多项式的插值方式。线性插值的几何意义即为利用过A点和B点的 直线 ( y = k x + b ) (y=kx+b) (y=kx+b) 来近似表示原函数。线性插值可以用来近似代替原函数,也可以用来计算得到查表过程中表中没有的数值。
那么如下图所示,假设已知 y 1 = f ( x 0 ) , y 2 = f ( x 1 ) y_1=f(x_0) , y_2=f(x_1) y1=f(x0),y2=f(x1) ,现在要通过线性插值的方式得到区间 [ x 0 , x 1 ] [x_0, x_1] [x0,x1] 内任何一点的 f ( x ) f(x) f(x)值。
y ′ − y 1 x ′ − x 1 = y 2 − y 1 x 2 − x 1 \frac{y'-y_1}{x'-x_1} = \frac{y_2-y_1}{x_2-x_1} x′−x1y′−y1=x2−x1y2−y1
变换得:
y ′ = x 2 − x ′ x 2 − x 1 y 1 + x ′ − x 1 x 2 − x 1 y 2 y'=\frac{x_2-x'}{x_2-x_1}y_1 + \frac{x'-x_1}{x_2-x_1}y_2 y′=x2−x1x2−x′y1+x2−x1x′−x1y2
双线性插值
双线性插值是有两个变量的线性插值算法的扩展,即两个变量分别做一次线性插值。
在此我们以百度百科提供的图作为参考,每个点的数值是由 z = f ( x , y ) z=f(x,y) z=f(x,y) 决定的,因此借鉴于线性插值算法,双线性插值,需要通过临近点计算出 ( x ′ , y ′ ) (x',y') (x′,y′) ,
放在二维俯视图上,如下图所示
⚠️注意:线性插值的结果与插值的顺序无关。
首先进行y方向的插值,然后进行x方向的插值,所得到的结果是一样的。双线性插值的结果与先进行哪个方向的插值无关。
在此以 先进行 x方向插值,再y方向插值为例:
- X方向的线性插值,Q11,Q21 中插入蓝色点R1,在 Q12,Q22 中插入蓝色点R2;
- Y方向的线性插值,通过第一步计算出的 R1与R2 在y方向上插值计算出P点。
由线性插值算法可以得到,
R
1
R_1
R1 的值为 :
f
(
R
1
)
=
f
(
x
,
y
1
)
=
x
2
−
x
x
2
−
x
1
f
(
Q
11
)
+
x
−
x
1
x
2
−
x
1
f
(
Q
21
)
f(R_1)=f(x,y_1) \qquad\qquad\qquad\qquad\qquad\qquad \quad\\ =\frac{x_2-x}{x_2-x_1}f(Q_{11}) + \frac{x-x_1}{x_2-x_1}f(Q_{21})
f(R1)=f(x,y1)=x2−x1x2−xf(Q11)+x2−x1x−x1f(Q21)
同理,
R
2
R_2
R2 的值为:
f
(
R
2
)
=
f
(
x
,
y
2
)
=
x
2
−
x
x
2
−
x
1
f
(
Q
12
)
+
x
−
x
1
x
2
−
x
1
f
(
Q
22
)
f(R_2)=f(x,y_2) \qquad\qquad\qquad\qquad\qquad\qquad \quad\\ =\frac{x_2-x}{x_2-x_1}f(Q_{12}) + \frac{x-x_1}{x_2-x_1}f(Q_{22})
f(R2)=f(x,y2)=x2−x1x2−xf(Q12)+x2−x1x−x1f(Q22)
得到
R
1
,
R
2
R_1, R_2
R1,R2 的插值之后,再通过一次线性插值计算
P
P
P 点的插值。
f
(
P
)
=
f
(
x
,
y
)
=
y
2
−
y
y
2
−
y
1
f
(
R
1
)
+
y
−
y
1
y
2
−
y
1
f
(
R
2
)
f(P)=f(x,y) \qquad\qquad\qquad\qquad\qquad\qquad \\ =\frac{y_2-y}{y_2-y_1}f(R_1) + \frac{y-y_1}{y_2-y_1}f(R_2)
f(P)=f(x,y)=y2−y1y2−yf(R1)+y2−y1y−y1f(R2)
将上面的
R
1
,
R
2
R_1, R_2
R1,R2 代入上式,得:
f
(
P
)
=
f
(
x
,
y
)
=
(
x
2
−
x
)
(
y
2
−
y
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
f
(
Q
11
)
+
(
x
−
x
1
)
(
y
2
−
y
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
f
(
Q
21
)
+
(
x
2
−
x
)
(
y
−
y
1
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
f
(
Q
12
)
+
(
x
−
x
1
)
(
y
−
y
1
)
(
x
2
−
x
1
)
(
y
2
−
y
1
)
f
(
Q
22
)
f(P)=f(x,y) \qquad \qquad \qquad \qquad \qquad\qquad\qquad\qquad\qquad\qquad\qquad \\ =\frac{(x_2-x)(y_2-y)}{(x_2-x_1)(y_2-y_1)}f(Q_{11}) + \frac{(x-x_1)(y_2-y)}{(x_2-x_1)(y_2-y_1)}f(Q_{21}) \\ + \frac{(x_2-x)(y-y_1)}{(x_2-x_1)(y_2-y_1)}f(Q_{12}) + \frac{(x-x_1)(y-y_1)}{(x_2-x_1)(y_2-y_1)}f(Q_{22})
f(P)=f(x,y)=(x2−x1)(y2−y1)(x2−x)(y2−y)f(Q11)+(x2−x1)(y2−y1)(x−x1)(y2−y)f(Q21)+(x2−x1)(y2−y1)(x2−x)(y−y1)f(Q12)+(x2−x1)(y2−y1)(x−x1)(y−y1)f(Q22)
图像中的双线性插值
接触图像处理的小伙伴可能经常遇到图像放大等操作,即图像的上采样处理,此时很大一部分采用的便是双线性插值算法。
在图像中,双线性插值算法一般采用最邻近的4个像素点,因此
x
2
−
x
1
=
1
,
y
2
−
y
1
=
1
x_2-x_1=1, y_2-y_1=1
x2−x1=1,y2−y1=1,并且设
x
−
x
−
1
=
u
,
y
−
y
1
=
v
x-x-1=u, y-y_1=v
x−x−1=u,y−y1=v,因此上述公式可以简化为:
f
(
P
)
=
(
1
−
u
)
(
1
−
v
)
f
(
Q
11
)
+
u
(
1
−
v
)
f
(
Q
21
)
+
(
1
−
u
)
v
f
(
Q
12
)
+
u
v
f
(
Q
22
)
f(P)=(1-u)(1-v)f(Q_{11}) + u(1-v)f(Q_{21}) \\ \qquad \quad+(1-u)vf(Q_{12})\quad \quad + \quad uvf(Q_{22}) \qquad
f(P)=(1−u)(1−v)f(Q11)+u(1−v)f(Q21)+(1−u)vf(Q12)+uvf(Q22)
Pytorch 实现
在 Pytorch 中的 Upsample 算法,其实内部实现算法便是双线性插值处理即 'bilinear'
模式
import torch.nn.functional as F
F.interpolate(x, size=input_shape, mode='bilinear', align_corners=False)
mode (str) –
algorithm used for upsampling: 'nearest' | 'linear' | 'bilinear' |
'bicubic' | 'trilinear' | 'area' | 'nearest-exact'.
Default: 'nearest'
参考:
- https://blog.csdn.net/qq_37541097/article/details/112564822