动手实现双线性插值

本文详细解释了双线性插值实际上是做了三次单线性插值的过程,通过数学公式展示如何计算插值点的像素值,并用Python代码示例展示了如何使用numpy和OpenCV库进行双线性插值操作。
摘要由CSDN通过智能技术生成

双线行插值其实是做了三次单线性插值
在这里插入图片描述

如上图所示,在计算插值点p的像素值的时候,先是通过两次单线性插值得到 R 1 R_{1} R1 R 2 R_{2} R2,然后单次插值得到p的值,公式如下所示(公式由单线性插值得到):
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})=\frac{x_{2}-x}{x_{2}-x_{1}}f(Q_{11})+\frac{x-x_{1}}{x_{2}-x_{1}}f(Q_{21}) f(R1)=x2x1x2xf(Q11)+x2x1xx1f(Q21)
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})=\frac{x_{2}-x}{x_{2}-x_{1}}f(Q_{12})+\frac{x-x_{1}}{x_{2}-x_{1}}f(Q_{22}) f(R2)=x2x1x2xf(Q12)+x2x1xx1f(Q22)
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)

f ( R 1 ) f(R_{1}) f(R1) f ( R 2 ) f(R_{2}) f(R2)代入得:
f ( p ) = ( x 2 − x ) ( y 2 − y ) ( y 2 − y 1 ) ( x 2 − x 1 ) f ( Q 11 ) + ( x − x 1 ) ( y 2 − y ) ( y 2 − y 1 ) ( x 2 − x 1 ) f ( Q 21 ) + ( x 2 − x ) ( y − y 1 ) ( y 2 − y 1 ) ( x 2 − x 1 ) f ( Q 12 ) + ( x − x 1 ) ( y − y 1 ) ( y 2 − y 1 ) ( x 2 − x 1 ) f ( Q 22 ) f(p)=\frac{(x_{2}-x)(y_{2}-y)}{(y_{2}-y_{1})(x_{2}-x_{1})}f(Q_{11})+\frac{(x-x_{1})(y_{2}-y)}{(y_{2}-y_{1})(x_{2}-x_{1})}f(Q_{21})+\frac{(x_{2}-x)(y-y_{1})}{(y_{2}-y_{1})(x_{2}-x_{1})}f(Q_{12})+\frac{(x-x_{1})(y-y_{1})}{(y_{2}-y_{1})(x_{2}-x_{1})}f(Q_{22}) f(p)=(y2y1)(x2x1)(x2x)(y2y)f(Q11)+(y2y1)(x2x1)(xx1)(y2y)f(Q21)+(y2y1)(x2x1)(x2x)(yy1)f(Q12)+(y2y1)(x2x1)(xx1)(yy1)f(Q22)

由于是邻近点,所以有 x 2 − x 1 = 1 x_{2}-x_{1}=1 x2x1=1 y 2 − y 1 = 1 y_{2}-y_{1}=1 y2y1=1,因此上式可以简化为:

f ( p ) = ( x 2 − x ) ( y 2 − y ) f ( Q 11 ) + ( x − x 1 ) ( y 2 − y ) f ( Q 21 ) + ( x 2 − x ) ( y − y 1 ) f ( Q 12 ) + ( x − x 1 ) ( y − y 1 ) f ( Q 22 ) f(p)={(x_{2}-x)(y_{2}-y)}f(Q_{11})+(x-x_{1})(y_{2}-y)f(Q_{21})+(x_{2}-x)(y-y_{1})f(Q_{12})+(x-x_{1})(y-y_{1})f(Q_{22}) f(p)=(x2x)(y2y)f(Q11)+(xx1)(y2y)f(Q21)+(x2x)(yy1)f(Q12)+(xx1)(yy1)f(Q22)

x = x 1 + u x=x_{1}+u x=x1+u y = y 1 + v y=y_{1}+v y=y1+v,因此上述等式可以再次简化为:
f ( p ) = ( 1 − u ) ( 1 − v ) f ( Q 11 ) + u ( 1 − v ) f ( Q 21 ) + v ( 1 − u ) f ( Q 12 ) + u v f ( Q 12 ) f(p)=(1-u)(1-v)f(Q_{11})+u(1-v)f(Q_{21})+v(1-u)f(Q_{12})+uvf(Q_{12}) f(p)=(1u)(1v)f(Q11)+u(1v)f(Q21)+v(1u)f(Q12)+uvf(Q12)

程序如下:

import numpy as np
import matplotlib.pyplot as plt
import cv2

def bilinear_interpolation(image,ratio):
    h,w,_=image.shape
    dst_h,dst_w=int(h*ratio),int(w*ratio)
    dst=np.zeros([dst_h,dst_w,3])
    for dst_y in range(dst_h):
        for dst_x in range(dst_w):
            # find the position in the src_image
            src_x=dst_x/ratio
            src_y=dst_y/ratio

            i=int(np.floor(src_x))
            j=int(np.floor(src_y))

            u=src_x-i
            v=src_y-j

            if i==w-1:
                i=w-2
            if j==h-1:
                j=h-2
            dst[dst_y,dst_x]=(1-u)*(1-v)*image[j,i]+u*(1-v)*image[j+1,i]+v*(1-u)*image[j+1,i+1]+u*v*image[j+1,i]
    return dst

if __name__=="__main__":
    image=cv2.imread("cat1.png")
    dst_image=bilinear_interpolation(image,2)
    cv2.imwrite("./dst_image.png",dst_image)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值