用FPFH进行特征点的提取

该博客展示了如何使用PCL库中的FPFH特征提取方法,对RGB点云进行处理,通过KdTree搜索和阈值判断生成不同颜色的FPFH Signature,同时计算并输出处理时间和异常点数量。最后将处理后的点云保存为PCD文件并可视化。
摘要由CSDN通过智能技术生成
#include <iostream>
#include <pcl/io/pcd_io.h> 
#include <pcl/point_types.h> 
#include <pcl/visualization/cloud_viewer.h> 
#include <pcl/visualization/histogram_visualizer.h>
#include <pcl/point_types.h>
#include <pcl/features/fpfh.h>
#include <pcl/filters/fast_bilateral.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_plotter.h>
#include <vtkAutoInit.h>  
#include <string.h>

#define vtkRenderingCore_AUTOINIT 3(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingOpenGL2) 
VTK_MODULE_INIT(vtkRenderingOpenGL);
using namespace std;



pcl::PointCloud<pcl::PointXYZRGB>::Ptr computeFPFH(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_origin, pcl::PointCloud<pcl::Normal>::Ptr cloud_normals)
{
	float radius;
	int k_number;
	int pf_num = 0;
	cout << "input radius/k_nubmer of fpfh_search: ";
	//cin >> radius;
	cin >> k_number;
	clock_t start, finish;
	start = clock();
	pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
	fpfh.setInputCloud(cloud_origin);
	fpfh.setInputNormals(cloud_normals);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
	fpfh.setSearchMethod(tree);
	pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_fe_ptr(new pcl::PointCloud<pcl::FPFHSignature33>());
	//pfh.setRadiusSearch(radius);
	fpfh.setKSearch(k_number);
	fpfh.compute(*fpfh_fe_ptr);

	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_b(new pcl::PointCloud<pcl::PointXYZRGB>);
	cloud_b->resize(cloud_origin->size());
	for (int i = 0; i < cloud_origin->points.size(); i++)
	{
		cloud_b->points[i].x = cloud_origin->points[i].x;
		cloud_b->points[i].y = cloud_origin->points[i].y;
		cloud_b->points[i].z = cloud_origin->points[i].z;
	}

	Eigen::Vector3d d, n1, n2;
	double d_x, d_y, d_z;
	for (int i = 0; i < fpfh_fe_ptr->points.size(); i++)
	{
		if (fpfh_fe_ptr->points[i].histogram[16] < 50)
		{
			pf_num++;
			cloud_b->at(i).r = 255;
			cloud_b->at(i).g = 0;
			cloud_b->at(i).b = 0;
		}
		else
		{
			cloud_b->at(i).r = 130;
			cloud_b->at(i).g = 130;
			cloud_b->at(i).b = 130;
		}
	}
	finish = clock();
	cout << "total time is: " << finish - start << endl;
	cout << "pf_num is: " << pf_num << endl;

	pcl::PCDWriter writer;
	writer.write("d://sunyu.pcd", *cloud_b, false);//将点保存到PCD文件中去
	//savefile(cloud_b, cloud_normals, "sunyu.ply", "FPFH");
	return cloud_b;
}

int main()
{

	pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOrigin(new pcl::PointCloud<pcl::PointXYZ>);
	
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("d://1.pcd", *cloudOrigin) == -1) //* 读入PCD格式的文件,如果文件不存在,返回-1  
	{
		PCL_ERROR("Couldn't read file test_pcd.pcd \n"); //文件不存在时,返回错误,终止程序。  
		return (-1);
	}
	//点云滤波
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filltered(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::VoxelGrid<pcl::PointXYZ> sor;
	sor.setInputCloud(cloudOrigin);
	sor.setLeafSize(0.01f, 0.01f, 0.01f);
	sor.filter(*cloud_filltered);
	cout << cloud_filltered->size() << endl;
	//点云的法线

	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
	ne.setInputCloud(cloud_filltered);
	ne.setSearchSurface(cloudOrigin);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
	ne.setSearchMethod(tree);
	ne.setRadiusSearch(0.03);
	ne.compute(*cloud_normals);

	cout << cloud_filltered->size() << endl;

	computeFPFH(cloudOrigin, cloud_normals);

	return 0;

}

参考资料
https://blog.csdn.net/McQueen_LT/article/details/107506368?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164907067016781683941987%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164907067016781683941987&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-107506368.142v5control,157v4control&utm_term=%E5%88%A9%E7%94%A8FPFH%E8%BF%9B%E8%A1%8C%E7%89%B9%E5%BE%81%E7%82%B9%E6%8F%90%E5%8F%96&spm=1018.2226.3001.4187

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值