(四)线性插值


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


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} x1x0xx0=y1y0yy0

记方程左右的等值为 α \alpha α,则可得 α = x − x 0 x 1 − x 0 \alpha=\frac{x-x_0}{x_1-x_0} α=x1x0xx0,

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)=x2x1x2xf(Q11)+x2x1xx1f(Q21)f(R2)=x2x1x2xf(Q12)+x2x1xx1f(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)=y2y1y2yf(R1)+y2y1yy1f(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.628

3.2与OpneCV Resize方法做比较

使用OpenCVresize方法,插值方法选择双线性插值。将3x3的图像使用双线性插值resize2x2
使用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后大小为2x2destination图像对应的点再还原到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)×dstWidthsrcWidth0.5Y=(dstY+0.5)×dstHeightsrcHeight0.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 的区别
在这里插入图片描述


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值