如何计算3D中4点之间的MatLab相似变换? 我可以从
计算变换矩阵 T*X = Xp
,
但由于点坐标误差很小,它会给我仿射矩阵。我怎样才能将该矩阵与相似矩阵相匹配?我需要像fitgeotrans
这样的东西,但需要3D
由于
答案 0 :(得分:6)
如果我正确地解释你的问题,你会寻找在3D变换矩阵中找到最佳扭曲一个点到另一个点的所有系数。你真正需要做的就是把这个问题放到线性系统中解决。回想一下,在3D中将一个点翘曲到另一个点只是:
A*s = t
s = (x,y,z)
是源点,t = (x',y',z')
是目标点,A
是3 x 3转换矩阵,其格式为:
A = [a00 a01 a02]
[a10 a11 a12]
[a20 a21 a22]
写出A*s = t
的实际方程组,我们得到:
a00*x + a01*y + a02*z = x'
a10*x + a11*y + a12*z = y'
a20*x + a21*y + a22*z = z'
A
中的系数是我们需要解决的问题。用矩阵形式重写这个,我们得到:
[x y z 0 0 0 0 0 0] [a00] [x']
[0 0 0 x y z 0 0 0] * [a01] = [y']
[0 0 0 0 0 0 x y z] [a02] [z']
[a10]
[a11]
[a12]
[a20]
[a21]
[a22]
鉴于您有四个点,您只需连接左侧矩阵的行和右侧的矢量
[x1 y1 z1 0 0 0 0 0 0] [a00] [x1']
[0 0 0 x1 y1 z1 0 0 0] [a01] [y1']
[0 0 0 0 0 0 x1 y1 z1] [a02] [z1']
[x2 y2 z2 0 0 0 0 0 0] [a10] [x2']
[0 0 0 x2 y2 z2 0 0 0] [a11] [y2']
[0 0 0 0 0 0 x2 y2 z2] [a12] [z2']
[x3 y3 z3 0 0 0 0 0 0] * [a20] = [x3']
[0 0 0 x3 y3 z3 0 0 0] [a21] [y3']
[0 0 0 0 0 0 x3 y3 z3] [a22] [z3']
[x4 y4 z4 0 0 0 0 0 0] [x4']
[0 0 0 x4 y4 z4 0 0 0] [y4']
[0 0 0 0 0 0 x4 y4 z4] [z4']
S * a = T
S
现在是一个矩阵,其中包含上述格式的四个源点,a
现在是您想要的矩阵中变换系数的向量解决(以行主格式排序),T
将是上述格式的目标点向量。
要求解参数,您只需在MATLAB中使用mldivide
运算符或\
,它将为您计算最小二乘估计值。因此:
a = S^{-1} * T
因此,只需像上面那样构建矩阵,然后使用\
运算符来求解矩阵中的变换参数。完成后,将T
重新整形为3 x 3矩阵。因此:
S = ... ; %// Enter in your source points here like above
T = ... ; %// Enter in your target points in a right hand side vector like above
a = S \ T;
similarity_matrix = reshape(a, 3, 3).';
关于每个坐标的小扰动中的误差,你得到的点越多越好。使用4肯定会给你一个解决方案,但它不足以减轻我认为的任何错误。
次要注意:这个(或多或少)是fitgeotrans
所做的。它在给定一堆源点和目标点的情况下计算出最佳单应性,并使用最小二乘法确定它。
希望这能回答你的问题!
答案 1 :(得分:1)
@rayryeng的答案是正确的,因为你在3
空间内有一组最多3-dimensional
个点。如果您需要转换m
空间(n-dimensional
)中的m>n
点,则首先需要将m-n
坐标添加到这些m
点,以便它们存在在m-dimensional
空间(即@rayryeng中的a
矩阵变成方阵)...然后@rayryeng描述的过程会给你精确的点变换,然后你只需要选择原始n-dimensional
空间中变换点的坐标。
举个例子,假设您要转换点数:
(2 -2 2) -> (-3 5 -4)
(2 3 0) -> (3 4 4)
(-4 -2 5) -> (-4 -1 -2)
(-3 4 1) -> (4 0 5)
(5 -4 0) -> (-3 -2 -3)
请注意,您有m=5
点n=3
- 维。因此,您需要为这些点添加坐标,使它们为n=m=5
- 维,然后应用@rayryeng描述的过程。
我已经实现了一个功能(在下面找到它)。您只需要组织点,使得每个源点都是矩阵u
中的列,并且每个目标点都是矩阵v
中的列。因此,u
和v
矩阵将3
分别为5
。
警告:强>
函数中的矩阵A可能需要大量内存用于中等多点nP
,因为它有nP^4
个元素。
为了解决这个问题,对于方形矩阵u
和v
,您只需在MATLAB表示法中使用T=v*inv(u)
或T=v/u
。
代码运行速度可能非常慢......
在MATLAB中:
u = [2 2 -4 -3 5;-2 3 -2 4 -4;2 0 5 1 0]; % setting the set of source points
v = [-3 3 -4 4 -3;5 4 -1 0 -2;-4 4 -2 5 -3]; % setting the set of target points
T = findLinearTransformation(u,v); % calculating the transformation
您可以通过以下方式验证T
是否正确:
I = eye(5);
uu = [u;I((3+1):5,1:5)]; % filling-up the matrix of source points so that you have 5-d points
w = T*uu; % calculating target points
w = w(1:3,1:5); % recovering the 3-d points
w - v % w should match v ... notice that the error between w and v is really small
计算变换矩阵的函数:
function [T,A] = findLinearTransformation(u,v)
% finds a matrix T (nP X nP) such that T * u(:,i) = v(:,i)
% u(:,i) and v(:,i) are n-dim col vectors; the amount of col vectors in u and v must match (and are equal to nP)
%
if any(size(u) ~= size(v))
error('findLinearTransform:u','u and v must be the same shape and size n-dim vectors');
end
[n,nP] = size(u); % n -> dimensionality; nP -> number of points to be transformed
if nP > n % if the number of points to be transform exceeds the dimensionality of points
I = eye(nP);
u = [u;I((n+1):nP,1:nP)]; % then fill up the points to be transformed with the identity matrix
v = [v;I((n+1):nP,1:nP)]; % as well as the transformed points
[n,nP] = size(u);
end
A = zeros(nP*n,n*n);
for k = 1:nP
for i = ((k-1)*n+1):(k*n)
A(i,mod((((i-1)*n+1):(i*n))-1,n*n) + 1) = u(:,k)';
end
end
v = v(:);
T = reshape(A\v, n, n).';
end