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;

 

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
计算点云平面的平均向量,可以使用PCL库中pcl::NormalEstimation类。该类提供了估计点云向量的功能。使用该类的方法如下: 1. 创建pcl::NormalEstimation对象并设置输入点云数据。 2. 设置搜索方法(例如使用KD树)和搜索半径。 3. 调用compute()函数来计算向量。 4. 访问pcl::NormalEstimation对象的结果,可以通过调用getNormalIndices()函数获取向量的索引,调用getNormals()函数获取向量数据。 具体的步骤如下: 1. 导入所需的库和头文件: ``` #include <pcl/features/normal_3d.h> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> ``` 2. 创建pcl::PointCloud对象来存储输入点云数据: ``` pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); ``` 3. 从文件中读取点云数据: ``` pcl::io::loadPCDFile<pcl::PointXYZ>("input_cloud.pcd", *cloud); ``` 4. 创建pcl::NormalEstimation对象: ``` pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; ``` 5. 设置输入点云数据: ``` ne.setInputCloud(cloud); ``` 6. 设置搜索方法和搜索半径: ``` pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>()); ne.setSearchMethod(tree); ne.setRadiusSearch(0.01); // 设置半径为0.01米 ``` 7. 创建pcl::PointCloud对象来存储向量数据: ``` pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); ``` 8. 调用compute()函数来计算向量: ``` ne.compute(*normals); ``` 9. 访问向量数据: ``` for (int i = 0; i < normals->size(); ++i) { pcl::Normal normal = normals->points[i]; // 使用normal.x, normal.y, normal.z 来访问向量的三个分量 } ``` 请注意,上述代码是一个简化的示例,实际使用时需要根据自己的需求进行适当修改和调整。同时,还可以根据具体情况选择其他PCL库中提供的方法计算点云平面的平均向量。 引用了内容:pcl::NormalEstimation类的使用方法 引用了内容:使用PCA主成分分析实现的向量估计方法 引用了内容:基于PCL库的向量估计方法<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [PCL 计算点云向量并显示](https://blog.csdn.net/qq_36686437/article/details/105559280)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [基于最小二乘估计点云的曲面向量(PCL编程实现)](https://download.csdn.net/download/lming_08/7035195)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溯夜流云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值