点云处理基础操作

PCL点云处理基础操作

  • 点云定义(还是点云指针定义?一直搞不懂)
  • 1. 读取和保存点云
  • 批量存取时文件名写法
  • 2. 定义一个新的点云
  • 3. 去除NAN点

点云定义(还是点云指针定义?一直搞不懂)

//常用
typedef pcl::PointXYZRGBA PointT;
pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
//两个一起定义:pcl::PointCloud::Ptr cloud(new pcl::PointCloud), cloud_f(new pcl::PointCloud);

pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);//带法线的点云
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);//法线

1. 读取和保存点云

这两种方法不知道有什么区别,先记下来吧
法一:

#include 
#include 
typedef pcl::PointXYZRGBA PointT;

pcl::PCDReader reader;
pcl::PLYReader reader1;
reader.read("tree3.pcd", *cloud);
reader1.read("cow_final1_RORFed.ply", *cloud);
pcl::PCDWriter writer;
pcl::PLYWriter writer1;
writer.write<PointT> ("tree3.pcd", *every_cluster, false);
writer1.write<PointT> ("tree3.pcd", *every_cluster, false);

法二:

#include 
#include 

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 创建点云(指针)
if (pcl::io::loadPLYFile<pcl::PointXYZ>("2020- 6- 9-10-0passthrough.ply", *cloud) <0) //* 读入PLY格式的文件,如果文件不存在,返回-1
{
	PCL_ERROR("Couldn't read file test_pcd.pcd \n"); //文件不存在时,返回错误,终止程序。
	getchar();
	return (-1);
}

pcl::io::savePLYFile("test.ply", *cloud, true);

批量存取时文件名写法

string和stringstream区别:string和stringstream用法总结

//简单版批量存储
//(在for循环里面)
std::stringstream ss, ss1;
ss << "tree3_cluster_" << j << ".pcd";
ss1<< "tree3_cluster_" << j << ".ply";
writer.write<PointT> (ss.str (), *every_cluster, false);
writer1.write<PointT> (ss1.str(), *every_cluster, false);
	j++;

结合结构体以及字符串对点云进行批量存取:

//复杂版批量读取点云和存储点云
#include 
#include 
#include  
#include 

string num2str(int i)
{
	stringstream ss;
	ss << i;
	return ss.str();
}

//定义结构体,用于处理点云
struct PLY
{
	std::string f_name; //文件名
	pcl::PointCloud<pcl::PointNormal>::Ptr cloudWithNormal;//存储估计的法线的指针
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;//存储点云
	//构造函数
	PLY() : cloud(new pcl::PointCloud<pcl::PointXYZ>),cloudWithNormal(new pcl::PointCloud<pcl::PointNormal>){}; //初始化
};

int main()
{
	const int numberOfViews = 6;//文件数量
	std::vector<PLY, Eigen::aligned_allocator<PCD> > data; //点云数据
	std::vector<PLY, Eigen::aligned_allocator<PCD> > data1; //点云数据
	std::string prefix("cow1");
	std::string extension("_withNormal_boundary.ply"); //声明并初始化string类型变量extension,表示文件后缀名
	// 通过遍历文件名,读取ply文件
	for (int i = 0; i < numberOfViews; i++) //遍历所有的文件名
	{
		std::string fname = prefix + num2str(i) + extension;
		// 读取点云,并保存到models
		PLY m;
		m.f_name = fname;
		if (pcl::io::loadPLYFile(fname, *m.cloud) == -1) //* 读入PCD格式的文件,如果文件不存在,返回-1
		{
			cout << "Couldn't read file " + fname + "." << endl; //文件不存在时,返回错误,终止程序。
			return (-1);
		}
		data.push_back(m);
	}
//这样之后data[i].cloud就代表一个点云,共六个
//批量存储点云
	for (int i = 0; i < numberOfViews; ++i)
	{
		std::string fname = prefix + num2str(i) + "_rotate" + extension;
		pcl::io::savePLYFile(fname, *data[i].cloudWithNormal, true);
	}
	
	return 0;
}

还可以批量进行其他操作,比如离群点滤波

	//-----------------------去除离群点------------------------
	std::vector<PCD, Eigen::aligned_allocator<PCD> > data1; //这里新定义了一个算是数组?好像滤波之后的点云不能重复赋值到这个数组里
	pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
	outrem.setRadiusSearch(0.01);
	outrem.setMinNeighborsInRadius(5);
	for (int i = 0; i < numberOfViews; ++i)
	{
		PLY a;//这里新定义了一个结构体
		outrem.setInputCloud(data[i].cloud);
		outrem.filter(*a.cloud);
		data1.push_back(a);
	}

2. 定义一个新的点云

*cloud是已知的点云
*newcloud是新点云

pcl::PointCloud<pcl::PointXYZRGB>::Ptr newcloud(new pcl::PointCloud<pcl::PointXYZRGB>); // 创建点云(指针)

newcloud->height = cloud->height;//或者直接这个newcloud->height = 1;一般好像点云这个都是1
newcloud->width = cloud->width;//*cloud是已知的点云
newcloud->is_dense = false;

也可以直接复制点云

pcl::PointCloud<pcl::PointXYZRGB>::Ptr newcloud(new pcl::PointCloud<pcl::PointXYZRGB>); // 创建点云(指针)

pcl::copyPointCloud(*cloud, *newcloud);//把cloud复制给newcloud(然后就可以直接用newcloud了,里面就有相应点的坐标了,相当于把指针赋值了吧)
//一顿操作之后newcloud里面一些点被修改,需要保存起来,如下:
newcloud->height = 1;
newcloud->width = newcloud->points.size();
newcloud->is_dense = false;

3. 去除NAN点

//去除NAN点
	std::vector<int> mapping;
	pcl::removeNaNFromPointCloud(*pcloud, *pcloud, mapping);
	std::cout << "原始点云去除NaN点后数量: " << pcloud->points.size() << std::endl;

你可能感兴趣的:(PCL,点云处理,C++)