我正在尝试在Python中进行刚体变换,通过仅允许源点集绕源和目标共享的一个点(即第二点)旋转,将源点集注册到目标点集。我基本上通过减去用户定义的旋转中心而不是质心来平移源和目标。然后我申请了
np.linalg.svd
以获得 rotation_matrix
。
但是,当我尝试不同精度的源点和目标点时,它们得到了完全不同的结果。
第一组源和目标是:
source_points = np.array([[29.930, 65.059, -692.872], [20.588, 38.868, -675.454], [18.266, 57.316, -682.061]])
target_points = np.array([[27.474, 61.970, -689.958], [20.588, 38.868, -675.454], [15.340, 60.875, -681.762]]) # Your target points
脚本是https://github.com/chz31/surgical_plate_registration/blob/main/proper_svd.py
我得到了一个整洁的旋转变换矩阵,它产生了良好的对齐效果
array([[ 0.99795083, -0.05814411, 0.02670959],
[ 0.05909811, 0.99758699, -0.03643628],
[-0.02452659, 0.0379401 , 0.99897898]])
第二组源和目标具有更高的精度,但本质上是相同的点:
source_points = np.array([[29.92973456, 65.05863408, -692.87207321], [20.58772087,38.86774826, -675.45440674],[18.2662661, 57.31554544, -682.06144071]])
target_points = np.array([[27.47413063, 61.97033691, -689.95812988], [20.58772087, 38.86774826, -675.45440674], [15.33987617, 60.87537766, -681.76153564]])
脚本为:https://github.com/chz31/surgical_plate_registration/blob/main/svd_deform_error.py
然后我得到了完全不同的转变:
array([[ 0.49127036, -0.40722086, -0.76995104],
[-0.2900711 , 0.75702601, -0.58546595],
[-0.82128691, -0.51096261, -0.25378144]])
因此,对于第二组,我重建的齐次变换矩阵本质上使源变形。对于刚体配准,它不应使源变形。
#translation
t = rotation_center.T - np.dot(rotation_matrix, rotation_center.T)
#homogeneous transform matrix
T = np.identity(4)
T[:3, :3] = rotation_matrix
T[:3, 3] = t
我认为这两个脚本应该产生非常相似的结果,因为它们本质上是相同的点,只是精度不同。特别是,刚性变换不应使源变形。谁能就我做错了什么或为什么会发生这种情况提出一些建议?
好吧,我忘了旋转矩阵的符号可能会被反映的情况。
Adding this piece solved the problem:
# special reflection case
m = translated_source_points.shape[1]
if np.linalg.det(rotation_matrix) < 0:
Vt[m - 1, :] *= -1 rotation_matrix = np.dot(Vt.T, U.T)