类 SIFTKeypoint 是将二维图像中的 SIFT 算子调整后移植到 3D 空间的 SIFT算子的实现。输入为带有 XYZ 坐标值和强度的点云 , 输出为点云中的 SIFT 关键点。
void | setScales (float min_scale, int nr_octaves, int nr_scales_per_octave) |
设置搜索时与尺度相关参数, min_scale 在点云体素尺度空间中标准偏差,为尺度空间中最小尺度的标准偏差,点云对应体素栅格中体素的最小尺寸; nr_octaves 是检测关键点时体素空间尺度的数目,高斯金字塔中组的数目;nr_scales_ per _ octave 为在每一个体素空间尺度下计算高斯空间的尺度时所需的参数,每组(Octave)计算的尺度数目。 | |
void | setMinimumContrast (float min contrast) |
设置限制关键点检测的阈值 | |
void | compute(PointCloudOut &output) |
计算并储存关键点到output中 |
#pragma warning(disable:4996)
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
#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>
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("F:\\C++project\\pig.pcd", *cloud_xyz);
const float min_scale = 0.01; //设置尺度空间中最小尺度的标准偏差
const int n_octaves = 6; //设置高斯金字塔组(octave)的数目
const int n_scales_per_octave =4; //设置每组(octave)计算的尺度
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::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;
}
运行结果如下: