点云去质心 pcl

本文介绍了一段C++代码,用于使用PCL库对点云数据进行去质心操作。首先,程序加载了.obj格式的点云数据,然后计算了质心,并通过两种不同的方法执行了去质心:直接调用demeanPointCloud()函数和手动循环实现。尽管理论上去质心后的质心应为(0,0,0),但实际结果存在微小误差,这是由于数值计算的截断误差。最后,程序将去质心后的点云保存为.pcd文件。
摘要由CSDN通过智能技术生成

日期:2021/12/2
参考链接:http://it.ckcest.cn/article-3992715-1.html

代码

网上公开的点云去质心的程序比较少,此处结合实际应用对参考程序进行修改,代码如下:

#include <pcl/io/pcd_io.h>
#include <pcl/common/centroid.h>
#include <iostream>

#include <vtkAutoInit.h>
#include <pcl/io/io.h>
#include <pcl/io/obj_io.h>
#include <pcl/PolygonMesh.h>
#include <pcl/point_cloud.h>
#include <pcl/io/vtk_lib_io.h> //loadPolygonFileOBJ所属头文件;
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

int main()
{
	//加载点云,此处输入为.obj文件
    std::string fileName = "/home/sun/Fast_RNRR/data/test/source.obj"; //输入文件地址;    
    pcl::PolygonMesh meshData; //读取原始数据
    pcl::io::loadPolygonFile(fileName,meshData);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in;
    cloud_in.reset(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPCLPointCloud2(meshData.cloud, *cloud_in);//将obj数据转换为点云数据
	// if (pcl::io::loadPCDFile(fileName, *cloud_in) < 0)
	// {
	// 	PCL_ERROR("该点云文件不存在!");
	// 	return -1;
	// }

	//计算输入点云质心
	Eigen::Vector4f centroid_in;
	pcl::compute3DCentroid(*cloud_in, centroid_in);
	cout << "质心坐标为:" << "core_x:" << centroid_in[0] << endl << "core_y:" << centroid_in[1] << endl << "core_z:" << centroid_in[2] << endl;
	
	/*-----执行去质心-----*/
	//方式1:调用demeanPointCloud()函数
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out1(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::demeanPointCloud(*cloud_in, centroid_in, *cloud_out1);
	//计算去质心后点云质心
	Eigen::Vector4f centroid_out1;
	pcl::compute3DCentroid(*cloud_out1, centroid_out1);
	cout << "方式1去质心后质心坐标为:" << "core_x:" << centroid_out1[0] << endl << "core_y:" << centroid_out1[1] << endl << "core_z:" << centroid_out1[2] << endl;

	//方式2:循环实现
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out2(new pcl::PointCloud<pcl::PointXYZ>);
	*cloud_out2 = *cloud_in;
	for (size_t i = 0; i < cloud_in->size(); ++i)
	{
		cloud_out2->points[i].x = cloud_in->points[i].x - centroid_in[0];
		cloud_out2->points[i].y = cloud_in->points[i].y - centroid_in[1];
		cloud_out2->points[i].z = cloud_in->points[i].z - centroid_in[2];
	}
	//计算去质心后点云质心
	Eigen::Vector4f centroid_out2;
	pcl::compute3DCentroid(*cloud_out2, centroid_out2);
	cout << "方式2去质心后质心坐标为:" << "core_x:" << centroid_out2[0] << endl << "core_y:" << centroid_out2[1] << endl << "core_z:" << centroid_out2[2] << endl;

	//两种去质心方式的比较
	cout << "两种去质心方式的差值:" << endl;
	cout << "delt_x=" << centroid_out1[0] - centroid_out2[0] << endl << "delt_y=" << centroid_out1[1] - centroid_out2[1] << endl << "delt_z=" << centroid_out1[2] - centroid_out2[2] << endl;

	//保存去质心后点云
	if (!cloud_out1->empty())
	{
	//保存的文件名为cloud0.pcd,默认保存位置为build文件夹下
		pcl::io::savePCDFileBinary("cloud0.pcd", *cloud_out1); 
	}

	return 0;
}

运行结果

程序运行结果如下:
在这里插入图片描述

结果分析

根据理论分析,点云去质心之后的质心坐标应该是(0,0,0),可是实际的结果却不是零,而是一个接近零的数,这是合理的,因为计算机的结果是数值解,会存在截断误差。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

兔子的倔强

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

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

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

打赏作者

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

抵扣说明:

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

余额充值