将 PCA 组件与笛卡尔轴对齐并旋转
Align PCA component with cartesian axis with rotation
我正在尝试旋转我的点云,使最不重要的 PCA 分量与 z 轴对齐,但收效甚微。
我先计算PCA成分
U, S, Vt = np.linalg.svd(vertices - vertices.mean(axis=0), full_matrices=False)
但是我在构造旋转矩阵时遇到了问题,我尝试了 scipy.spatial.transform.Rotation
和 from_rotvec()
方法,但我不确定我做错了什么,因为结果看起来不像我想要的期待。
angles = np.arctan2(Vt[:, 2], np.array([0, 0, 1]))
rot = scipy.spatial.transform.Rotation.from_rotvec(angles)
new_vertices = np.dot(vertices, rot.T)
我生成了一个示例数据如下
import numpy as np;
import matplotlib.pyplot as plt
vertices = np.random.randn(10000, 2) / 2
vertices[:, 0] *= 3
vertices[:, 1] += vertices[:, 0] * 0.5;
vc = vertices - vertices.mean(axis=0)
U, S, Vt = np.linalg.svd(vc)
vr = vc @ Vt.T
plt.figure(figsize=(10, 5))
plt.subplot(1,2,1)
plt.title('original vertices')
plt.scatter(vc[:, 0], vc[:, 1], alpha=0.1), plt.xlim([-6, 6]), plt.ylim([-6, 6])
plt.subplot(1,2,2)
plt.title('rotated vertices')
plt.scatter(vr[:, 0], vr[:, 1], alpha=0.1), plt.xlim([-6, 6]), plt.ylim([-6, 6])
基本上X = U[:, :2] @ np.diag(S) @ Vt
,
np.allclose(U[:, :2] @ np.diag(S) @ Vt, vc)
U
是正交的,S
只是缩放U
的列,Vt
应用旋转。如果我们将等式的两边都乘以 inv(Vt) = Vt.T
,我们得到对齐的点。
我正在尝试旋转我的点云,使最不重要的 PCA 分量与 z 轴对齐,但收效甚微。
我先计算PCA成分
U, S, Vt = np.linalg.svd(vertices - vertices.mean(axis=0), full_matrices=False)
但是我在构造旋转矩阵时遇到了问题,我尝试了 scipy.spatial.transform.Rotation
和 from_rotvec()
方法,但我不确定我做错了什么,因为结果看起来不像我想要的期待。
angles = np.arctan2(Vt[:, 2], np.array([0, 0, 1]))
rot = scipy.spatial.transform.Rotation.from_rotvec(angles)
new_vertices = np.dot(vertices, rot.T)
我生成了一个示例数据如下
import numpy as np;
import matplotlib.pyplot as plt
vertices = np.random.randn(10000, 2) / 2
vertices[:, 0] *= 3
vertices[:, 1] += vertices[:, 0] * 0.5;
vc = vertices - vertices.mean(axis=0)
U, S, Vt = np.linalg.svd(vc)
vr = vc @ Vt.T
plt.figure(figsize=(10, 5))
plt.subplot(1,2,1)
plt.title('original vertices')
plt.scatter(vc[:, 0], vc[:, 1], alpha=0.1), plt.xlim([-6, 6]), plt.ylim([-6, 6])
plt.subplot(1,2,2)
plt.title('rotated vertices')
plt.scatter(vr[:, 0], vr[:, 1], alpha=0.1), plt.xlim([-6, 6]), plt.ylim([-6, 6])
基本上X = U[:, :2] @ np.diag(S) @ Vt
,
np.allclose(U[:, :2] @ np.diag(S) @ Vt, vc)
U
是正交的,S
只是缩放U
的列,Vt
应用旋转。如果我们将等式的两边都乘以 inv(Vt) = Vt.T
,我们得到对齐的点。