PCL:关键点-SIFT

类 SIFTKeypoint 是将二维图像中的 SIFT 算子调整后移植到 3D 空间的 SIFT算子的实现。输入为带有 XYZ 坐标值和强度的点云 , 输出为点云中的 SIFT 关键点。

class pcl:: SIFTKeypoint< PointlnT , PointOutT>

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/io.h>
#include <pcl/keypoints/sift_keypoint.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/time.h>
#pragma comment(lib,"User32.lib")
#pragma comment(lib, "gdi32.lib")
using namespace std;

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);

	const float min_scale = stof("0.01");             //设置尺度空间中最小尺度的标准偏差          
	const int n_octaves = stof("6");               //设置高斯金字塔组(octave)的数目            
	const int n_scales_per_octave = stof("4");     //设置每组(octave)计算的尺度  
	const float min_contrast = stof("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::PointCloud<pcl::PointXYZ>::Ptr cloud_temp(new pcl::PointCloud<pcl::PointXYZ>);
	copyPointCloud(result, *cloud_temp);//将点类型pcl::PointWithScale的数据转换为点类型pcl::PointXYZ的数据

										//可视化输入点云和关键点
	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;

}

在这里插入图片描述
如果先进行VoxelGrid滤波,发现检测出的特征点相同

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/io.h>
#include <pcl/keypoints/sift_keypoint.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/time.h>
#pragma comment(lib,"User32.lib")
#pragma comment(lib, "gdi32.lib")
using namespace std;

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);
    //先进行VoxelGrid滤波,发现检测出的特征点相同
	pcl::PCLPointCloud2::Ptr cloud(new pcl::PCLPointCloud2());
	pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());

	// 填入点云数据
	pcl::PCDReader reader;
	// 把路径改为自己存放文件的路径
	reader.read("pig.pcd", *cloud); // 记住要事先下载这个数据集!
	std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height
		<< " data points (" << pcl::getFieldsList(*cloud) << ").";

	// 创建滤波器对象
	pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
	sor.setInputCloud(cloud);
	sor.setLeafSize(0.01f, 0.01f, 0.01f);//设置滤波时创建的体素体积为 1cm*1cm*1cm的立方体
	sor.filter(*cloud_filtered);

	std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
		<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ").";

	// 保存结果
	pcl::PCDWriter writer;
	writer.write("2f.pcd", *cloud_filtered, Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), false);

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("2f.pcd", *cloud_xyz);





	const float min_scale = stof("0.01");             //设置尺度空间中最小尺度的标准偏差          
	const int n_octaves = stof("6");               //设置高斯金字塔组(octave)的数目            
	const int n_scales_per_octave = stof("4");     //设置每组(octave)计算的尺度  
	const float min_contrast = stof("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::PointCloud<pcl::PointXYZ>::Ptr cloud_temp(new pcl::PointCloud<pcl::PointXYZ>);
	copyPointCloud(result, *cloud_temp);//将点类型pcl::PointWithScale的数据转换为点类型pcl::PointXYZ的数据

										//可视化输入点云和关键点
	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;

}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值