NumPy中齐次坐标矩阵乘法实现坐标变换结果异常的问题求助
NumPy中齐次坐标矩阵乘法实现坐标变换结果异常的问题求助
大家好,我最近在处理3D点集的坐标变换时碰到了一个百思不得其解的问题,想请各位大佬帮忙分析下原因。
我这边的情况是:有一个4×4的变换矩阵T,它的形式固定是[[R , t], [ 0, 1]](这点我可以百分百确定);还有一个需要变换的点集points,形状是(M,3),M通常在1k到2k之间。
我的问题在于:当我用方法1(齐次坐标法)做变换时,结果是错误的——具体来说,部分变换后的齐次点(points_local_homogeneous)最后一位不等于1,这显然不对;但用方法2拆分矩阵计算时,所有结果都是正确的。
下面是两种方法的代码:
# Method 1: wrong result. ones = np.ones((points.shape[0], 1)) points_homogeneous = np.hstack((points, ones)) points_local_homogeneous = (T @ points_homogeneous.T).T points_local = points_local_homogeneous[:, :3] # Method 2: Good results. points_local= (T[:3, :3] @ points.T).T + T[:3, 3]
还有一个更诡异的现象能反映这个问题:先做矩阵乘法再提取单个点,结果是错的;但先提取单个点再做矩阵乘法,结果却是正确的:
>>> (T @ points_homogeneous.T).T[547] array([-15.44923687, -0.03295934, -0.07585889, -15.45439878]) >>> T @ points_homogeneous[547] array([6.58938647, 3.43626129, 2.84996901, 1. ])
我已经准备了最小可复现示例,方便大家测试:
import numpy as np T =np.array([[-9.99997984e-01, 2.00338436e-03, 1.36517526e-04,2.30385575e+01], [-2.00432316e-03, -9.99971609e-01, -7.26382636e-03,3.48879370e+00], [ 1.21961414e-04, -7.26408534e-03, 9.99973609e-01,-5.29494007e-02], [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,1.00000000e+00]]) points = np.random.random((1000,3)) print(points) ones = np.ones((points.shape[0], 1)) points_homogeneous = np.hstack((points, ones)) points_local_homogeneous = (T @ points_homogeneous.T).T print(points_local_homogeneous) points_local = points_local_homogeneous[:, :3] print(points_local) points_local= (T[:3, :3] @ points.T).T + T[:3, 3] print(points_local)
运行后的输出如下:
points: [[0.70431115 0.18240672 0.33961428] [0.03708955 0.67343087 0.82448419] [0.56714298 0.73581627 0.6482321 ] ... [0.57882963 0.04147515 0.05351834] [0.67357367 0.02644866 0.19563735] [0.86036017 0.27597764 0.63466743]] points_local_homogeneous: [[ 2.23346596e+01 3.30251359e+00 2.85416795e-01 1.00000000e+00] [ 2.30029297e+01 2.80931870e+00 7.66625690e-01 1.00000000e+00] [ 2.24729783e+01 2.74715294e+00 5.89989729e-01 1.00000000e+00] ... [ 4.21157332e-01 -1.46142995e-03 9.03349144e-01 5.65885052e-01] [ 3.26428767e-01 -1.54217777e-03 5.56317837e-01 4.18719365e-01] [ 1.39730259e-01 -3.72909348e-03 6.30229075e+00 1.10249332e+00]] points_local(Method 1): [[ 2.23346596e+01 3.30251359e+00 2.85416795e-01] [ 2.30029297e+01 2.80931870e+00 7.66625690e-01] [ 2.24729783e+01 2.74715294e+00 5.89989729e-01] ... [ 4.21157332e-01 -1.46142995e-03 9.03349144e-01] [ 3.26428767e-01 -1.54217777e-03 5.56317837e-01] [ 1.39730259e-01 -3.72909348e-03 6.30229075e+00]] points_local(Method 2): [[2.23346596e+01 3.30251359e+00 2.85416795e-01] [2.30029297e+01 2.80931870e+00 7.66625690e-01] [2.24729783e+01 2.74715294e+00 5.89989729e-01] ... [2.24598194e+01 3.44577082e+00 3.36839801e-04] [2.23650649e+01 3.45957466e+00 1.42572815e-01] [2.21788386e+01 3.20648934e+00 5.79801482e-01]]
可以看到,points_local_homogeneous的最后一列应该全是1.0,但实际并不是,而且方法1和方法2的结果差异很大。我实在搞不懂为什么会这样,有没有朋友能帮我解惑?
备注:内容来源于stack exchange,提问作者pei
相关产品推荐
相关产品推荐

