You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 18:40:26