如何在 Python 中执行双线性插值 [英] How to perform bilinear interpolation in Python

查看:38
本文介绍了如何在 Python 中执行双线性插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 python 执行双线性插值.
我要为其插入高度的示例 gps 点是:

B = 54.4786674627L = 17.0470721369

使用具有已知坐标和高度值的四个相邻点:

n = [(54.5, 17.041667, 31.993), (54.5, 17.083333, 31.911), (54.458333, 17.041667, 31.945), (536,315), (536,315)].


z01 z11zz00 z10


这是我的原始尝试:

导入数学z00 = n[0][2]z01 = n[1][2]z10 = n[2][2]z11 = n[3][2]c = 0.016667 #网格间距x0 = 56 #网格原点纬度y0 = 13 #网格原点的经度i = math.floor((L-y0)/c)j = math.floor((B-x0)/c)t = (B - x0)/c - jz0 = (1-t)*z00 + t*z10z1 = (1-t)*z01 + t*z11s = (L-y0)/c - iz = (1-s)*z0 + s*z1


其中 z0 和 z1

z01 z0 z11zz00 z1 z10


我得到 31.964,但从其他软件我得到 31.961.
我的脚本是否正确?
你能提供另一种方法吗?

解决方案

这是您可以使用的可重用函数.它包括文档测试和数据验证:

def bilinear_interpolation(x, y, points):'''从与四个点关联的值中插入 (x,y).这四个点是四个三元组的列表:(x, y, value).这四个点可以按任何顺序排列.它们应该形成一个矩形.>>>bilinear_interpolation(12, 5.5,... [(10, 4, 100),... (20, 4, 200),... (10, 6, 150),... (20, 6, 300)])165.0'''# 参见公式:http://en.wikipedia.org/wiki/Bilinear_interpolationpoints = sorted(points) # 按 x 排序,然后按 y(x1, y1, q11), (_x1, y2, q12), (x2, _y1, q21), (_x2, _y2, q22) = 点如果 x1 != _x1 或 x2 != _x2 或 y1 != _y1 或 y2 != _y2:raise ValueError('点不形成矩形')如果不是 x1 <= x <= x2 或不是 y1 <= y <= y2:引发 ValueError('(x, y) 不在矩形内')返回 (q11 * (x2 - x) * (y2 - y) +q21 * (x - x1) * (y2 - y) +q12 * (x2 - x) * (y - y1) +q22 * (x - x1) * (y - y1))/((x2 - x1) * (y2 - y1) + 0.0)

您可以通过添加以下内容来运行测试代码:

如果 __name__ == '__main__':导入文档测试doctest.testmod()

在数据集上运行插值会产生:

<预><代码>>>>n = [(54.5, 17.041667, 31.993),(54.5, 17.083333, 31.911),(54.458333, 17.041667, 31.945),(54.458333, 17.083333, 31.866),]>>>双线性插值(54.4786674627,17.0470721369,n)31.95798688313631

I would like to perform blinear interpolation using python.
Example gps point for which I want to interpolate height is:

B = 54.4786674627
L = 17.0470721369

using four adjacent points with known coordinates and height values:

n = [(54.5, 17.041667, 31.993), (54.5, 17.083333, 31.911), (54.458333, 17.041667, 31.945), (54.458333, 17.083333, 31.866)]


z01    z11

     z
z00    z10


and here's my primitive attempt:

import math
z00 = n[0][2]
z01 = n[1][2]
z10 = n[2][2]
z11 = n[3][2]
c = 0.016667 #grid spacing
x0 = 56 #latitude of origin of grid
y0 = 13 #longitude of origin of grid
i = math.floor((L-y0)/c)
j = math.floor((B-x0)/c)
t = (B - x0)/c - j
z0 = (1-t)*z00 + t*z10
z1 = (1-t)*z01 + t*z11
s = (L-y0)/c - i
z = (1-s)*z0 + s*z1


where z0 and z1

z01  z0  z11

     z
z00  z1   z10


I get 31.964 but from other software I get 31.961.
Is my script correct?
Can You provide another approach?

解决方案

Here's a reusable function you can use. It includes doctests and data validation:

def bilinear_interpolation(x, y, points):
    '''Interpolate (x,y) from values associated with four points.

    The four points are a list of four triplets:  (x, y, value).
    The four points can be in any order.  They should form a rectangle.

        >>> bilinear_interpolation(12, 5.5,
        ...                        [(10, 4, 100),
        ...                         (20, 4, 200),
        ...                         (10, 6, 150),
        ...                         (20, 6, 300)])
        165.0

    '''
    # See formula at:  http://en.wikipedia.org/wiki/Bilinear_interpolation

    points = sorted(points)               # order points by x, then by y
    (x1, y1, q11), (_x1, y2, q12), (x2, _y1, q21), (_x2, _y2, q22) = points

    if x1 != _x1 or x2 != _x2 or y1 != _y1 or y2 != _y2:
        raise ValueError('points do not form a rectangle')
    if not x1 <= x <= x2 or not y1 <= y <= y2:
        raise ValueError('(x, y) not within the rectangle')

    return (q11 * (x2 - x) * (y2 - y) +
            q21 * (x - x1) * (y2 - y) +
            q12 * (x2 - x) * (y - y1) +
            q22 * (x - x1) * (y - y1)
           ) / ((x2 - x1) * (y2 - y1) + 0.0)

You can run test code by adding:

if __name__ == '__main__':
    import doctest
    doctest.testmod()

Running the interpolation on your dataset produces:

>>> n = [(54.5, 17.041667, 31.993),
         (54.5, 17.083333, 31.911),
         (54.458333, 17.041667, 31.945),
         (54.458333, 17.083333, 31.866),
    ]
>>> bilinear_interpolation(54.4786674627, 17.0470721369, n)
31.95798688313631

这篇关于如何在 Python 中执行双线性插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