PCL中ROPS特征描述的实例

本文详细介绍了一种基于点云的特征描述方法ROPS的实现过程。从关键点的选取到三角面元信息的获取,再到ROPS特征的计算,提供了完整的代码示例。特别关注了.obj文件与点云文件的对应关系,以及.obj到.pcd文件的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相比于其他的特征描述,ROPS需要三个输入数据:

  1. points: 输入点云
  2. indices: RoPS特征点的标号(即关键点在点云中的下标)
  3. triangles:三角面元

首先介绍一下我获取indices的方法。我是用ISS3D求得关键点之后,调用getKeypointsIndices()函数实现的。具体程序如下:

pcl::PointIndicesPtr indices(new pcl::PointIndices());
......ISS3D计算关键点算法部分省略......
*indices = *iss.getKeypointsIndices();

然后是获取triangles三角面元信息。这里我是通过.obj文件生成的triangle.txt文件。生成程序如下(此处建议另新建一工程进行生成):

#include <fstream>//fstream类是把程序和文件关联起来
ifstream ifs("此处填写要输入的本地文件地址,如F:\\a.obj", ifstream::in);
ofstream ofs("此处填写用于存放生成文件的地址及文件名和类型,如F:\\triangle.txt", ofstream::out);
if(!ifs.is_open()){
	cout<<"error opening file. "
}
while(
	char *c = new char[256];
	if(!ifs.getline(c,256).eof()){break;}//到文件结尾循环结束
	if(c[0] == 'f'){
		int a[6]
		sscanf(c,"f %d//%d %d//%d %d//%d", &a[0],&a[1], &a[2], &a[3], &a[4], &a[5]);
		ofs<<a[0]-1<<" "<<a[2]-1<<" "<<a[4]-1<<endl;//-1的原因是obj格式的文件下标是从1开始存储的,而程序中是从0开始的
	}
)

通过上面的程序就可以获取自己的trianle.txt文件了,接下来就是在加载面元信息了。程序如下:

ifstream ifs("生成triangle.txt文件的路径", ifstream::in);
vector<pcl::Vertices> triangles;
while(1){
	pcl::Vertices triangle;
	int a[3];
	if(!ifs.getline(a, 3).eof()){break;}
	triangle.push_back(a[0]);
	triangle.push_back(a[1]);
	triangle.push_back(a[2]);
	triangles.push_back(triangle);
}

最后是实例化pcl::ROPSEstimation类

pcl::PointCloud<pcl::Histogram<135>>::Ptr rops_features(new pcl::PointCloud<pcl::Histogram<135>>())
float search_radius = 0.0285f;
int number_of_partition_bins = 5;
int number_of_rotations = 3;
pcl::ROPSEtimation<pcl::PointXYZ, pcl::Histogram<135>> rops;
pcl::search::KDTree<pcl::PointXYZ>::Ptr search_method(new pcl::search::KDTree<pcl::PointXYZ>);
search_method->setInputCloud(cloud);
rops.setSearchSurface(cloud);
rops.setInputCloud(cloud);
rops.setIndices(indices);
rops.setTriangles(triangles);
rops.setRadiusSearch(search_radius);
rops.setNumberOfPartitionBins(number_of_partition_bins);
rops.setNumberOfRotations(number_of_rotations);
rops.setSupportRadius(radius_search);

rops.compute(*rops_features);

经实践以上方法得到的indice和triangles 信息是正确的,但这里要注意生成triangle.txt文件时,要保证.obj文件和.pcd文件是对应的,否则就会出现段错误。
在这里补一个.obj转化为.pcd文件的程序。

#include <pcl/io/io.h>
#include <pcl/io/pcd_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所属头文件;
int main()
{
	pcl::PolygonMesh mesh;
	pcl::io::loadPolygonFileOBJ("F\\project\\a.obj", mesh);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::fromPCLPointCloud2(mesh.cloud, *cloud);
	pcl::io::savePCDFileASCII("F\\project\\a.pcd", *cloud);
	return 0;
}
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值