PCL—低層次視覺—點雲濾波(基於點雲頻率)


1.點雲的頻率

  今天在閱讀分割有關的文獻時,驚喜的發現,點雲和圖像一樣,有可能也存在頻率的概念。但這個概念並未在文獻中出現也未被使用,謹在本博文中濫用一下“高頻”一詞。點雲表達的是三維空間中的一種信息,這種信息本身並沒有一一對應的函數值。故點雲本身並沒有在講訴一種變化的信號。但在抽象意義上,點雲必然是在表達某種信號的,雖然沒有明確的時間關系,但應該會存在某種空間關系(例如LiDar點雲)。我們可以人為的指定點雲空間中的一個點(例如Scan的重心或LiDar的“源”),基於此點來討論點雲在各個方向上所謂的頻率。

  在傳統的信號處理中,高頻信號一般指信號變化快,低頻信號一般指信號變化緩慢。在圖像處理中,高低頻的概念被引申至不同方向上圖像灰度的變化,傅里葉變換可以用於提取圖像的周期成分濾除布紋噪聲。在點雲處理中,定義:點雲法線向量差為點雲所表達的信號。換言之,如果某處點雲曲率大,則點雲表達的是一個變化的信號。如果點雲曲率小,則其表達的是一個不變的信號。這和我們的直觀感受也是相近的,地面曲率小,它表達的信息量也小;人的五官部分曲率大,其表達了整個Scan中最大的信息量。

2.基於點雲頻率的濾波方法

  雖然點雲頻率之前並沒有被討論,但使用頻率信息的思想已經被廣泛的應用在了各個方面,最著名的莫過於DoN算法。DoN算法被作者歸類於點雲分割算法中,但我認為並不准確,本質上DoN只是一種前處理,應該算是一種比較先進的點雲濾波算法。分割本質上還是由歐式分割算法完成的。DoN 是 Difference of Normal 的簡寫。算法的目的是在去除點雲低頻濾波,低頻信息(例如建築物牆面,地面)往往會對分割產生干擾,高頻信息(例如建築物窗框,路面障礙錐)往往尺度上很小,直接采用 基於臨近信息 的濾波器會將此類信息合並至牆面或路面中。所以DoN算法利用了多尺度空間的思想,算法如下:

  1. 在小尺度上計算點雲法線1
  2. 在大尺度上計算點雲法線2
  3. 法線1-法線2
  4. 濾去3中值較小的點
  5. 歐式分割

  顯然,在小尺度上是可以對高頻信息進行檢測的,此算法可以很好的小尺度高頻信息。其在大規模點雲(如LiDar點雲)中優勢尤其明顯。

3.PCL對該算法的實現

  算法運行過程可用圖表示為:

  算法實現過程可表示為:

  // Create a search tree, use KDTreee for non-organized data.
  pcl::search::Search<PointXYZRGB>::Ptr tree;
  if (cloud->isOrganized ())
  {
    tree.reset (new pcl::search::OrganizedNeighbor<PointXYZRGB> ());
  }
  else
  {
    tree.reset (new pcl::search::KdTree<PointXYZRGB> (false));
  }
  // Set the input pointcloud for the search tree
  tree->setInputCloud (cloud);

  //生成法線估計器(OMP是並行計算,忽略)
  pcl::NormalEstimationOMP<PointXYZRGB, PointNormal> ne;
  ne.setInputCloud (cloud);
  ne.setSearchMethod (tree);
  //設定法線方向(要做差,同向很重要)
    ne.setViewPoint (std::numeric_limits<float>::max (),    std::numeric_limits<float>::max (), std::numeric_limits<float>::max ());

  //計算小尺度法線
  pcl::PointCloud<PointNormal>::Ptr normals_large_scale (new pcl::PointCloud<PointNormal>);
  ne.setRadiusSearch (scale2);
  ne.compute (*normals_large_scale);
  //計算大尺度法線
  pcl::PointCloud<PointNormal>::Ptr normals_large_scale (new pcl::PointCloud<PointNormal>);
  ne.setRadiusSearch (scale2);
  ne.compute (*normals_large_scale);

  //生成DoN分割器
  pcl::DifferenceOfNormalsEstimation<PointXYZRGB, PointNormal, PointNormal> don;
  don.setInputCloud (cloud);
  don.setNormalScaleLarge (normals_large_scale);
  don.setNormalScaleSmall (normals_small_scale);

  //計算法線差
  PointCloud<PointNormal>::Ptr doncloud (new pcl::PointCloud<PointNormal>);
  copyPointCloud<PointXYZRGB, PointNormal>(*cloud, *doncloud);
  don.computeFeature (*doncloud);

  //生成濾波條件:把法線差和閾值比
    pcl::ConditionOr<PointNormal>::Ptr range_cond (
    new pcl::ConditionOr<PointNormal> ()
    );
  range_cond->addComparison (pcl::FieldComparison<PointNormal>::ConstPtr (
                               new pcl::FieldComparison<PointNormal> ("curvature", pcl::ComparisonOps::GT, threshold))
                             );
  //生成條件濾波器,輸入濾波條件和點雲
  pcl::ConditionalRemoval<PointNormal> condrem (range_cond);
  condrem.setInputCloud (doncloud);

  //導出濾波結果
  pcl::PointCloud<PointNormal>::Ptr doncloud_filtered (new pcl::PointCloud<PointNormal>);
  condrem.filter (*doncloud_filtered);

  //歐式聚類~~~(略)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM