ch10——10.3PCL中的NARF关键点

1.简述
关键点也称为兴趣点,是2D图像或3D点云或曲面模型上,可以通过定义标准来获取具有稳定性、区别性的点集。它与局部特征描述子一起组成关键描述子用来加快后续识别、追踪等对数据处理速度。
2.关键点算法
NARF关键点:是为了从深度图中识别物体而提出来的。 关键点探测的重要一步是减少特征提取的搜索空间,把重点放在重要的结构上。对NARF关键点提取有以下要求:
1) 提取的过程考虑边缘以及物体表面变化信息在内;
2)在不同视角关键点可以被重复探测;
3)关键点所在位置有足够的支持区域,可以计算描述子和进行唯一的估计法向量。
其对应的探测步骤如下:
(1) 遍历每个深度图像点,通过寻找在近邻区域有深度变化的位置进行边缘检测。
(2) 遍历每个深度图像点,根据近邻区域的表面变化决定一测度表面变化的系数,及变化的主方向。
(3) 根据step(2)找到的主方向计算兴趣点,表征该方向和其他方向的不同,以及该处表面的变化情况,即该点有多稳定。
(4) 对兴趣值进行平滑滤波。
(5) 进行无最大值压缩找到的最终关键点,即为NARF关键点。
3.代码

#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <boost/thread/thread.hpp>
#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/features/range_image_border_extractor.h>
#include <pcl/keypoints/narf_keypoint.h>
using namespace std;
using namespace pcl;

//参数 全局变量
typedef pcl::PointXYZ PointType;
float angular_resolution = 0.5f; //角坐标分辨率
float support_size = 0.2f; //感兴趣点的尺寸(球面的直径)
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME; //坐标框架:相机框架

int main( )
{
	angular_resolution = pcl::deg2rad(angular_resolution);
	//读取pcd文件;如果没有指定文件,就创建样本点
	pcl::PointCloud<PointType>::Ptr point_cloud_ptr(new pcl::PointCloud<PointType>); //点云指针
	pcl::PointCloud<PointType>& point_cloud = *point_cloud_ptr; //上面点云的别名
	Eigen::Affine3f scene_sensor_pose(Eigen::Affine3f::Identity()); //仿射变换
	scene_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_); //设置传感器的姿势
	
	pcl::io::loadPCDFile("D:\\pcd\\frame_00000.pcd", point_cloud); //从磁盘读取pcd文件
	/*   //自己设置点云文件
	for (float x = -0.5f;x <= 0.5f;x += 0.01f)
	{
		for (float y = -0.5f;y <= 0.5f;y += 0.01f)
		{
			PointType point;
			point.x = x;
			point.y = y;
			point.z = 2.0f - y;
			point_cloud.points.push_back(point);
		}
	}
	point_cloud.width = (int)point_cloud.points.size();point_cloud.height = 1; */

	//从点云数据,创建深度图像
	float noise_level = 0.0;
	float min_range = 0.0f;
	int border_size = 1;
	boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage); //创建RangeImage对象(指针)
	pcl::RangeImage& range_image = *range_image_ptr;  //引用
	range_image.createFromPointCloud(point_cloud, angular_resolution, pcl::deg2rad(360.0f), pcl::deg2rad(180.0f),
		scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size); //从点云创建深度图像
	
	//打开3D观察图形窗口,并添加点云
	pcl::visualization::PCLVisualizer viewer("3D Viewer"); //创建3D Viewer对象
	viewer.setBackgroundColor(1, 1, 1); //设置背景色
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler(range_image_ptr, 0, 0, 0);
	viewer.addPointCloud(range_image_ptr, range_image_color_handler, "range image"); //添加点云
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "range image");
	viewer.initCameraParameters();
	//显示深度图像(平面图,上面的3D显示)
	pcl::visualization::RangeImageVisualizer range_image_widget("Range image");
	range_image_widget.showRangeImage(range_image);

	//提取NARF关键点
	pcl::RangeImageBorderExtractor range_image_border_extractor; //创建深度图像的边界提取器,用于提取NARF关键点
	pcl::NarfKeypoint narf_keypoint_detector(&range_image_border_extractor); //创建NARF对象
	narf_keypoint_detector.setRangeImage(&range_image);
	narf_keypoint_detector.getParameters().support_size = support_size;

	pcl::PointCloud<int> keypoint_indices; //用于存储关键点的索引
	narf_keypoint_detector.compute(keypoint_indices); //计算NARF关键点
	cout << "Found " << keypoint_indices.points.size() << " key points.\n";

	//在3D图形窗口中显示关键点
	pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_ptr(new pcl::PointCloud<pcl::PointXYZ>); //创建关键点指针
	pcl::PointCloud<pcl::PointXYZ>& keypoints = *keypoints_ptr; //引用
	keypoints.points.resize(keypoint_indices.points.size()); //点云变形,无序
	for (size_t i = 0; i < keypoint_indices.points.size(); ++i) {
		keypoints.points[i].getVector3fMap() = range_image.points[keypoint_indices.points[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");

	//Main loop
	while (!viewer.wasStopped())
	{
		range_image_widget.spinOnce();  // 处理 GUI事件
		viewer.spinOnce();
		pcl_sleep(0.01);
	}
}

4.显示
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值