有谁知道如何进行“逆”三线性插值?

时间:2009-07-02 08:37:54

标签: algorithm math interpolation

三线性插值使用立方体顶点处的值近似于立方体内的点(x,y,z)的值。我正在尝试进行“逆”三线插值。知道立方体顶点的值和附加到点的值我如何找到(x,y,z)?任何帮助将受到高度赞赏。谢谢!

5 个答案:

答案 0 :(得分:3)

您正在使用1个数据求解3个未知数,并且当您使用线性插值时,您的答案通常是平面(2个自由变量)。根据立方体的不同,可能没有解决方案或3D解决方案空间。

我会做以下事情。设v为初始值。对于立方体的12个边(一对相邻顶点)的每个“边”,看看是否1个顶点是> = v而另一个< = v - 称之为跨越v的边缘。

如果没有边缘越过v,则没有可能的解决方案。

否则,对于每个穿过v的边,如果边的两个顶点都等于v,则整个边是一个解。否则,在边缘上线性插值以找到具有值v的点。因此假设边缘是(x1,y1,z1) - > v1< = v< =(x2,y2,z2) - > ; V2

s = (v-v1)/(v2-v1)
(x,y,z) = (s*(x2-x1)+x1, (s*(y2-y1)+y1, s*(z2-z1)+z1)

这将为您提供所有等于v的边缘点。这是一个解决方案,但您可能需要一个内部解决方案 - 请注意,如果有内部解决方案,将始终存在边缘解决方案。

如果你想要一个内部解决方案,那么只需在边缘解决方案之间线性地取任何点 - 当你进行线性插值时,结果也将是v。

答案 1 :(得分:2)

我不确定你能否适用于所有情况。例如,对颜色使用三线性滤波,其中每个点的每个颜色(C)都相同意味着无论您在何处插值,您仍将获得返回的颜色C.在这种情况下,任何x,y,z都可能有效。因此,无法确定初始插值值是什么。

我确信在某些情况下你可以改变数学,但我想,如果不了解更多的输入信息,就有太多的情况不可能做到。

祝你好运,我希望有人会证明我错了:)

答案 2 :(得分:0)

你所描述的问题有些不明确。
你要求的基本上是这个:我有一个3D功能,我知道它的8个已知点的值。我想知道函数接收值V的重点是什么 麻烦的是,在很大程度上,根据数据,有无数个这样的点可以形成一组表面,线或点。
找到此集合的一种方法是使用像Marching cubes这样的等表面处理算法。

答案 3 :(得分:0)

wikipedia page for trilinear interpolation链接到a NASA page据称描述了反转过程 - 您有没看过它?

答案 4 :(得分:0)

让我们从2d开始:想想一平方公里的双线山, 在4个角落处高度为0 10 20 30 以及在高度z处切割山丘的水平面。 画一条从0角到30角的线(无论是相邻角还是对角线)。 对于任何z,飞机必须切断此线 所以所有点x,y,z都落在这一行上,对吗? HMM。

好的,有很多解决方案 - 任何z平面都会在轮廓曲线上切割山丘。 假设我们希望解决方案遍布整个山丘, 即一次最小化两件事:

  • 垂直距离z - bilin(x,y),
  • 从x,y到广场某个点的距离。

Scipy.optimize.leastsq是这样做的一种方式,示例代码如下; 三线是类似的。

(一次优化任何两件事需要任意权衡或加权: 食物与金钱,工作与游戏...... 参看Bounded rationality

""" find x,y so bilin(x,y) ~ z  and  x,y near the middle """
from __future__ import division
import numpy as np
from scipy.optimize import leastsq

zmax = 30
corners = [ 0, 10, 20, zmax ]
midweight = 10

def bilin( x, y ):
    """ bilinear interpolate
        in: corners at 0 0  0 1  1 0  1 1 in that order (binary)
        see wikipedia Bilinear_interpolation ff.
    """
    z00,z01,z10,z11 = corners  # 0 .. 1
    return (z00 * (1-x) * (1-y)
        + z01 * (1-x) * y
        + z10 * x * (1-y)
        + z11 * x * y)

vecs = np.array([ (x, y) for x in (.25, .5, .75) for y in (.25, .5, .75) ])
def nearvec( x, vecs ):
    """ -> (min, nearest vec) """
    t = (np.inf,)
    for v in vecs:
        n = np.linalg.norm( x - v )
        if n < t[0]:  t = (n, v)
    return t

def lsqmin( xy ):  # z, corners
    x,y = xy
    near = nearvec( np.array(xy), vecs )[0] * midweight
    return (z - bilin( x, y ), near )
        # i.e. find x,y so both bilin(x,y) ~ z  and  x,y near a point in vecs

#...............................................................................
if __name__ == "__main__":
    import sys
    ftol = .1
    maxfev = 10
    exec "\n".join( sys.argv[1:] )  # ftol= ...
    x0 = np.array(( .5, .5 ))
    sumdiff = 0
    for z in range(zmax+1):
        xetc = leastsq( lsqmin, x0, ftol=ftol, maxfev=maxfev, full_output=1 )
            # (x, {cov_x, infodict, mesg}, ier)
        x,y = xetc[0]  # may be < 0 or > 1
        diff = bilin( x, y ) - z
        sumdiff += abs(diff)
        print  "%.2g  %8.2g  %5.2g %5.2g" % (z, diff, x, y)

print "ftol %.2g maxfev %d midweight %.2g  =>  av diff %.2g" % (
    ftol, maxfev, midweight, sumdiff/zmax)