欢迎访问个人网络日志🌹🌹知行空间🌹🌹文章来源地址https://www.toymoban.com/news/detail-664109.html
1.线性插值
线性插值是指使用连接两个已知点的直线来确定同在这个直线上的未知点值的方法。
图片来自于线性插值
如上图,已知坐标 ( x 0 , y 0 ) , ( x 1 , y 1 ) (x_0, y_0),(x_1,y_1) (x0,y0),(x1,y1),要求区间 [ x 0 , x 1 ] [x_0, x_1] [x0,x1]中间一个x位置在直线上的值,使用线性插值的方法如下,两点式直线方程可写为:
x − x 0 x 1 − x 0 = y − y 0 y 1 − y 0 \frac{x-x_0}{x_1-x_0}=\frac{y-y_0}{y_1-y_0} x1−x0x−x0=y1−y0y−y0
记方程左右的等值为
α
\alpha
α,则可得
α
=
x
−
x
0
x
1
−
x
0
\alpha=\frac{x-x_0}{x_1-x_0}
α=x1−x0x−x0,
y
=
(
1
−
α
)
y
0
+
α
y
1
y=(1-\alpha)y_0+\alpha y_1
y=(1−α)y0+αy1
上式可用来计算 y y y。实际上当 x ∉ [ x 0 , x 1 ] x\notin[x_0,x_1] x∈/[x0,x1]且 α ∉ [ 0 , 1 ] \alpha\notin[0,1] α∈/[0,1]时,上式仍然可以使用,这种情况下,这种方法叫作线性外插。
2.双线性插值
知道线性插值后,双线性插值,又称双线性内插,就是在两条线上分别进行一次线性插值,等到两个中间点,再对中间点进行一次线性插值得到的,如下图:
图片来自双线性插值
现在函数值是和 ( x , y ) (x,y) (x,y)相关的二维函数, z = f ( x , y ) z=f(x, y) z=f(x,y), 可将上图当成是沿z轴方向的俯视图, Q 11 , Q 12 , Q 21 , Q 22 Q_{11}, Q_{12}, Q_{21}, Q_{22} Q11,Q12,Q21,Q22是已知的四个点,双线性插值所做的事情即根据这四个点求中间点 P P P的值,上图中
f ( Q 11 ) = f ( x 1 , y 1 ) f ( Q 12 ) = f ( x 1 , y 2 ) f ( Q 21 ) = f ( x 2 , y 1 ) f ( Q 22 ) = f ( x 2 , y 2 ) \begin{matrix} f(Q_{11}) = f(x_1, y_1) \\ f(Q_{12}) = f(x_1, y_2) \\ f(Q_{21}) = f(x_2, y_1) \\ f(Q_{22}) = f(x_2, y_2) \end{matrix} f(Q11)=f(x1,y1)f(Q12)=f(x1,y2)f(Q21)=f(x2,y1)f(Q22)=f(x2,y2)
求P需先求中间点 R 1 , R 2 R_1,R_2 R1,R2, R 1 R_1 R1可根据 Q 11 , Q 12 Q_{11},Q_{12} Q11,Q12用线性插值公式来求, R 2 R_2 R2可根据 Q 21 , Q 22 Q_{21},Q_{22} Q21,Q22用线性插值公式来求。
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 2 ) = x 2 − x x 2 − x 1 f ( Q 12 ) + x − x 1 x 2 − x 1 f ( Q 22 ) \begin{matrix} f(R_1)=\frac{x_2-x}{x_2-x_1}f(Q_{11}) + \frac{x-x_1}{x_2-x1}f(Q_{21}) \\ f(R_2)=\frac{x_2-x}{x_2-x_1}f(Q_{12}) + \frac{x-x_1}{x_2-x1}f(Q_{22}) \end{matrix} f(R1)=x2−x1x2−xf(Q11)+x2−x1x−x1f(Q21)f(R2)=x2−x1x2−xf(Q12)+x2−x1x−x1f(Q22)
得到 R 1 , R 2 R_1,R_2 R1,R2后,对这两点再应用线性插值即可求 P P 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) = \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)
3.示例
3.1 双线性插值求像素点的值
已知 ( 2 , 2 ) , ( 2 , 3 ) , ( 3 , 2 ) , ( 3 , 3 ) (2,2),(2,3),(3,2),(3,3) (2,2),(2,3),(3,2),(3,3)四个像素点的值分别为 20 , 15 , 30 , 40 20,15,30,40 20,15,30,40,用双线性插值求其中间点 P ( 2.6 , 2.4 ) P(2.6,2.4) P(2.6,2.4)的像素值的过程如下,
图片来自双线性插值
f ( R 1 ) = 0.4 × 20 + 0.6 × 30 = 26 f ( R 2 ) = 0.4 × 15 + 0.6 × 40 = 30 f ( P ) = 0.6 × 26 + 0.4 × 30 = 27.6 ≈ 28 \begin{matrix} f(R_1) = 0.4 \times 20 + 0.6 \times 30 = 26 \\ f(R_2) = 0.4\times15+0.6\times40 = 30 \\ f(P)=0.6\times26+0.4\times30 = 27.6 \approx 28 \end{matrix} f(R1)=0.4×20+0.6×30=26f(R2)=0.4×15+0.6×40=30f(P)=0.6×26+0.4×30=27.6≈28
3.2与OpneCV Resize方法做比较
使用OpenCV
的resize
方法,插值方法选择双线性插值。将3x3
的图像使用双线性插值resize
成2x2
。
使用OpenCV
计算的结果为:
img = np.array([[30, 20, 10],
[10, 40, 60],
[20, 30, 40]], dtype=np.uint8)
img = cv2.resize(img, (2,2), cv2.INTER_LINEAR)
print(img)
# [[25 23]
# [21 42]]
手动计算双线性插值过程,需先将resize后大小为2x2
的destination
图像对应的点再还原到source
源图像上去,然后才能在原图像上应用双线性插值,这里将目标图像点映射到源图像上的坐标计算公式为:
X
=
(
d
s
t
X
+
0.5
)
×
s
r
c
W
i
d
t
h
d
s
t
W
i
d
t
h
−
0.5
Y
=
(
d
s
t
Y
+
0.5
)
×
s
r
c
H
e
i
g
h
t
d
s
t
H
e
i
g
h
t
−
0.5
\begin{matrix} X = (dstX + 0.5) \times \frac{srcWidth}{dstWidth} - 0.5 \\ Y = (dstY + 0.5) \times \frac{srcHeight}{dstHeight} - 0.5 \end{matrix}
X=(dstX+0.5)×dstWidthsrcWidth−0.5Y=(dstY+0.5)×dstHeightsrcHeight−0.5
- dstX 是resize后图像上的像素点坐标
- srcWidth/srcHeight源图像宽高,dstWidth/dstHeight resize后图像的宽高
这个公式可以写成:
s
r
c
X
+
0.5
d
s
t
X
+
0.5
=
s
r
c
W
i
d
t
h
d
s
t
W
i
d
t
h
\frac{srcX + 0.5}{dstX + 0.5} = \frac{srcWidth}{dstWidth}
dstX+0.5srcX+0.5=dstWidthsrcWidth
可理解成将resize
后每个像素点中心和原图上对应点开始一半像素的位置对齐。
计算过程为:
图片来自双线性插值
可见与OpenCV resize
函数使用INTER_LINEAR
方法时的结果相同。
上述原图坐标和resize
后图像坐标的映射方式等同于TORCH.NN.FUNCTIONAL.INTERPOLATE
函数align_corners=False
时的场景,
import torch
import torch.nn.functional as F
t = torch.tensor(img, dtype=torch.float).reshape(1,1,3,3)
it0 = F.interpolate(t, size=2, mode = 'bilinear')
print(it0)
# tensor([[[[25.0000, 23.1250],
# [21.2500, 41.8750]]]])
it0 = F.interpolate(t, size=2, mode = 'bilinear', align_corners=True)
print(it0)
# tensor([[[[30., 10.],
# [20., 40.]]]])
关于align_corners
参数的介绍可参考(三)TORCH.NN.FUNCTIONAL.INTERPOLATE使用说明。
其他
关于双线性插值,可以将上述公式 f ( P ) f(P) f(P)展开成 f ( Q i j ) f(Q_{ij}) f(Qij)的加权和,其物理含义可借助下图表示:
图片来自于RoI Pooling 与 RoI Align 的区别
文章来源:https://www.toymoban.com/news/detail-664109.html
欢迎访问个人网络日志🌹🌹知行空间🌹🌹
参考资料
- 1.https://blog.csdn.net/qq_37541097/article/details/112564822?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164784799816780255299039%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=164784799816780255299039&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-112564822.nonecase&utm_term=%E5%8F%8C%E7%BA%BF%E6%80%A7&spm=1018.2226.3001.4450#t4
- 2.https://zhuanlan.zhihu.com/p/161540817
到了这里,关于(四)线性插值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!