PCL - MLS代碼研讀(十四)- DISTINCT_CLOUD上採樣方法

PCL - MLS代碼研讀(十四)- DISTINCT_CLOUD上採樣方法

前言

PCL - MLS代碼研讀(十一)- computeMLSPointNormal函數中已經介紹了NONESAMPLE_LOCAL_PLANE上採樣方法,並且在PCL - MLS代碼研讀(十三)- RANDOM_UNIFORM_DENSITY上採樣方法中介紹了RANDOM_UNIFORM_DENSITY上採樣方法,本篇主要介紹五種上採樣方法中的第四種:DISTINCT_CLOUD上採樣方法。

成員變數

protected成員變數:

/** \brief The distinct point cloud that will be projected to the MLS surface. */
PointCloudInConstPtr distinct_cloud_;

DISTINCT_CLOUD上採樣方法中,我們會對輸入點雲外的另一個點雲中每一個非無窮遠的點都做投影,並把投影結果加入輸出點雲中。此處定義的成員變數distinct_cloud_即是被投影的點雲。

setter & getter

public成員函數,這兩個函數是為distinct_cloud_成員變數的setter和getter。

/** \brief Set the distinct cloud used for the DISTINCT_CLOUD upsampling method. */
inline void
setDistinctCloud (PointCloudInConstPtr distinct_cloud) { distinct_cloud_ = distinct_cloud; }

/** \brief Get the distinct cloud used for the DISTINCT_CLOUD upsampling method. */
inline PointCloudInConstPtr
getDistinctCloud () const { return (distinct_cloud_); }

process函數

process函數中,僅將cache_mls_results_設為true後,就調用performProcessing (output)進行曲面重建。

template <typename PointInT, typename PointOutT> void
pcl::MovingLeastSquares<PointInT, PointOutT>::process (PointCloudOut &output)
{
  //...

  // Check if distinct_cloud_ was set
  if (upsample_method_ == DISTINCT_CLOUD && !distinct_cloud_)
  {
    PCL_ERROR ("[pcl::%s::process] Upsample method was set to DISTINCT_CLOUD, but no distinct cloud was specified.\n", getClassName ().c_str ());
    return;
  }

  //...

  switch (upsample_method_)
  {
    // Initialize random number generator if necessary
    case (RANDOM_UNIFORM_DENSITY):
    {
      //...
    }
    case (VOXEL_GRID_DILATION):
    case (DISTINCT_CLOUD):
    {
      if (!cache_mls_results_)
        PCL_WARN ("The cache mls results is forced when using upsampling method VOXEL_GRID_DILATION or DISTINCT_CLOUD.\n");

      cache_mls_results_ = true;
      break;
    }
    default:
      break;
  }

  //...

  // Perform the actual surface reconstruction
  performProcessing (output);

  //...
}

performProcessing函數

template <typename PointInT, typename PointOutT> void
pcl::MovingLeastSquares<PointInT, PointOutT>::performUpsampling (PointCloudOut &output)
{

  if (upsample_method_ == DISTINCT_CLOUD)
  {
    corresponding_input_indices_.reset (new PointIndices);

distinct_cloud_中的每一個點都做以下事情:

    for (std::size_t dp_i = 0; dp_i < distinct_cloud_->size (); ++dp_i) // dp_i = distinct_point_i
    {

如果distinct_cloud_中有無窮遠的點,就忽視它:

      // Distinct cloud may have nan points, skip them
      if (!std::isfinite ((*distinct_cloud_)[dp_i].x))
        continue;

尋找input_點雲中距離(*distinct_cloud_)[dp_i]最近的點,其索引為input_index

      // Get 3D position of point
      //Eigen::Vector3f pos = (*distinct_cloud_)[dp_i].getVector3fMap ();
      pcl::Indices nn_indices;
      std::vector<float> nn_dists;
      tree_->nearestKSearch ((*distinct_cloud_)[dp_i], 1, nn_indices, nn_dists);
      const auto input_index = nn_indices.front ();

如果input_點雲中最近鄰的投影結果是無效的,則跳過:

      // If the closest point did not have a valid MLS fitting result
      // OR if it is too far away from the sampled point
      // 這裡似乎沒有排除太遠的點?
      if (mls_results_[input_index].valid == false)
        continue;

獲取(*distinct_cloud_)[dp_i]的坐標,接下來我們會對它做投影:

      //distinct_cloud_中的每一個非無窮遠的點都是待投影點
      Eigen::Vector3d add_point = (*distinct_cloud_)[dp_i].getVector3fMap ().template cast<double> ();

將剛剛得到的add_point投影到由input_點雲中第input_index個點鄰域點所擬合的曲面上:

      //需要5 * nr_coeff_個鄰居?
      MLSResult::MLSProjectionResults proj =  mls_results_[input_index].projectPoint (add_point, projection_method_,  5 * nr_coeff_);

最後將投影結果添加到outputnormals_等數據結構中:

      addProjectedPointNormal (input_index, proj.point, proj.normal, mls_results_[input_index].curvature, output, *normals_, *corresponding_input_indices_);
    }
  }

  // ...
}

上採樣結果

原始點雲:
PCL - MLS代碼研讀(十四)- DISTINCT_CLOUD上採樣方法用來被投影的點雲(distinct_cloud_):
PCL - MLS代碼研讀(十四)- DISTINCT_CLOUD上採樣方法投影後的distinct_cloud
PCL - MLS代碼研讀(十四)- DISTINCT_CLOUD上採樣方法投影前與投影後的distinct_cloud_
PCL - MLS代碼研讀(十四)- DISTINCT_CLOUD上採樣方法輸入點雲與投影後的distinct_cloud
PCL - MLS代碼研讀(十四)- DISTINCT_CLOUD上採樣方法

上一篇:MongoDB Java 驱动程序 v4.3 检索字段的不同值


下一篇:Java的基础语法