• 线性插值方法介绍及图像缩放


    1 线性插值

      设函数 y = f ( x ) y=f(x) y=f(x)在两点 x 0 x_{0} x0 x 1 x_{1} x1上的值分别为 y 0 y_{0} y0 y 1 y_{1} y1。求多项式 y = p 1 ( x ) = a 0 + a 1 x y=p_{1}(x)=a_{0}+a_{1}x y=p1(x)=a0+a1x,使满足 p 1 ( x 0 ) = y 0 , p 1 ( x 1 ) = y 1 p_{1}(x_{0})=y_{0},p_{1}(x_{1})=y_{1} p1(x0)=y0,p1(x1)=y1。其几何意义求通过 A ( x 0 , y 0 ) A(x_{0},y_{0}) A(x0,y0) B ( x 1 , y 1 ) B(x_{1},y_{1}) B(x1,y1)的一条直线。由解析几何可知: y = p 1 ( x ) = y 0 + y 1 − y 0 x 1 − x 0 ( x − x 0 ) y=p_{1}(x)=y_{0}+\frac{y_{1}-y_{0}}{x_{1}-x_{0}}(x-x_{0}) y=p1(x)=y0+x1x0y1y0(xx0)将上述公式重新整理可得到: p 1 ( x ) = x − x 1 x 0 − x 1 y 0 + x − x 0 x 1 − x 0 y 1 p_{1}(x)=\frac{x-x_{1}}{x_{0}-x_{1}}y_{0}+\frac{x-x_{0}}{x_{1}-x_{0}}y_{1} p1(x)=x0x1xx1y0+x1x0xx0y1

    2 双线性插值

    2.1 计算公式

      双线性插值,是连个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。这里以下图为例进行说明:
      假设现在想知道未知函数 f f f在点 P ( x , y ) P(x,y) P(x,y)的值,目前已知函数 f f f Q 11 = ( x 1 , y 1 ) Q_{11}=(x_{1},y_{1}) Q11=(x1,y1) Q 12 = ( x 1 , y 2 ) Q_{12}=(x_{1},y_{2}) Q12=(x1,y2) Q 21 = ( x 2 , y 1 ) Q_{21}=(x_{2},y_{1}) Q21=(x2,y1) Q 22 = ( x 2 , y 2 ) Q_{22}=(x_{2},y_{2}) Q22=(x2,y2)的值。
    在这里插入图片描述
    双线性插值的计算步骤如下:

    • 首先在 x x x方向上的线性插值,分别计算函数 f f f R 1 R_{1} R1 R 2 R_{2} R2上的值。其计算公式如下: 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)
    • 其次,利用 R 1 R_{1} R1 R 2 R_{2} 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)
    2.2 使用案例

      下面是一段使用双线性插值方法对图片像素进行修改的方法。

    from PIL import Image
    import numpy as np
    import math
    
    def get_pixel(path):
        img=Image.open(path)
        pixel=img.load()
        data=[]
        for i in range(img.size[0]):
            for j in range(img.size[1]):
                data.extend(list(pixel[i,j]))
        data=np.reshape(np.array(data),(img.size[0],img.size[1],3))
        return img,data
        
    def img_resize(height,width,img,data):
        #生成在图片上取样的x坐标、y坐标
        lin_height=np.linspace(0,img.size[0]-1,height)
        lin_width=np.linspace(0,img.size[1]-1,width)
                  
        new_img=Image.new('RGB',(height,width),(0,0,0))
        
        x1=np.array(list(map(lambda x:x if x<(img.size[0]-1) else x-1,[math.floor(i) for i in lin_height])))
        x2=np.array(list(map(lambda x:x-1 if x==img.size[0] else x,[math.floor(i+1) for i in lin_height])))
        
        y1=np.array(list(map(lambda x:x if x<(img.size[1]-1) else x-1,[math.floor(i) for i in lin_width])))
        y2=np.array(list(map(lambda x:x-1 if x==img.size[1] else x,[math.floor(i+1) for i in lin_width])))
        pixel_list=[]
        for i in range(height):    
            Q_r1=data[x1[i],y1,:]*(x2[i]-lin_height[i])+data[x2[i],y1,:]*(lin_height[i]-x1[i])
            Q_r2=data[x1[i],y2,:]*(x2[i]-lin_height[i])+data[x2[i],y2,:]*(lin_height[i]-x1[i])
            Q=Q_r1*np.reshape(y2-lin_width,(-1,1))+\
                Q_r2*np.reshape(lin_width-y1,(-1,1))
            Q=Q.astype(int)
            for j in range(Q.shape[0]):
                new_img.putpixel((i,j),tuple(Q[j]))
        return new_img
    if __name__=="__main__":
        path=r'/Users/sherry/Downloads/杀生丸.jpeg'
        img,data=get_pixel(path)
        new_img=img_resize(2000,2000,img,data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    Android 蓝牙 OPP文件传输-Obex协议连接-socket连接 从framework到协议栈btif层 --- 全网最详细(一)
    String类重点知识思维导图
    Java 在PDF中替换文字(详解)
    点成案例丨温度梯度培养箱在探究温度对植物发芽影响中的应用
    详解AVL树(二叉搜索平衡树)【C++实现】
    【Linux】基础:进程的概念
    iceberg合并小文件冲突测试
    ReactNative 开发之旅: 项目配置与版本管理实践
    30天Python入门(第九天:深入了解Python中的条件语句)
    计算机组成原理---第四章指令系统---指令的寻址方式---选择题
  • 原文地址:https://blog.csdn.net/yeshang_lady/article/details/132850861