一尘不染

算法:如何计算双线性插值的INVERSE?映射到任意四边形的逆函数?

algorithm

更新: 我下面的术语是错误的。我在“ Lerp2D”中描述的“正向”算法(我需要逆运算)需要四个任意角。它沿着每个边都是线性的,但是 所有
4个 边_都可以独立拉伸。它 _不是双线性的

我已经在标题中保留了双线性-如果您来这里是寻找“双线性的逆”,例如in
x和中的独立拉伸y

如果需要更一般的情况(由任意四边形定义拉伸),请参见接受的答案。

在此问题的评论中,另请参阅人们给出的链接。


原始问题:

双线性插值的计算很简单。但是我需要一种执行逆运算的算法。(算法对我来说可以是伪代码或任何广泛使用的计算机语言)

例如,这是双线性插值的Visual Basic实现。

' xyWgt ranges (0..1) in x and y. (0,0) will return X0Y0,
(0,1) will return X0Y1, etc.
' For example, if xyWgt is relative location within an image,
' and the XnYn values are GPS coords at the 4 corners of the image,
' The result is GPS coord corresponding to xyWgt.
' E.g. given (0.5, 0.5), the result will be the GPS coord at center of image.
Public Function Lerp2D(xyWgt As Point2D, X0Y0 As Point2D, X1Y0 As Point2D, X0Y1 As Point2D, X1Y1 As Point2D) As Point2D
    Dim xY0 As Point2D = Lerp(X0Y0, X1Y0, xyWgt.X)
    Dim xY1 As Point2D = Lerp(X0Y1, X1Y1, xyWgt.X)

    Dim xy As Point2D = Lerp(xY0, xY1, xyWgt.Y)
    Return xy
End Function

哪里

' Weighted Average of two points.
Public Function Lerp(ByVal a As Point2D, ByVal b As Point2D, ByVal wgtB As Double) As Point2D
    Return New Point2D(Lerp(a.X, b.X, wgtB), Lerp(a.Y, b.Y, wgtB))
End Function

' Weighted Average of two numbers.
' When wgtB==0, returns a, when wgtB==1, returns b.
' Implicitly, wgtA = 1 - wgtB. That is, the weights are normalized.
Public Function Lerp(ByVal a As Double, ByVal b As Double, ByVal wgtB As Double) As Double
    Return a + (wgtB * (b - a))
End Function

在1-D中,我确定了Lerp的反函数:

' Calculate wgtB that would return result, if did Lerp(a, b, wgtB).
' That is, where result is, w.r.t. a and b.
' < 0 is before a, > 1 is after b.
Public Function WgtFromResult(ByVal a As Double, ByVal b As Double, ByVal result As Double) As Double

    Dim denominator As Double = b - a

    If Math.Abs(denominator) < 0.00000001 Then
        ' Avoid divide-by-zero (a & b are nearly equal).
        If Math.Abs(result - a) < 0.00000001 Then
            ' Result is close to a (but also to b): Give simplest answer: average them.
            Return 0.5
        End If
        ' Cannot compute.
        Return Double.NaN
    End If

    ' result = a + (wgt * (b - a))   =>
    ' wgt * (b - a) = (result - a)   =>
    Dim wgt As Double = (result - a) / denominator

    'Dim verify As Double = Lerp(a, b, wgt)
    'If Not NearlyEqual(result, verify) Then
    '    Dim test = 0    ' test
    'End If

    Return wgt
End Function

现在,我需要在二维中执行相同的操作:

' Returns xyWgt, which if given to Lerp2D, would return this "xy".
' So if xy = X0Y0, will return (0, 0). if xy = X1Y0, will return (1, 0), etc.
' For example, if 4 corners are GPS coordinates in corners of an image,
' and pass in a GPS coordinate,
' returns relative location within the image.
Public Function InverseLerp2D(xy As Point2D, X0Y0 As Point2D, X1Y0 As Point2D, X0Y1 As Point2D, X1Y1 As Point2D) As Point2D
    ' TODO ????
End Function

阅读 587

收藏
2020-07-28

共1个答案

一尘不染

为了简化,让我们从仅考虑单个内插值 z开始
假设四个值 z 00, z 01, z 10, z 10和两个权重 w 0和 w 1应用于第一和第二索引,得出

z 0 = z 00 + w 0 ×( z 10 - z 00)
z 1 = z 01 + w 0 ×( z 11 - z 01)

最后

z = z 0 + w 1 ×( z 1 - z 0)
= z 00 + w 0 ×( z 10 - z 00)+ w 1 ×( z 01 - z 00)+ w 1 ×
w 0 ×( z 11 - ž 10 - ž 01 + ž 00)

因此,对于您的问题,您将必须逆转二维二次方程

x = x 00 + w 0 ×( x 10 - x 00)+ w 1 ×( x 01 - x 00)+ w 1
× w 0 ×( x 11 - x 10 - x 01 + x 00)
y = y 00 + w 0 ×( y 10 - y 00)+ w 1×( y 01 - y 00)+ w 1 ×
w 0 ×( y 11 - y 10 - y 01 + y 00)

不幸的是,没有一个简单的公式可以从 xy 恢复 w 0和 w 1。但是,您可以将其视为非线性最小二乘问题并最小化

x ww 0, w 1) -x )2 +( y ww 0, w 1) -y )2

您可以使用Levenberg-
Marquardt算法
高效地执行此操作。

编辑 :进一步的想法

在我看来,您可能会对从( xy )到( w 0, w 1)的插值感到满意,而不是实际的逆。从rev(fwd( w 0, w
1))可能比( w 0, w 1)更远的地方开始,这会比实际的倒数更不准确。

您在不规则网格而不是规则网格上进行插值的事实将使这一点变得更加棘手。理想情况下,您应该将( xy
)点与不重叠的三角形连接起来,并使用重心坐标进行线性插值。
为了保持数值稳定性,应避免使用浅而尖的三角形。幸运的是,Delaunay三角剖分满足了这一要求,并且在二维中构造也不是
困难。

如果您希望反向插值采用与正向插值类似的形式,则可以使用基函数

1
x
y
x × y

并计算系数 a ib ic id ii 等于0或1),使得

w 0 = a 0 + b 0 × x + c 0 × y + d 0 × x × y
w 1 = a 1 + b 1 × x + c 1 × y + d 1 × x × y

通过代入相关的已知值 xyw 0和 w 1,您将为每个 w 获得四个联立的 线性 方程,您可以求解这些 线性
方程,以获取其系数。
理想情况下,您应该使用数值稳定的矩阵求逆算法,该算法可以处理接近奇异的矩阵(例如SVD),但是如果小心一点,您
也许 可以摆脱高斯消除

抱歉,我无法给您提供任何更简单的选择,但恐怕这确实是一个相当棘手的问题!

2020-07-28