天天看点

PCL - MLS代碼研讀(十一)- computeMLSPointNormal函數

PCL - MLS代碼研讀(十一)- computeMLSPointNormal函數

    • 前言
    • computeMLSPointNormal

前言

在PCL - MLS代碼研讀(十)- performProcessing函數中,看到了

performProcessing

函數調用

computeMLSPointNormal

函數做計算,得到投影點坐標及法向量。實際上在此函數中,還會根據

upsample_method_

所指定的上採樣方法做上採樣。

computeMLSPointNormal

根據

upsample_method_

決定要如何投影及上採樣。如果上採樣方式是

SAMPLE_LOCAL_PLANE

RANDOM_UNIFORM_DENSITY

,則在此完成上採樣。否則調用

performUpsampling

函數做上採樣。

template <typename PointInT, typename PointOutT> void
pcl::MovingLeastSquares<PointInT, PointOutT>::computeMLSPointNormal (pcl::index_t index,
                                                                     const pcl::Indices &nn_indices,
                                                                     PointCloudOut &projected_points,
                                                                     NormalCloud &projected_points_normals,
                                                                     PointIndices &corresponding_input_indices,
                                                                     MLSResult &mls_result) const
{
  // Note: this method is const because it needs to be thread-safe
  //       (MovingLeastSquaresOMP calls it from multiple threads)
           

調用

computeMLSSurface

函數:

如果上採樣方法是

NONE

,調用

projectQueryPoint

得到

proj

這個投影結果,然後調用

addProjectedPointNormal

將結果新增到

projected_points

,

projected_points_normals

,

corresponding_input_indices

switch (upsample_method_)
  {
    case (NONE):
    {
      const MLSResult::MLSProjectionResults proj = mls_result.projectQueryPoint (projection_method_, nr_coeff_);
      addProjectedPointNormal (index, proj.point, proj.normal, mls_result.curvature, projected_points, projected_points_normals, corresponding_input_indices);
      break;
    }
           

在半徑

upsampling_radius_

的範圍內,在u和v方向上每隔

upsampling_step_

的距離取一個點,然後投影到平面上:

case (SAMPLE_LOCAL_PLANE):
    {
      // Uniformly sample a circle around the query point using the radius and step parameters
      for (float u_disp = -static_cast<float> (upsampling_radius_); u_disp <= upsampling_radius_; u_disp += static_cast<float> (upsampling_step_))
        for (float v_disp = -static_cast<float> (upsampling_radius_); v_disp <= upsampling_radius_; v_disp += static_cast<float> (upsampling_step_))
          if (u_disp * u_disp + v_disp * v_disp < upsampling_radius_ * upsampling_radius_)
          {
            MLSResult::MLSProjectionResults proj = mls_result.projectPointSimpleToPolynomialSurface (u_disp, v_disp);
            addProjectedPointNormal (index, proj.point, proj.normal, mls_result.curvature, projected_points, projected_points_normals, corresponding_input_indices);
          }
      break;
    }
           

RANDOM_UNIFORM_DENSITY

上採樣方法暫時不做介紹:

case (RANDOM_UNIFORM_DENSITY):
    {
      // Compute the local point density and add more samples if necessary
      const int num_points_to_add = static_cast<int> (std::floor (desired_num_points_in_radius_ / 2.0 / static_cast<double> (nn_indices.size ())));

      // Just add the query point, because the density is good
      if (num_points_to_add <= 0)
      {
        // Just add the current point
        const MLSResult::MLSProjectionResults proj = mls_result.projectQueryPoint (projection_method_, nr_coeff_);
        addProjectedPointNormal (index, proj.point, proj.normal, mls_result.curvature, projected_points, projected_points_normals, corresponding_input_indices);
      }
      else
      {
        // Sample the local plane
        for (int num_added = 0; num_added < num_points_to_add;)
        {
          const double u = (*rng_uniform_distribution_) (rng_);
          const double v = (*rng_uniform_distribution_) (rng_);

          // Check if inside circle; if not, try another coin flip
          if (u * u + v * v > search_radius_ * search_radius_ / 4)
            continue;

          MLSResult::MLSProjectionResults proj;
          if (order_ > 1 && mls_result.num_neighbors >= 5 * nr_coeff_)
            proj = mls_result.projectPointSimpleToPolynomialSurface (u, v);
          else
            proj = mls_result.projectPointToMLSPlane (u, v);

          addProjectedPointNormal (index, proj.point, proj.normal, mls_result.curvature, projected_points, projected_points_normals, corresponding_input_indices);

          num_added++;
        }
      }
      break;
    }

    default:
      break;
  }
}
           

继续阅读