我正在尝试使用affine tranform
给出的解决方案找到给定两点的2-D Kloss, and Kloss in “N-Dimensional Linear Vector Field Regression with NumPy.” (2010, The Python Papers Source Codes 2).他们提供了一种方法来找到连接两组 y 和 x 的仿射变换,其中变换由矩阵 A 表示和矢量 b (即矩阵方程 y = Ax + b )。
在二维中,您有6个未知数,4个定义2x2 A 矩阵,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.
...
问题:
为什么他们说你需要6分来获得2D仿射变换?
opencv getAffineTransform只需要3个数据点来查找2D中的点,这是直观的数字,因为3个点定义了一个平面。当我从Kloss和Kloss代码中取出上述条件测试时,它可以在2D中工作3个点。
答案 0 :(得分:4)
为什么他们说你需要6分来获得2D仿射变换?
对于这样的转换,使用引入第三个w
坐标的homogenous coordinates很方便,即:
(x, y)
变为(x, y, w)
,x'/w' = x/w
和y'/w'= y/w
两个等效点。 因此,您通常可以使用w = 1
。
使用此系统,您可以使用矩阵乘法表示2D变换(平移,旋转等):
[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个参数(a.k.a未知数),因此你需要3对点来解决系统,因为每对点都会给你2个方程。
换句话说,您需要(至少) 6分(= 3对)来计算您的转化。
注意:你需要至少 6分,因为如果你得到更多,那么你的系统是overdetermined,这意味着你可以找到一个近似解,例如最小二乘,这是你的文章的重点。
答案 1 :(得分:3)
明白了,
为什么他们说你需要6分来获得2D仿射变换?
我猜你指的是在eq之前的位。 (4)文章,他们说你至少需要m>=n^2+n
。在那里,m
是点数对,n
是维数。
我认为他们没有太多关注,他们的意思是m>=n+1
。
这意味着在2D中你需要n+1=3
个成对的点,并且在3D
中我们需要n+1=4
个点对来完全定义仿射变换。请注意,只要这些点不共线,您就能找到解决方案。
这与您发布的opencv链接一致,3x2=6
输入nubers(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。
答案 2 :(得分:1)
要检索2D仿射变换,您需要精确地3个点,并且它们不应位于一条直线上。对于N维空间,有一个简单的规则:要明确恢复仿射变换,您应该知道N + 1个点的图像,这些点形成 simplex --- 2D三角形,3D金字塔等。您可以在“ Beginner's guide to mapping simplexes affinely”中找到关于为什么应该这样的很好的解释。 UPD:该指南的作者最近发布了“ Workbook on mapping simplexes affinely”,其中包含许多示例,这些示例通过对特定点的作用来获取仿射变换,也许您可以在其中找到有用的东西。 / p>