【点云PCL入门】关键点提取

1.深度图像中提取NARF关键点

#include<iostream>
#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/range_image_border_extractor.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/keypoints/narf_keypoint.h>

// -----Parameters-----
float angular_resolution = 0.5f;
float support_size = 0.2f;
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;

int main(int argc, char* argv[])
{
	angular_resolution = pcl::deg2rad(angular_resolution);
    // -----Read pcd file or create example point cloud if not given-----
	pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>&point_cloud = *point_cloud_ptr;
	pcl::PointCloud<pcl::PointWithViewpoint>far_ranges;//远距离点云数据
	Eigen::Affine3f scense_sensor_pose(Eigen::Affine3f::Identity());
	
	if(pcl::io::loadPCDFile("./frame_00000.pcd",point_cloud)==-1)
	{
		std::cerr << "Was not able to open file \n";
		return 0;
	}
	scense_sensor_pose = Eigen::Affine3f(Eigen::Translation3f(point_cloud.sensor_origin_[0], point_cloud.sensor_origin_[1], point_cloud.sensor_origin_[2]))*Eigen::Affine3f(point_cloud.sensor_orientation_);

  // -----Create RangeImage from the PointCloud-----
	float noise_level = 0.0;
	float min_range = 0.0;
	int border_size = 2;
	pcl::RangeImage::Ptr range_image_ptr(new pcl::RangeImage);
	pcl::RangeImage&range_image = *range_image_ptr;
	range_image.createFromPointCloud(point_cloud, angular_resolution, pcl::deg2rad(360.0), pcl::deg2rad(180.0), scense_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
	//range_image.integrateFarRanges(far_ranges);
	range_image.setUnseenToMaxRange();//不可见区域变为最大范围读数,识别出边界

    // -----Open 3D viewer and add point cloud-----
	pcl::visualization::PCLVisualizer viewer("3D Viewer");
	viewer.setBackgroundColor(1, 1, 1); 
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange>range_image_color_handle(range_image_ptr,0,0,0);
	viewer.addPointCloud(range_image_ptr, range_image_color_handle, "range image");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "range image");
	viewer.initCameraParameters();
	// -----Show range image-----
	pcl::visualization::RangeImageVisualizer range_image_widget("Range image");
	range_image_widget.showRangeImage(range_image);
	// -----Extract NARF keypoints-----
	pcl::RangeImageBorderExtractor range_image_border_extractor;
	pcl::NarfKeypoint narf_keypoint_detector(&range_image_border_extractor);
	narf_keypoint_detector.setRangeImage(&range_image);
	narf_keypoint_detector.getParameters().support_size = support_size;
	narf_keypoint_detector.getParameters().add_points_on_straight_edges = true;
	narf_keypoint_detector.getParameters().distance_for_additional_points = 0.5;
	pcl::PointCloud<int>keypoint_indices;
	narf_keypoint_detector.compute(keypoint_indices);
	std::cout << "Found " << keypoint_indices.size() << " key points.\n";

	// -----Show keypoints in 3D viewer-----
	pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_ptr(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>& keypoints = *keypoints_ptr;
	keypoints.resize(keypoint_indices.size());
	for (std::size_t i = 0; i < keypoint_indices.size(); ++i)
		keypoints[i].getVector3fMap() = range_image[keypoint_indices[i]].getVector3fMap();

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color_handler(keypoints_ptr, 0, 255, 0);
	viewer.addPointCloud<pcl::PointXYZ>(keypoints_ptr, keypoints_color_handler, "keypoints");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "keypoints");

	while (!viewer.wasStopped())
	{
		range_image_widget.spinOnce();  // process GUI events
		viewer.spinOnce();
		pcl_sleep(0.01);
	}
	return 0;
}

2.SIFT关键点提取

#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include<pcl/keypoints/sift_keypoint.h>
#include <pcl/features/normal_3d.h>
#include<pcl/visualization/pcl_visualizer.h>

