pcl点云库中,使用pca计算某块平面区域的法向量

之前做过一个基于深度相机的图像矫正,其中使用深度相机计算了需要矫正的平面图像区域对应的法向量。

本来是直接使用pcl提供的分割接口,但是使用的过程中发现不是很稳定,所以就用pca的方法写了一下。

主要原理:pca的方法计算出了特征值和特征向量。再结合平面点云在法向量方向的差异是最小的,那么特征值最小的特征向量即为法向量,具体原理可以百度其他大佬的博客。

Eigen::Vector3f 	minVec;//待测平面的法向量
//定义每个表面小块的3x3协方差矩阵的存储对象

	Eigen::Matrix3f covariance_matrix;

	//定义一个表面小块的质心坐标16字节对齐存储对象

	Eigen::Vector4f xyz_centroid;

	//估计质心坐标

	pcl::compute3DCentroid(*cut, xyz_centroid);

	//计算3x3协方差矩阵

	pcl::computeCovarianceMatrix(*cut, xyz_centroid, covariance_matrix);
	Eigen::EigenSolver<Eigen::Matrix3f> es(covariance_matrix);
	Eigen::Matrix3f val = es.pseudoEigenvalueMatrix();
	Eigen::Matrix3f vec = es.pseudoEigenvectors();
	//cout << "特征值:" << endl << es.eigenvalues() << endl << endl;
	cout << "特征值:" << endl << val << endl << endl;
	// cout << "特征向量:" << endl << es.eigenvectors() << endl << endl;
	cout << "特征向量:" << endl << vec << endl << endl;
	int minVal = 0;
	if (val(0, 0) > val(1, 1))
	{
		minVal = 1;
	}
	if (val(minVal, minVal) > val(2, 2))minVal = 2;

	for (int i = 0; i < 3; i++)
	{
		minVec(i) = vec(i, minVal);
	}
	cout << "特征值最小为第:" << minVal + 1 << "个" << endl;
	cout << "该特征值为" << val(minVal, minVal) << endl;
	cout << "该特征向量为" << minVec << endl;

猜你喜欢

转载自blog.csdn.net/weixin_42067304/article/details/110705864