Image processing 仿射变换检索中的最小点数?

Image processing 仿射变换检索中的最小点数?,image-processing,numpy,linear-algebra,affinetransform,Image Processing,Numpy,Linear Algebra,Affinetransform,我正试图找到一个2-D给定两点,使用给出的解决方案 它们给出了一种寻找连接两组点y和x的仿射变换的方法,其中变换由矩阵a和向量b表示(即矩阵方程y=Ax+b) 在二维中有6个未知量,4个定义2x2A矩阵,2个定义b 然而,在示例脚本和描述该脚本的文章中,它们有未知量t=n^2+n,其中n是点数,这意味着您需要六个点,对于2D情况,这实际上是12个已知值(即图像上每个点的x和y值) 他们通过以下方式进行测试: def solve(point_list): """ This fun

我正试图找到一个2-D给定两点,使用给出的解决方案

它们给出了一种寻找连接两组点yx的仿射变换的方法,其中变换由矩阵a和向量b表示(即矩阵方程y=Ax+b

在二维中有6个未知量,4个定义2x2A矩阵,2个定义b

然而,在示例脚本和描述该脚本的文章中,它们有未知量t=n^2+n,其中n是点数,这意味着您需要六个点,对于2D情况,这实际上是12个已知值(即图像上每个点的x和y值)

他们通过以下方式进行测试:

def solve(point_list):
    """
    This function solves the linear equation system involved in the n
    dimensional linear extrapolation of a vector field to an arbitrary point.

    f(x) = x * A + b

    with:
       A - The "slope" of the affine function in an n x n matrix.
       b - The "offset" value for the n dimensional zero vector.

    The function takes a list of n+1 point-value tuples (x, f(x)) and returns
    the matrix A and the vector b. In case anything goes wrong, the function
    returns the tuple (None, None).

    These can then be used to compute directly any value in the linear
    vector field.
    """dimensions = len(point_list[0][0])
    unknowns = dimensions ** 2 + dimensions
    number_points = len(point_list[0]) 
    # Bail out if we do not have enough data.
    if number_points < unknowns:
        print ’For a %d dimensional problem I need at least %d data points.’ \ % (dimensions, unknowns)  
        print ’Only %d data points were given.’ % number_points return None, None.
def solve(点列表):
"""
此函数用于求解n中涉及的线性方程组
向量场到任意点的维数线性外推。
f(x)=x*A+b
与:
A-nxn矩阵中仿射函数的“斜率”。
b-n维零向量的“偏移”值。
该函数获取n+1个点值元组(x,f(x))的列表并返回
矩阵A和向量b。如果出现任何错误,函数
返回元组(无,无)。
然后可以使用这些函数直接计算线性矩阵中的任何值
向量场。
“”“dimensions=len(点列表[0][0])
未知数=尺寸**2+尺寸
点数=len(点数列表[0])
#如果我们没有足够的数据,就出手援助。
如果点数<未知数:
打印“对于%d个维度问题,我需要至少%d个数据点”。\%(维度,未知)
打印“仅提供了%d个数据点”。%number\u点返回无,无。

问题:

为什么他们说你需要6个点才能得到二维仿射变换

opencv只需要3个数据点就可以在2D中找到一个点,这是直观的数字,因为3个点定义了一个平面。当我从Kloss和Kloss代码中取出上面的条件测试时,它在2D中可以工作3个点

为什么他们说你需要6个点才能得到二维仿射变换

对于此类变换,使用引入第三个
w
坐标的变换很方便,即:

  • (x,y)
    变为
    (x,y,w)
  • 两点是等价的iff
    x'/w'=x/w
    y'/w'=y/w
因此,您通常可以使用
w=1

使用此系统,您可以使用矩阵乘法表示二维变换(平移、旋转等):

[x']       [x]
[y'] = A . [y]
[1 ]       [1]
仿射变换是平移、缩放和旋转变换的组合,可表示为:

    [1 0 tx]   [Sx 0  0]   [cos(a) -sin(a) 0]   [a b c]
A = [0 1 ty] . [0  Sy 0] . [sin(a)  cos(a) 0] = [d e f]
    [0 0 1 ]   [0  0  1]   [0       0      1]   [0 0 1]
所以你有6个参数(也就是未知数),因此你需要3对点来解这个系统,因为每对点会给你2个方程

换句话说,您需要(至少)6个点(=3对)来计算转换

注意:你需要至少6个点,如果你得到更多,那么你的系统就是,这意味着你可以找到一个近似的解决方案,例如最小二乘法,这是你文章的重点。

切中要害

为什么他们说你需要6个点才能得到二维仿射变换

我猜你指的是本文等式(4)前面的位,他们说你至少需要
m>=n^2+n
。其中,
m
是点对的数量,
n
是维度的数量

我认为他们没有太注意,他们的意思是
m>=n+1

这意味着在2D中需要
n+1=3
点对,而在
3D
中,我们需要
n+1=4
点对来完全定义仿射变换。请注意,只要点不共线,就可以找到解决方案

这与您发布的opencv链接一致,具有
3x2=6
输入编号(3个源点,每个点有两个坐标)和类似的
6
输出编号:

(x1,y1,x2,y2,x3,y3)
分为
X[x1,y1],Y[x1,y1],X[x2,y2],Y[x2,y2],X[x3,y3],Y[x3,y3]

(但是请注意,opencv会计算精确的仿射变换,而本文不会)

我说,你经常不在乎这个

您可能需要的仿射变换的点比
m
少,并且您对其中一种解决方案感兴趣


您通常需要对变换进行估计并将误差降至最低,例如在最小二乘意义上,这就是本文的内容:使用numpy快速执行此操作。

要检索二维仿射变换,您需要精确的3个点,它们不应位于一条线上。对于N维空间,有一个简单的规则:要明确地恢复仿射变换,你应该知道N+1点的图像,这些点形成一个单纯形——2D为三角形,3D为金字塔,等等。你可以在“”中找到一个很好的解释UPD:该指南的作者最近发布了“”,其中包含许多通过对一定数量的点进行操作来检索仿射变换的示例,也许您可以在那里找到有用的内容。

在对编辑的评论中,用最小二乘法处理问题不需要6个点。他们对点的定义不是你对点的定义,这总是与未知数的数量一致。@flebool:如果你有>3对,那么最小二乘法就是最好的方法。正好有3对,没有必要。否则:我的上一次编辑增加了一些相对于点/对数的精度(实际上我们有
未知数/维度=维度+1