使用numpy获取二维多项式变换的逆(用于图像或光栅图像扭曲/采样)

使用numpy获取二维多项式变换的逆(用于图像或光栅图像扭曲/采样),numpy,image-processing,gis,transform,linear-algebra,Numpy,Image Processing,Gis,Transform,Linear Algebra,如果我有一个一阶/仿射、二阶或三阶的二维(x和y坐标)多项式变换函数(即,我有系数/变换矩阵a),那么获得该函数精确逆的数学或编程方法是什么?理想情况下,我将如何在Numpy中实现这一点?这是在图像扭曲或地图地理参考的背景下进行的,即在新扭曲坐标系中将坐标从输入图像转换或扭曲到输出图像 尝试解决方案 为了解决这个问题,我尝试了一种矩阵代数方法来解决方程组。从数学上讲,转换过程表示为Au=v。正向变换很简单,根据输入坐标,将u计算为包含多项式方程项的列矩阵,然后将u与变换矩阵a相乘,为了获得包含输

如果我有一个一阶/仿射、二阶或三阶的二维(x和y坐标)多项式变换函数(即,我有系数/变换矩阵
a
),那么获得该函数精确逆的数学或编程方法是什么?理想情况下,我将如何在Numpy中实现这一点?这是在图像扭曲或地图地理参考的背景下进行的,即在新扭曲坐标系中将坐标从输入图像转换或扭曲到输出图像

尝试解决方案 为了解决这个问题,我尝试了一种矩阵代数方法来解决方程组。从数学上讲,转换过程表示为
Au=v
。正向变换很简单,根据输入坐标,将
u
计算为包含多项式方程项的列矩阵,然后将
u
与变换矩阵
a
相乘,为了获得包含输出坐标的转换输出列矩阵
v
。另一方面,反向变换意味着我们知道输出坐标
v
,并希望找到输入坐标
u
,因此我们需要将方程重新排列为
u=Av
。根据矩阵代数的规则,
A
矩阵在移动时必须反转。对于二阶多项式变换,在Numpy中实现这一点似乎确实可行:

import numpy as np

# input coords
x = np.array([13])
y = np.array([13])
    
# terms of the 2nd order polynomial equation
x = x
y = y
xx = x*x
xy = x*y
yy = y*y
ones = np.ones(x.shape)

# u consists of each term in 2nd order polynomial equation
# with each term being array if want to transform multiple
u = np.array([xx,xy,yy,x,y,ones])
print('original input u', u)

## output:
## ('original input u', array([[169.],
##       [169.],
##       [169.],
##       [ 13.],
##       [ 13.],
##       [  1.]]))

# forward transform matrix
A = np.array([[1,2,3,1,6,8],
              [5,2,9,2,0,1],
              [8,1,5,8,4,3],
              [1,4,8,2,3,9],
              [9,3,2,1,9,5],
              [4,2,5,6,2,1]])

# get forward coords
v = A.dot(u)
print('output v', v)

## output:
## ('output v', array([[1113.],
##       [2731.],
##       [2525.],
##       [2271.],
##       [2501.],
##       [1964.]]))

# get backward coords (should exactly reproduce the input coords)
Ainv = np.linalg.inv(A)
u_pred = Ainv.dot(v)
print('backwards predicted input u', u_pred)

## output:
## ('backwards predicted input u', array([[169.],
##       [169.],
##       [169.],
##       [ 13.],
##       [ 13.],
##       [  1.]]))
在上面的示例中,输出
v
实际上是一个1x6矩阵,其中只有前两行/值表示转换后的x和y坐标。问题是,我们需要
v
中的所有附加值,以便精确地反转坐标。但在现实场景中,我们只知道转换后的x和y值(即
v
的前两行/值),我们不知道完整的1x6
v
矩阵

也许我认为这是错误的,或者这个矩阵代数方法不是正确的方法,因为二阶多项式和更高阶的多项式不再是线性的?是否有替代的程序化/numpy方法来反演多动物转化

一些背景 我查阅了许多类似的问题和网站以及numpy函数,如
numpy.polynomy.polynomy.fit
,但它们中的大多数只涉及到一维多项式变换的求逆。我发现的几个关于二维变换的链接说,没有精确的方法来反转它,这没有意义,因为这是图像扭曲/重采样和地图地理参考中非常常见的操作。例如,扭曲图像的步骤通常细分为:

  • 使用变换函数/matrix
    A
    向前投影所有原始像素(列行)坐标
    u
    ,以找到变换后的坐标空间
    v
    的边界
  • 然后,对于在变换后的坐标空间边界(在步骤1中找到)中以固定间隔采样的每个坐标,在变换后的坐标系中向后采样这些
    v
    坐标,以找到它们的原始坐标
    u
    。这将确定要为变换图像中的每个位置采样的原始像素

  • 我的问题是,我有步骤1所需的正变换,但我需要找到步骤2中向后采样所需的变换的精确逆。一个数学答案或一个数值解都可以。二维仿射函数的反演非常简单。它采用2x2线性方程组的分辨率

    二次多项式和三次多项式的情况问题更大。如果我是对的,两个未知量的系统等价于一个四次或非四次(9次)多项式方程。对于四次情形,存在显式(尽管复杂)公式,但对于非四次情形,没有显式(尽管复杂)公式,并且您必须求助于数值方法(牛顿迭代)

    此外,这些非线性方程的解不是唯一的(你可以有4或9个解),你需要保留正确的解



    如果变换仍然接近仿射变换(例如在校正图像失真时),我建议选择一种近似完整方程的仿射变换,使用反向变换找到初始近似值,然后使用牛顿进行优化。

    Correct,仿射变换是我唯一能处理矩阵简单逆的变换。我还怀疑增加的复杂性是因为二阶和三阶多边形可能会使图像自身弯曲,从而原始图像中的像素可能会变换到扭曲图像中的多个可能位置。这是否有助于增加一些假设,例如,原始图像像素坐标保证仅为正数?此外,这是否意味着在实践中根本不进行二阶多边形的反转?我知道地图地理参考/校正通常使用二阶或三阶多边形,我只是不确定它们如何反转变换以进行向后像素重采样。。。