Пример #1
0
template <typename PointInT, typename PointNT> void
pcl::BoundaryEstimation<PointInT, PointNT, Eigen::MatrixXf>::computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  // Allocate enough space to hold the results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);

  Eigen::Vector4f u = Eigen::Vector4f::Zero (), v = Eigen::Vector4f::Zero ();

  output.is_dense = true;
  output.points.resize (indices_->size (), 1);
  // Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
  if (input_->is_dense)
  {
    // Iterating over the entire index vector
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
      {
        output.points (idx, 0) = std::numeric_limits<float>::quiet_NaN ();
        output.is_dense = false;
        continue;
      }

      // Obtain a coordinate system on the least-squares plane
      //v = normals_->points[(*indices_)[idx]].getNormalVector4fMap ().unitOrthogonal ();
      //u = normals_->points[(*indices_)[idx]].getNormalVector4fMap ().cross3 (v);
      this->getCoordinateSystemOnPlane (normals_->points[(*indices_)[idx]], u, v);

      // Estimate whether the point is lying on a boundary surface or not
      output.points (idx, 0) = this->isBoundaryPoint (*surface_, input_->points[(*indices_)[idx]], nn_indices, u, v, angle_threshold_);
    }
  }
  else
  {
    // Iterating over the entire index vector
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      if (!isFinite ((*input_)[(*indices_)[idx]]) ||
          this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
      {
        output.points (idx, 0) = std::numeric_limits<float>::quiet_NaN ();
        output.is_dense = false;
        continue;
      }

      // Obtain a coordinate system on the least-squares plane
      //v = normals_->points[(*indices_)[idx]].getNormalVector4fMap ().unitOrthogonal ();
      //u = normals_->points[(*indices_)[idx]].getNormalVector4fMap ().cross3 (v);
      this->getCoordinateSystemOnPlane (normals_->points[(*indices_)[idx]], u, v);

      // Estimate whether the point is lying on a boundary surface or not
      output.points (idx, 0) = this->isBoundaryPoint (*surface_, input_->points[(*indices_)[idx]], nn_indices, u, v, angle_threshold_);
    }
  }
}
Пример #2
0
template <typename PointInT, typename PointNT> void
pcl::PrincipalCurvaturesEstimation<PointInT, PointNT, Eigen::MatrixXf>::computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  // Resize the output dataset
  output.points.resize (indices_->size (), 5);

  // Allocate enough space to hold the results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);

  output.is_dense = true;
  // Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
  if (input_->is_dense)
  {
    // Iterating over the entire index vector
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
      {
        output.points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
        output.is_dense = false;
        continue;
      }

      // Estimate the principal curvatures at each patch
      this->computePointPrincipalCurvatures (*normals_, (*indices_)[idx], nn_indices,
                                       output.points (idx, 0), output.points (idx, 1), output.points (idx, 2),
                                       output.points (idx, 3), output.points (idx, 4));
    }
  }
  else
  {
    // Iterating over the entire index vector
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      if (!isFinite ((*input_)[(*indices_)[idx]]) ||
          this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
      {
        output.points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
        output.is_dense = false;
        continue;
      }

      // Estimate the principal curvatures at each patch
      this->computePointPrincipalCurvatures (*normals_, (*indices_)[idx], nn_indices,
                                       output.points (idx, 0), output.points (idx, 1), output.points (idx, 2),
                                       output.points (idx, 3), output.points (idx, 4));
    }
  }
}
Пример #3
0
template <typename PointInT, typename PointNT> void
pcl::IntensityGradientEstimation<PointInT, PointNT, Eigen::MatrixXf>::computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  // Resize the output dataset
  output.points.resize (indices_->size (), 3);

  // Allocate enough space to hold the results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);

  output.is_dense = true;
  // Iterating over the entire index vector
  for (size_t idx = 0; idx < indices_->size (); ++idx)
  {
    if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
    {
      output.points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
      output.is_dense = false;
      continue;
    }

    Eigen::Vector4f centroid;
    compute3DCentroid (*surface_, nn_indices, centroid);

    float mean_intensity = 0;
    unsigned valid_neighbor_count = 0;
    for (size_t nIdx = 0; nIdx < nn_indices.size (); ++nIdx)
    {
      const PointInT& p = (*surface_)[nn_indices[nIdx]];
      if (!pcl_isfinite (p.intensity))
        continue;

      mean_intensity += p.intensity;
      ++valid_neighbor_count;
    }

    mean_intensity /= static_cast<float> (valid_neighbor_count);

    Eigen::Vector3f normal = Eigen::Vector3f::Map (normals_->points[idx].normal);
    Eigen::Vector3f gradient;
    this->computePointIntensityGradient (*surface_, nn_indices, centroid.head<3> (), mean_intensity, normal, gradient);

    output.points (idx, 0) = gradient[0];
    output.points (idx, 1) = gradient[1];
    output.points (idx, 2) = gradient[2];
  }
}
Пример #4
0
template <typename PointInT, typename PointRFT> void
pcl::UniqueShapeContext<PointInT, Eigen::MatrixXf, PointRFT>::computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  output.points.resize (indices_->size (), descriptor_length_ + 9);

  for (size_t point_index = 0; point_index < indices_->size (); point_index++)
  {
    for (int d = 0; d < 9; ++d)
      output.points (point_index, d) = frames_->points[point_index].rf[ (4*(d/3) + (d%3)) ];

    std::vector<float> descriptor (descriptor_length_);
    computePointDescriptor (point_index, descriptor);
    for (size_t j = 0; j < descriptor_length_; ++j)
      output.points (point_index, 9 + j) = descriptor[j];
  }
}
Пример #5
0
template <typename PointInT, typename PointNT> void
pcl::ShapeContext3DEstimation<PointInT, PointNT, Eigen::MatrixXf>::computeFeatureEigen (
    pcl::PointCloud<Eigen::MatrixXf> &output)
{

  // Set up the output channels
  output.channels["3dsc"].name     = "3dsc";
  output.channels["3dsc"].offset   = 0;
  output.channels["3dsc"].size     = 4;
  output.channels["3dsc"].count    = descriptor_length_ + 9;
  output.channels["3dsc"].datatype = sensor_msgs::PointField::FLOAT32;

  // Resize the output dataset
  output.points.resize (indices_->size (), descriptor_length_ + 9);

  float rf[9];

  output.is_dense = true;
  // Iterate over all points and compute the descriptors
	for (size_t point_index = 0; point_index < indices_->size (); point_index++)
  {
    // If the point is not finite, set the descriptor to NaN and continue
    if (!isFinite ((*input_)[(*indices_)[point_index]]))
    {
      output.points.row (point_index).setConstant (std::numeric_limits<float>::quiet_NaN ());
      output.is_dense = false;
      continue;
    }

    std::vector<float> descriptor (descriptor_length_);
    if (!this->computePoint (point_index, *normals_, rf, descriptor))
      output.is_dense = false;
    for (int j = 0; j < 9; ++j)
      output.points (point_index, j) = rf[j];
    for (size_t j = 0; j < descriptor_length_; ++j)
      output.points (point_index, 9 + j) = descriptor[j];
  }
}
Пример #6
0
template <typename PointInT> void
pcl::NormalEstimation<PointInT, Eigen::MatrixXf>::computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  // Resize the output dataset
  output.points.resize (indices_->size (), 4);

  // Allocate enough space to hold the results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);

  output.is_dense = true;
  // Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
  if (input_->is_dense)
  {
    // Iterating over the entire index vector
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
      {
        output.points (idx, 0) = output.points (idx, 1) = output.points (idx, 2) = output.points (idx, 3) = std::numeric_limits<float>::quiet_NaN ();
        output.is_dense = false;
        continue;
      }

      computePointNormal (*surface_, nn_indices,
                          output.points (idx, 0), output.points (idx, 1), output.points (idx, 2), output.points (idx, 3));

      flipNormalTowardsViewpoint (input_->points[(*indices_)[idx]], vpx_, vpy_, vpz_,
                                  output.points (idx, 0), output.points (idx, 1), output.points (idx, 2));

    }
  }
  else
  {
    // Iterating over the entire index vector
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      if (!isFinite ((*input_)[(*indices_)[idx]]) ||
          this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
      {
        output.points (idx, 0) = output.points (idx, 1) = output.points (idx, 2) = output.points (idx, 3) = std::numeric_limits<float>::quiet_NaN ();
        output.is_dense = false;
        continue;
      }

      computePointNormal (*surface_, nn_indices,
                          output.points (idx, 0), output.points (idx, 1), output.points (idx, 2), output.points (idx, 3));

      flipNormalTowardsViewpoint (input_->points[(*indices_)[idx]], vpx_, vpy_, vpz_,
                                  output.points (idx, 0), output.points (idx, 1), output.points (idx, 2));

    }
  }
}
Пример #7
0
template <typename PointInT, typename GradientT> void
pcl::RIFTEstimation<PointInT, GradientT, Eigen::MatrixXf>::computeFeatureEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  // These should be moved into initCompute ()
  {
    // Make sure a search radius is set
    if (search_radius_ == 0.0)
    {
      PCL_ERROR ("[pcl::%s::computeFeature] The search radius must be set before computing the feature!\n",
                 getClassName ().c_str ());
      output.width = output.height = 0;
      output.points.resize (0, 0);
      return;
    }

    // Make sure the RIFT descriptor has valid dimensions
    if (nr_gradient_bins_ <= 0)
    {
      PCL_ERROR ("[pcl::%s::computeFeature] The number of gradient bins must be greater than zero!\n",
                 getClassName ().c_str ());
      output.width = output.height = 0;
      output.points.resize (0, 0);
      return;
    }
    if (nr_distance_bins_ <= 0)
    {
      PCL_ERROR ("[pcl::%s::computeFeature] The number of distance bins must be greater than zero!\n",
                 getClassName ().c_str ());
      output.width = output.height = 0;
      output.points.resize (0, 0);
      return;
    }

    // Check for valid input gradient
    if (!gradient_)
    {
      PCL_ERROR ("[pcl::%s::computeFeature] No input gradient was given!\n", getClassName ().c_str ());
      output.width = output.height = 0;
      output.points.resize (0, 0);
      return;
    }
    if (gradient_->points.size () != surface_->points.size ())
    {
      PCL_ERROR ("[pcl::%s::computeFeature] ", getClassName ().c_str ());
      PCL_ERROR ("The number of points in the input dataset differs from the number of points in the gradient!\n");
      output.width = output.height = 0;
      output.points.resize (0, 0);
      return;
    }
  }
  
  output.points.resize (indices_->size (), nr_gradient_bins_ * nr_distance_bins_);
  Eigen::MatrixXf rift_descriptor (nr_distance_bins_, nr_gradient_bins_);
  std::vector<int> nn_indices;
  std::vector<float> nn_dist_sqr;
 
  output.is_dense = true;
  // Iterating over the entire index vector
  for (size_t idx = 0; idx < indices_->size (); ++idx)
  {
    // Find neighbors within the search radius
    if (tree_->radiusSearch ((*indices_)[idx], search_radius_, nn_indices, nn_dist_sqr) == 0)
    {
      output.points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
      output.is_dense = false;
      continue;
    }

    // Compute the RIFT descriptor
    this->computeRIFT (*surface_, *gradient_, (*indices_)[idx], static_cast<float> (search_radius_), nn_indices, nn_dist_sqr, 
                       rift_descriptor);

    // Copy into the resultant cloud
    int bin = 0;
    for (int g_bin = 0; g_bin < rift_descriptor.cols (); ++g_bin)
      for (int d_bin = 0; d_bin < rift_descriptor.rows (); ++d_bin)
        output.points (idx, bin++) = rift_descriptor (d_bin, g_bin);

  }
}