有些项目实现需要平面点云整体的法向量.
求平面法向量与拟合平面本质是一样的.我们也可以用LS来求取,这里给出了pca的方法和部分代码
LS 的在这里pcl 最小二乘求平面点云法向量-CSDN博客
void find_elipse_center_opencv::pca_PointXYZ(CP CloudIn, Vector3f& values, Matrix3f& vectors) {
Matrix3f covariance1 = Matrix3f::Zero();
//Matrix3f covariance2 = Matrix3f::Zero();
MatrixXf xyz_id = CloudIn->getMatrixXfMap(3, 4, 0);
Vector3f xyz_mean = xyz_id.rowwise().mean();
xyz_id = xyz_id.colwise()-xyz_mean;
int cloud_size = CloudIn->size();
//计算X^T*X,可以单算协方差矩阵每个位置的值,也可以像下面这种直接成
for (int i = 0; i < cloud_size; i++) {//直接乘的X^T*X
covariance1 += xyz_id.col(i) * (xyz_id.col(i).transpose());
}
covariance1 /= cloud_size;
Eigen::SelfAdjointEigenSolver<Matrix3f> es(covariance1);
if (es.info() != Eigen::Success) {
cout << "pca失败" << endl;
return;
}
vectors = es.eigenvectors();
values = es.eigenvalues();
vectors.colwise().normalize();
return;
//分开算的
/*float x2 = xyz_id.row(0) * (xyz_id.row(0).transpose());
float y2 = xyz_id.row(1) * (xyz_id.row(1).transpose());
float z2 = xyz_id.row(2) * (xyz_id.row(2).transpose());
float xy = xyz_id.row(0) * (xyz_id.row(1).transpose());
float xz = xyz_id.row(0) * (xyz_id.row(2).transpose());
float yz = xyz_id.row(1) * (xyz_id.row(2).transpose());
Matrix3f covariance2;
covariance2 << x2, xy, xz, xy, y2, yz, xz, yz, z2;
covariance2 /= cloud_size;*/
//for (int k = 0; k < 2; k++) {
// int temp = CloudIn->size() / 2;
// for (int i = temp * k; i < temp * k + temp; i++) {
// }
//}
}