PCL学习:关键点-SIFT

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

class pcl:: SIFTKeypoint< PointlnT , PointOutT>

类 SIFTKeypoint 关键函数说明:

  • void setScales (float min_scale, int nr_octaves, int nr_scales_per_octave)

设置搜索时与尺度相关参数, min_scale 在点云体素尺度空间中标准偏差,点云对应体素栅格中体素的最小尺寸, nr_octaves 是检测关键点时体素空间尺度的数目,nr_scales_ per _ octave 为在每一个体素空间尺度下计算高斯空间的尺度时所需的参数。

  • void setMinimumContrast (float min contrast)

设置候选关键点应有的对比度下限.

  • void compute (PointCloudOut&.output)

计算并存储关键点到 output 中。

#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 (argv[1], *cloud_xyz);

  const float min_scale = stof(argv[2]);             //设置尺度空间中最小尺度的标准偏差          
  const int n_octaves = stof(argv[3]);               //设置高斯金字塔组(octave)的数目            
  const int n_scales_per_octave = stof(argv[4]);     //设置每组(octave)计算的尺度  
  const float min_contrast = stof(argv[5]);          //设置限制关键点检测的阈值       
 
  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;
  
}

执行命令:

.\Siftdetect.exe ..\..\source\pig.pcd 0.01 6 4 0.01

 如图所示,检测关键点(蓝色点);

猜你喜欢

转载自blog.csdn.net/zfjBIT/article/details/92838084