天天看点

PCL - ICP代碼研讀(七 ) - determineRequiredBlobData函數

PCL - ICP代碼研讀(七 ) - determineRequiredBlobData函數

    • 前言
    • determineRequiredBlobData

前言

computeTransformation

函數中有這麼一段代碼:

// Make blobs if necessary
  // ?
  determineRequiredBlobData();
  PCLPointCloud2::Ptr target_blob(new PCLPointCloud2);
  if (need_target_blob_)
    pcl::toPCLPointCloud2(*target_, *target_blob);

  // Pass in the default target for the Correspondence Estimation/Rejection code
  // 目標點雲和法向量可以在循環之前設好,source點雲和法向量則需要在每一個iteration都重設一遍
  correspondence_estimation_->setInputTarget(target_);
  if (correspondence_estimation_->requiresTargetNormals())
    correspondence_estimation_->setTargetNormals(target_blob);
  // Correspondence Rejectors need a binary blob
  // 為correspondence_rejectors_中的每一個rejector設置目標點雲和法向量
  // 目標點雲和法向量可以在循環之前設好,source點雲和法向量則需要在每一個iteration都重設一遍
  for (std::size_t i = 0; i < correspondence_rejectors_.size(); ++i) {
    registration::CorrespondenceRejector::Ptr& rej = correspondence_rejectors_[i];
    if (rej->requiresTargetPoints())
      rej->setTargetPoints(target_blob);
    if (rej->requiresTargetNormals() && target_has_normals_)
      rej->setTargetNormals(target_blob);
  }
           

可以看到,在

need_target_blob_

為true的情況下,會將

pcl::PointCloud

類型的

target_

轉為

pcl::PCLPointCloud2

類型的點雲

target_blob

,然後將它作為

correspondence_estimation_->setTargetNormals

等函數的輸入。

這是因為校正算法輸入的點雲是

pcl::PointCloud

類型的,但是

computeTransformation

內部所用到的

pcl::registration::CorrespondenceEstimationBase::setTargetNormals

pcl::registration::CorrespondenceRejector::setTargetPoints

pcl::registration::CorrespondenceRejector::setTargetNormals

函數(對應的source版本為

pcl::registration::CorrespondenceEstimationBase::setSourceNormals

pcl::registration::CorrespondenceRejector::setSourcePoints

pcl::registration::CorrespondenceRejector::setSourceNormals

函數)接受的卻是

pcl::PCLPointCloud2

類型的點雲,所以才需要做這麼一道轉換。

determineRequiredBlobData

成員函數中,會判定是否需要用到上述的幾個函數,如果需要,

need_source_blob_

或/和

need_target_blob_

就會被設為true。接着在

computeTransformation

函數中,會依據這兩個flag決定是否需要執行

pcl::toPCLPointCloud2

determineRequiredBlobData

用於判定是否需要對source點雲和target點雲執行

pcl::toPCLPointCloud2

,並將結果記錄在

need_source_blob_

need_target_blob_

這兩個變數裡。

template <typename PointSource, typename PointTarget, typename Scalar>
void
IterativeClosestPoint<PointSource, PointTarget, Scalar>::determineRequiredBlobData()
{
  // 如果correspondence_estimation_需要source或target的法向量,就設為true
  // 如果correspondence_rejectors_中有任何一個rejector需要source或target的點雲或法向量,就設為true
  need_source_blob_ = false;
  need_target_blob_ = false;
  // Check estimator
  need_source_blob_ |= correspondence_estimation_->requiresSourceNormals();
  need_target_blob_ |= correspondence_estimation_->requiresTargetNormals();
  // Add warnings if necessary
  if (correspondence_estimation_->requiresSourceNormals() && !source_has_normals_) {
    PCL_WARN("[pcl::%s::determineRequiredBlobData] Estimator expects source normals, "
             "but we can't provide them.\n",
             getClassName().c_str());
  }
  if (correspondence_estimation_->requiresTargetNormals() && !target_has_normals_) {
    PCL_WARN("[pcl::%s::determineRequiredBlobData] Estimator expects target normals, "
             "but we can't provide them.\n",
             getClassName().c_str());
  }
  // Check rejectors
  for (std::size_t i = 0; i < correspondence_rejectors_.size(); i++) {
    registration::CorrespondenceRejector::Ptr& rej = correspondence_rejectors_[i];
    need_source_blob_ |= rej->requiresSourcePoints();
    need_source_blob_ |= rej->requiresSourceNormals();
    need_target_blob_ |= rej->requiresTargetPoints();
    need_target_blob_ |= rej->requiresTargetNormals();
    if (rej->requiresSourceNormals() && !source_has_normals_) {
      PCL_WARN("[pcl::%s::determineRequiredBlobData] Rejector %s expects source "
               "normals, but we can't provide them.\n",
               getClassName().c_str(),
               rej->getClassName().c_str());
    }
    if (rej->requiresTargetNormals() && !target_has_normals_) {
      PCL_WARN("[pcl::%s::determineRequiredBlobData] Rejector %s expects target "
               "normals, but we can't provide them.\n",
               getClassName().c_str(),
               rej->getClassName().c_str());
    }
  }
}
           

從以上代碼中,可以看到

pcl::registration::CorrespondenceEstimationBase

自帶了

requiresTargetNormals

pcl::registration::CorrespondenceRejector

自帶了

requiresTargetPoints

requiresTargetNormals

函數,因此這邊只需要對這些函數的回傳值做or即可。

继续阅读