首先我们的问题是:
看懂 PCL 库计算 PCA 的结果,通过和 Matlab 相比。
首先,我们的数据是:
//这是5个点(p),每一行是p.x p.y p.z
-0.376005, -0.541869, -0.342539;
-0.184247, -0.617787, -0.348916;
-0.672017, -0.49449, 0.035638;
-0.556014, -0.604463, -0.575986;
-0.834069, -0.786591, -0.703937;
void Tools::PCA(PointCloud<PointT>::Ptr aimCloud, Vector4f *pcaCentroid,
Matrix3f *eigenVectorsPCA, Vector3f *eigenValuesPCA) {
pcl::compute3DCentroid(*aimCloud, *pcaCentroid);
Eigen::Matrix3f covariance;
pcl::computeCovarianceMatrixNormalized(*aimCloud, *pcaCentroid, covariance);
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f>eigenSolver(covariance, Eigen::ComputeEigenvectors);
*eigenVectorsPCA = eigenSolver.eigenvectors();
*eigenValuesPCA = eigenSolver.eigenvalues();
eigenVectorsPCA->col(2) = eigenVectorsPCA->col(0).cross(eigenVectorsPCA->col(1)); //校正主方向间垂直
eigenVectorsPCA->col(0) = eigenVectorsPCA->col(1).cross(eigenVectorsPCA->col(2));
eigenVectorsPCA->col(1) = eigenVectorsPCA->col(2).cross(eigenVectorsPCA->col(0));
}
//计算点云的PCA
Vector4f pcaCentroid;
Matrix3f eigenVectorsPCA;
Vector3f eigenValuesPCA;
//cloud是只有上述5个点的点云
tools->PCA(cloud, &pcaCentroid, &eigenVectorsPCA, &eigenValuesPCA);
cout << "特征值(3x1):\n" << eigenValuesPCA << endl;
cout << "质心(3x1):\n" << pcaCentroid << endl;
cout << "特征向量(3x3):\n" << eigenVectorsPCA << endl;
计算结果是:
特征值(3x1):
0.00201173
0.0439675
0.0787971
质心(3x1):
-0.524471
-0.60904
-0.387148
1
特征向量(3x3):
-0.0959844 -0.877313 0.470221
0.946544 0.0657084 0.315809
-0.307961 0.475398 0.824109
feature = [
-0.376005, -0.541869, -0.342539;
-0.184247, -0.617787, -0.348916;
-0.672017, -0.49449, 0.0356387;
-0.556014, -0.604463, -0.575986;
-0.834069, -0.786591, -0.703937;
];
[coeff, score, latent, tsquared, explained, mu] = pca(feature)
计算结果是:
coeff =
0.4702 0.8773 -0.0960
0.3158 -0.0657 0.9465
0.8241 -0.4754 -0.3080
score =
0.1278 0.1046 0.0356
0.1887 0.2809 -0.0527
0.3152 -0.3380 -0.0076
-0.1690 0.0618 0.0655
-0.4627 -0.1093 -0.0408
latent =
0.0985
0.0550
0.0025
tsquared =
0.8687
2.9020
3.1101
2.0664
3.0528
explained =
63.1507
35.2371
1.6123
mu =
-0.5245 -0.6090 -0.3871
1、COEFF,返回N×P数据矩阵X的主成分系数。X的行对应于观测值,列对应于变量。
每列系数包含一个主成分的系数。各列按主成分方差(latent)降序排列。
默认情况下,PCA将数据居中并使用奇异值分解算法。对于非默认选项,请使用名称/值对参数。
--------------------------------------------------------------------------------------
coeff = 特征向量(3x3):
0.4702 0.8773 -0.0960 -0.0959844 -0.877313 0.470221
0.3158 -0.0657 0.9465 0.946544 0.0657084 0.315809
0.8241 -0.4754 -0.3080 -0.307961 0.475398 0.824109
--------------------------------------------------------------------------------------
其实是一样的,只是PCA里面对轴的方向做出了调整。
=========================================================================================
2、SCORE,返回主成分得分,它是X在主成分空间中的表示。
score的行对应观察值,列对应主成分。中心数据可以用SCORE*COEFF'重建。
--------------------------------------------------------------------------------------
score =
0.1278 0.1046 0.0356
0.1887 0.2809 -0.0527
0.3152 -0.3380 -0.0076
-0.1690 0.0618 0.0655
-0.4627 -0.1093 -0.0408
--------------------------------------------------------------------------------------
PCL没有算这个
=========================================================================================
3、LATENT,返回每个主成分方差,即X的协方差矩阵的特征值,特征值从大到小进行排序。
--------------------------------------------------------------------------------------
latent =
0.0985
0.0550
0.0025
--------------------------------------------------------------------------------------
PCL没有算这个
=========================================================================================
4、TSQUARED,返回X中每个观测值的Hotelling T平方统计值。
--------------------------------------------------------------------------------------
tsquared =
0.8687
2.9020
3.1101
2.0664
3.0528
--------------------------------------------------------------------------------------
PCL没有算这个
=========================================================================================
5、EXPLAINED,返回一个向量,其中包含每个主成分方差占总方差的百分比。
--------------------------------------------------------------------------------------
explained = PCL手算的结果
63.1507 0.01612268929531747
35.2371 0.35237051770956884
1.6123 0.6315067929951137
--------------------------------------------------------------------------------------
PCL这个得自己算:
sum = 0.00201173 + 0.0439675 + 0.0787971
print(0.00201173 / sum)
print(0.0439675 / sum)
print(0.0787971 / sum)
=========================================================================================
6、MU,“Centered”设置为true时返回估计的平均值MU;设置为false时返回所有零。
--------------------------------------------------------------------------------------
mu =
-0.5245 -0.6090 -0.3871
质心(3x1):
-0.524471
-0.60904
-0.387148
1
--------------------------------------------------------------------------------------
PCL第四个值不要就可以了。
=========================================================================================