填写2D阵列的间隙

时间:2016-05-03 22:31:43

标签: algorithm interpolation bicubic bilinear-interpolation

我有一个稀疏填充的数组,如下所示。是否有一种算法可以用线性有意义的值填充所有空白?即。从周围的原始值中推断出来。

我看过双线性插值和双三次插值,但还有其他吗?

     |    1    |    2   |    3    |    4    |    5    |    6    |    7
---------------------------------------------------------------------------------
1    | 
2    |
3    |             55
4    |             50                                     12         6
5    |             45                                                19
6    |             xxx 
7    |             35        45       50        yyy
8    |
9    |
10   |
11   |
12   |                       zzz
13   |
14   |
15   |

例如,我希望xxx在40附近,并且yyy在50附近。然而,zzz可能具有更随机的值。请注意:我想填充每个空白区域,而不仅仅是xxx,yyy和zzz。并且能够为任何人口稀少的数组执行此操作。

这种算法是否存在?

3 个答案:

答案 0 :(得分:1)

存在一百万个这样的算法。首先,你有一些已知值的字典,如下所示:

known_values = {
    (2, 3): 55.0,
    (2, 4): 50.0,
    (2, 5): 45.0,
    (2, 7): 35.0,
    (3, 7): 45.0,
    (4, 7): 50.0,
    (6, 4): 12.0,
    (7, 4): 6.0,
    (7, 5): 19.0,
}

最简单的方法是说任何一点的值都是所有填充点的加权平均值。重量为1 /距离平方。所以在上面的例子中,你有这样的代码:

def interpolate(known_values, p):
     total_weight = 0.0
     total_sum = 0.0
     for q, value in known_values:
         if p == q:
             return value
         d_square = (p[0] - q[0])**2 + (p[1] - q[1])**2
         total_weight = total_weight + 1.0 / d_square
         total_sum = total_sum + value / d_square
     return total_sum/total_weight

只要矩阵中有任何填充数据,此解决方案就可以正常工作。

然而,根据您提出问题的方式判断,您可能需要在任何小区域内进行平滑插值,该插值近似为线性。一种方法是查找(a, b, c),使函数a*x + b*y + c最小化误差平方的加权和,权重是从所需点到已知点的距离的四次幂点。 (前2个功率撤消该区域的平方,其他两个权重更靠近点。)

在这里使用最小二乘法的原因是数学运算简单。当abc中的一个小变化不会更改值时,您将最小化,这意味着偏导数为0.因此,三个偏导数为3线性方程组。在3个变量中求解3个方程式相当容易。

然而,推导是漫长而混乱的。如果你想尝试它,你应该看看通常的最小二乘推导,并尝试解决细节。然后尝试实现它。但是,只有当你真的试图尝试进行线性投影以远离你拥有数据的位置时才尝试。

答案 1 :(得分:1)

这个问题可以看作是一个“双变量插值”问题,这个领域有很多研究。您可以在Wiki中搜索“多变量插值”,并在“2维”部分下查找算法。

在各种方法中,双线性/双三次插值需要数据来形成网格,而不是数据的情况。 Delaunay三角剖分方法不适合您的情况下根据需要进行外推。反加权距离方法易于实现并且适合于外推,但结果通常不令人满意。我个人建议使用径向基函数,只要你没有太多的数据点(如数千)。

答案 2 :(得分:0)

我已经在GitHub上上传了自己的解决方案,该解决方案使用薄板样条方法:

https://github.com/lunarquaker/ThinPlateSpline_DotNet