//pcl中sift特征需要返回强度信息,改为如下:
namespace pcl
{
	template<>
	struct SIFTKeypointFieldSelector<PointXYZ>
	{
		inline float operator () (const PointXYZ &p) const
		{
			return p.z;
		}
	};
}
int main(int argc, char* argv[])
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("./pig.pcd", *cloud_xyz);
	//stof字符串转float
	const float min_scale = 0.01;//设置尺寸空间中最小尺度的标准偏差
	const int n_octaves = 6;//高斯金字塔中组的数目
	const int n_scales_per_octave = 4;//每组计算的尺度数目
	const float min_contrast = 0.01;

	pcl::SIFTKeypoint<pcl::PointXYZ, pcl::PointWithScale> sift;//创建sift关键点检测对象
	pcl::PointCloud<pcl::PointWithScale> result;
	sift.setInputCloud(cloud_xyz);//设置输入点云
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
	sift.setSearchMethod(tree);//创建一个空的kd树对象tree,并把它传递给sift检测对象
	sift.setScales(min_scale, n_octaves, n_scales_per_octave);//指定搜索关键点的尺度范围
	sift.setMinimumContrast(min_contrast);//设置限制关键点检测的阈值
	sift.compute(result);//执行sift关键点检测,保存结果在result


	//为了后期处理与显示的需要
	//将点类型pcl::PointWithScale的数据转换为点类型pcl::PointXYZ的数据
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_temp(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::copyPointCloud(result, *cloud_temp);

	//可视化输入点云和关键点
	pcl::visualization::PCLVisualizer viewer("Sift keypoint");
	viewer.setBackgroundColor(255, 255, 255);
	viewer.addPointCloud(cloud_xyz, "cloud");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "cloud");
	viewer.addPointCloud(cloud_temp, "keypoints");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 9, "keypoints");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 255, "keypoints");

	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}

	return 0;
}

3.Harris关键点提取

#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/visualization/pcl_visualizer.h>
#include<pcl/keypoints/harris_3D.h>

int main(int argc, char* argv[])
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("./roorm.pcd", *input_cloud);
	pcl::PCDWriter writer;
	float r_normal=0.1;
	float r_keypoint=0.1;

	//包含强度信息
	pcl::PointCloud<pcl::PointXYZI>::Ptr Harris_keypoints(new pcl::PointCloud<pcl::PointXYZI>);
	pcl::HarrisKeypoint3D<pcl::PointXYZ,pcl::PointXYZI,pcl::Normal>* harris_detector=new  pcl::HarrisKeypoint3D<pcl::PointXYZ, pcl::PointXYZI, pcl::Normal>;
	harris_detector->setRadius(r_normal);//设置法向量估计的半径
	harris_detector->setRadiusSearch(r_keypoint);//设置关键点估计的近邻搜索半径
	harris_detector->setInputCloud(input_cloud);
	harris_detector->compute(*Harris_keypoints);

	cout << "Harris_keypoints的大小是" << Harris_keypoints->size() << endl;
	writer.write<pcl::PointXYZI>("Harris_keypoints.pcd", *Harris_keypoints, false);

	pcl::visualization::PCLVisualizer visu3("clouds");
	visu3.setBackgroundColor(255, 255, 255);
	visu3.addPointCloud(Harris_keypoints, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZI>(Harris_keypoints, 0.0, 0.0, 255.0), "Harris_keypoints");
	visu3.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 8, "Harris_keypoints");
	visu3.addPointCloud(input_cloud, "input_cloud");
	visu3.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "input_cloud");
	visu3.initCameraParameters();
	visu3.spin();

}

参考

1.https://pcl.readthedocs.io/projects/tutorials/en/latest/index.html#keypoints

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的基于PCL库的点云窗户提取示例代码: ```c++ #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/filters/extract_indices.h> #include <pcl/filters/passthrough.h> int main(int argc, char** argv) { // Load input point cloud from file pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ>("input_cloud.pcd", *cloud); // Define window parameters float min_x = -1.0, max_x = 1.0; float min_y = -1.0, max_y = 1.0; float min_z = 0.0, max_z = 2.0; // Filter point cloud using window parameters pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PassThrough<pcl::PointXYZ> pass_filter; pass_filter.setInputCloud(cloud); pass_filter.setFilterFieldName("x"); pass_filter.setFilterLimits(min_x, max_x); pass_filter.filter(*filtered_cloud); pass_filter.setInputCloud(filtered_cloud); pass_filter.setFilterFieldName("y"); pass_filter.setFilterLimits(min_y, max_y); pass_filter.filter(*filtered_cloud); pass_filter.setInputCloud(filtered_cloud); pass_filter.setFilterFieldName("z"); pass_filter.setFilterLimits(min_z, max_z); pass_filter.filter(*filtered_cloud); // Save output point cloud to file pcl::io::savePCDFile<pcl::PointXYZ>("output_cloud.pcd", *filtered_cloud); return 0; } ``` 该代码首先加载了一个点云数据,然后定义了一个窗口的参数,最后使用PCL库的PassThrough滤波器对点云进行了过滤。过滤器根据窗口参数,将点云中不在窗口内的点过滤掉,最终输出一个过滤后的点云数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值