Beispiel #1
0
template <typename PointInT, typename PointOutT> void 
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypoints (PointCloudOut &output)
{
  if (surface_ && surface_ != input_)
  {
    PCL_WARN ("[pcl::%s::detectKeypoints] : ", name_.c_str ());
    PCL_WARN ("A search surface has been set by setSearchSurface, but this SIFT keypoint detection algorithm does ");
    PCL_WARN ("not support search surfaces other than the input cloud.  ");
    PCL_WARN ("The cloud provided in setInputCloud is being used instead.\n");
  }

  // Check if the output has a "scale" field
  scale_idx_ = pcl::getFieldIndex<PointOutT> (output, "scale", out_fields_);

  // Make sure the output cloud is empty
  output.points.clear ();

  // Create a local copy of the input cloud that will be resized for each octave
  boost::shared_ptr<pcl::PointCloud<PointInT> > cloud (new pcl::PointCloud<PointInT> (*input_));

  VoxelGrid<PointInT> voxel_grid;
  // Search for keypoints at each octave
  float scale = min_scale_;
  for (int i_octave = 0; i_octave < nr_octaves_; ++i_octave)
  {
    // Downsample the point cloud
    const float s = 1.0f * scale; // note: this can be adjusted
    voxel_grid.setLeafSize (s, s, s);
    voxel_grid.setInputCloud (cloud);
    boost::shared_ptr<pcl::PointCloud<PointInT> > temp (new pcl::PointCloud<PointInT>);    
    voxel_grid.filter (*temp);
    cloud = temp;

    // Make sure the downsampled cloud still has enough points
    const size_t min_nr_points = 25;
    if (cloud->points.size () < min_nr_points)
      break;

    // Update the KdTree with the downsampled points
    tree_->setInputCloud (cloud);

    // Detect keypoints for the current scale
    detectKeypointsForOctave (*cloud, *tree_, scale, nr_scales_per_octave_, output, *keypoints_indices_);

    // Increase the scale by another octave
    scale *= 2;
  }

  // Set final properties
  output.height = 1;
  output.width = static_cast<uint32_t> (output.points.size ());
  output.header = input_->header;
  output.sensor_origin_ = input_->sensor_origin_;
  output.sensor_orientation_ = input_->sensor_orientation_;
}
Beispiel #2
0
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypoints (PointCloudOut &output)
{
  // Check for valid inputs
  if (min_scale_ == 0 || nr_octaves_ == 0 || nr_scales_per_octave_ == 0)
  {
    ROS_ERROR ("[pcl::%s::detectKeypoints] : A valid range of scales must be specified by setScales before detecting keypoints!", name_.c_str ());
    return;
  }
  if (surface_ != input_)
  {
    ROS_WARN ("[pcl::%s::detectKeypoints] : A search surface has be set by setSearchSurface, but this SIFT keypoint detection algorithm does not support search surfaces other than the input cloud.  The cloud provided in setInputCloud is being used instead.", name_.c_str ());
  }

  // Make sure the output cloud is empty
  output.points.clear ();

  // Create a local copy of the input cloud that will be resized for each octave
  boost::shared_ptr<pcl::PointCloud<PointInT> > cloud = input_->makeShared ();

  // Search for keypoints at each octave
  float scale = min_scale_;
  for (int i_octave = 0; i_octave < nr_octaves_; ++i_octave)
  {
    // Downsample the point cloud
    VoxelGrid<PointInT> voxel_grid;
    float s = 1.0 * scale; // note: this can be adjusted
    voxel_grid.setLeafSize (s, s, s);
    voxel_grid.setInputCloud (cloud);
    voxel_grid.filter (*cloud);

    // Make sure the downsampled cloud still has enough points
    const size_t min_nr_points = 25;
    if (cloud->points.size () < min_nr_points)
    {
      return;
    }

    // Update the KdTree with the downsampled points
    tree_->setInputCloud (cloud);

    // Detect keypoints for the current scale
    detectKeypointsForOctave (*cloud, *tree_, scale, nr_scales_per_octave_, output);

    // Increase the scale by another octave
    scale *= 2;
  }
}