ch12——12.3.7如何从一个深度图像中提取NARF(法线对齐径向特征)特征

1.从一个深度图像中提取NARF特征点位置的NARF特征描述子。本节从给定的pcd文件中提取特征点,然后在这些位置估算特征描述子,接着在一个深度图像和三维视图中可视化这些特征点位置。

2.代码

#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>
#include <pcl/features/narf_descriptor.h>
using namespace std;

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

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\\table_scene_mug_stereo_textured.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;//创建NARF对象
	narf_keypoint_detector.setRangeImageBorderExtractor(&range_image_border_extractor);
	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");
	
	//为特征点提取NARF描述子
	vector<int> keypoint_indices2;
	keypoint_indices2.resize(keypoint_indices.points.size());
	for (unsigned int i = 0; i < keypoint_indices.size(); i++)
	{
		keypoint_indices2[i] = keypoint_indices.points[i];
	}
	//创建NarfDescriptor对象,输入数据(特征点索引和深度图像)
	pcl::NarfDescriptor narf_descriptor(&range_image, &keypoint_indices2);
	narf_descriptor.getParameters().support_size = support_size;//确定描述子区域大小
	narf_descriptor.getParameters().rotation_invariant = rotation_invariant;
	pcl::PointCloud<pcl::Narf36> narf_descriptors;
	narf_descriptor.compute(narf_descriptors);
	cout << "extracted" << narf_descriptors.size() << "descriptors for" 
		<< keypoint_indices.points.size()
		<< "keypoints\n" << endl;
	//Main loop
	while (!viewer.wasStopped())
	{
		range_image_widget.spinOnce();  // 处理 GUI事件
		viewer.spinOnce();
		pcl_sleep(0.01);
	}
}

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值