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

本文详细介绍了PCL库中MovingLeastSquares(MLS)算法的computeMLSPointNormal函数,该函数负责根据不同的上采样方法(NONE, SAMPLE_LOCAL_PLANE, RANDOM_UNIFORM_DENSITY)进行点云上采样,并计算投影点的坐标和法向量。在NONE情况下,直接投影并添加点;在SAMPLE_LOCAL_PLANE中,均匀采样平面并投影;而在RANDOM_UNIFORM_DENSITY下,根据局部密度增加采样点。该过程对于点云表面重建至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

前言

PCL - MLS代碼研讀(十)- performProcessing函數中,看到了performProcessing函數調用computeMLSPointNormal函數做計算,得到投影點坐標及法向量。實際上在此函數中,還會根據upsample_method_所指定的上採樣方法做上採樣。

computeMLSPointNormal

根據upsample_method_決定要如何投影及上採樣。如果上採樣方式是SAMPLE_LOCAL_PLANERANDOM_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函數:

  mls_result.computeMLSSurface<PointInT> (*input_, index, nn_indices, search_radius_, order_);

如果上採樣方法是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;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值