从4x4齐次变换矩阵中移除旋转部分

6
我正在处理一个转换矩阵,我的目标是移除旋转变换,保留缩放、平移等变换。
我该怎么做?我想要创建一个手动编程的解决方案。
4个回答

3

2
4×4齐次变换矩阵的定义如下:
| x2 |   | R11*SX R12*SY R13*SZ TX | | x1 |
| y2 | = | R21*SX R22*SY R23*SZ TY | | y1 |
| z2 |   | R31*SX R32*SY R33*SZ TZ | | z1 |
| 1  |   | 0      0      0      1  | |  1 |

其中(SX,SY,SZ)为缩放因子,(TX,TY,TZ)为平移因子,Rij为旋转系数。

获取平移很简单,只需选择最后一列即可。要获取缩放比例,可以利用变换是旋转乘以对角线缩放的属性(A=R*S),因此

tr(A)*A = tr(R*S)*(R*S) = tr(S)*tr(R)*R*S = tr(S)*S

其中tr(A)表示转置操作符。要获取缩放因子,请计算

S2 = tr(A)*A

并选择前三个对角线元素的平方根

SX = sqrt(S2(1,1))
SY = sqrt(S2(2,2))
SZ = sqrt(S2(3,3))

然后按以下方式组装新的转换:
| SX   0   0  TX |
|  0  SY   0  TY |
|  0   0  SZ  TZ |
|  0   0   0   1 |

2
如果你确定你的矩阵是旋转+平移+缩放的,那么你只需要提取你所需的参数即可:
rotation = atan2(m12, m11)
scale = sqrt(m11*m11 + m12*m12)
translation = (m31, m32)

编辑

我没有注意到你对3D变换感兴趣,如果是这样,旋转部分可能会让人感到烦恼,但如果你只想进行平移和缩放...

translation = (m41, m42, m43)
scale = sqrt(m11*m11 + m12*m12 + m13*m13)

2
如果只有平移、缩放和旋转,那么可以通过提取平移和缩放分量并将它们相乘来消除旋转,并忽略剩下的部分... - Dan
1
还有,你的缩放是否假设在每个方向上都是均匀的?这可能并不是实际情况,例如图像可能会被拉伸。 - Dan
@Dan:所谓“烦人”,我指的是用自由坐标表示旋转的“本质”无法像在二维中那样完美地呈现(参见万向节锁问题)。关于缩放,请注意,如果允许非均匀缩放和旋转,则闭合性变得更加普遍,甚至在远离奇点scale=0时,旋转角度的概念也变得值得怀疑。 - 6502
1
问题在于矩阵不限于均匀缩放,并且是三维的。 - brain56

0
到目前为止我不喜欢任何一个解决方案。一个3x4(或4x4)的仿射变换首先应用旋转,然后在目标帧中进行平移。该变换中的最后一列向量是平移向量,但是在目标坐标系中,而不是原始坐标系中!因此,如果我们反转该变换,则可以将最后一列向量作为原始坐标系中的平移向量。

以下是我的方法(使用numpy):

b_to_a = np.linalg.inv(a_to_b)
a_to_b_only_translation = np.eye(4)
a_to_b_only_translation[:,3] = -b_to_a[:,3]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接