双线性插值原理及Python实现

转载自:双线性插值原理及Python实现 - 简书

下面是关于双线性插值的经典说明图例:

转载请注明出处

首先,图中有5个像素点:

Q_{00}

Q_{01}

Q_{10}

Q_{11}

P

。其中四个红色点

Q

是原图的点,绿色点

P

就有意思了,理解了它的含义,对双线性插值原理就能有一个概念上的理解。
这个点

P

,其实是目标图的像素点在原图上的投影!

我们先跳出来想一下:
  • 双线性插值用来做什么?在CV领域,通常是用来改变原图的尺寸。
  • 那么目标图的每个像素点的像素值应该取多少呢?双线性插值的思路是,对于目标图的每个像素点,找到它在原图上最相关的四个点通过插值计算得到它的像素值。
  • 原图上哪四个点是最相关的呢?我们可以把目标图的点,投影回到原图上,投影点四周距离最近的四个原图点就是了。
回到上面的图例:

四个红色点

Q

就是投影点

P

的四周最近的点。通过四个红色点

Q

,可以计算出投影点

P

的像素值,这样目标图上的像素点的像素值也就得到了。

接下来就有两个问题。

目标图的点如何投影到原图上?

已知:

  1. 输入图的高和宽:

    height_{src}

    width_{src}

  2. 目标图的高和宽:

    height_{dst}

    width_{dst}

投影的公式是:
 

h = h_{dst} \ast \frac{height_{src}}{height_{dst}}

w = w_{dst} \ast \frac{width_{src}}{width_{dst}}

但是这个公式有一个问题,可能会导致目标图的中心跟原图的中心不对齐。例如:原图是3x3,中心点坐标(1, 1);目标图是9x9,中心点坐标(4, 4);通过上面的公式计算,目标图中心点在原图的投影坐标:

h = 4 * 3 / 9 = 1.3333 \neq 1


之所以会出现中心点不对齐,原因是每个像素点实际上是一个边长为1的正方形,所以对于坐标为(

h

,

w

)的像素点,它的中心其实是(

h+0.5

,

w+0.5

)。所以精确计算应该是:

\frac{h + 0.5}{height_{src}} = \frac{h_{dst} + 0.5}{height_{dst}}

\frac{w + 0.5}{width_{src}} = \frac{w_{dst} + 0.5}{width_{dst}}

转换一下得到正确的投影公式:

h = (h_{dst} + 0.5) \ast \frac{height_{src}}{height_{dst}} - 0.5

w = (w_{dst} + 0.5) \ast \frac{width_{src}}{width_{dst}} - 0.5

如何插值计算得到投影点的像素值?

已知:

  1. 四个红色点

    Q

    的坐标值:

    h_0

    h_1

    w_0

    w_1

  2. 四个红色点

    Q

    的像素值:

    f(Q_{00})

    f(Q_{01})

    f(Q_{10})

    f(Q_{11})

  3. 投影点

    P

    的坐标值:

    h

    w

思路是:每个

Q

点的像素值乘以各自的权重,然后相加得到投影点

P

像素值。

Q

点跟

P

点的距离越近,它的权重就越大。
双线性插值给出的算法很是简单粗暴:先在横轴方向上进行两次线性插值计算,然后在纵轴方向上进行一次插值计算。结合最开始那个图例看,就是先求

R_0

R_1

这两个蓝色点的像素值,然后再通过这两个值,求得

P

点的像素值。
具体计算如下:

f(R_0) \approx \frac{w_1 - w}{w_1 - w_0} f(Q_{00}) + \frac{w - w_0}{w_1 - w_0} f(Q_{01})

f(R_1) \approx \frac{w_1 - w}{w_1 - w_0} f(Q_{10}) + \frac{w - w_0}{w_1 - w_0} f(Q_{11})


 

f(P) \approx \frac{h_1 - h}{h_1 - h_0} f(R_0) + \frac{h - h_0}{h_1 - h_0} f(R_1)

\approx \frac{h_1 - h}{h_1 - h_0} \left ( \frac{w_1 - w}{w_1 - w_0} f(Q_{00}) + \frac{w - w_0}{w_1 - w_0} f(Q_{01}) \right ) + \frac{h - h_0}{h_1 - h_0} \left (\frac{w_1 - w}{w_1 - w_0} f(Q_{10}) + \frac{w - w_0}{w_1 - w_0} f(Q_{11}) \right )

= \frac{1}{(w_1 - w_0)(h_1 - h_0)} \left ( (h_1 - h)(w_1 - w)f(Q_{00}) + (h_1 - h)(w - w_0)f(Q_{01}) + (h - h_0)(w_1 - w)f(Q_{10}) + (h - h_0)(w - w_0)f(Q_{11}) \right )

前面说了,四个红色点

Q

是投影点

P

四周最近的点,显然四个红色点彼此间的距离都是1,也即

w_1 - w_0 = 1

h_1 - h_0 = 1

。上式可以写成:

f(P) \approx (h_1 - h)(w_1 - w)f(Q_{00}) + (h_1 - h)(w - w_0)f(Q_{01}) + (h - h_0)(w_1 - w)f(Q_{10}) + (h - h_0)(w - w_0)f(Q_{11})


再令:

u = h - h_0

v = w - w_0

,式子可以进一步写成:

f(P) \approx f(Q_{00})(1 - u)(1 - v) + f(Q_{01})(1 - u)v + f(Q_{10})u(1 - v) + f(Q_{11})uv

至此,关于双线性插值的原理就全部讲完了。



作者:Jinglever
链接:https://www.jianshu.com/p/29e5c84ea539
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值