PCL庫學習(2)_直通濾波

在激光點雲的採集過程中,因爲設備和環境因素的影響,會出現一些噪點信息,例如點雲數據中存在不合常理的座標值;同時由於採集設備的有效距離的影響,對於距離較遠的目標其反射的激光點雲數據呈現過度離散的狀態,不具備識別的可能,因此本文從目標對象本身的三維空間大小出發,通過統計方法對激光點雲數據做一些過濾處理操作,過濾噪點和距離過遠的點。

PCL官網代碼是對隨機產生的5個數據按設置參數進行濾波,代碼如下:

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int
 main (int argc, char** argv)
{ srand(time(0));
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
  //填入點雲數據
  cloud->width  = 5;//設置點雲寬度
  cloud->height = 1;//設置點雲高度,無序點雲默認爲1
  cloud->points.resize (cloud->width * cloud->height);
  for (size_t i = 0; i < cloud->points.size (); ++i)//爲點雲填充數據
  {
    cloud->points[i].x = rand () / (RAND_MAX + 1.0f)-0.5;
    cloud->points[i].y = rand () / (RAND_MAX + 1.0f)-0.5;
    cloud->points[i].z = rand () / (RAND_MAX + 1.0f)-0.5;
  }
  std::cout << "Cloud before filtering: " << std::endl;
  for (size_t i = 0; i < cloud->points.size (); ++i)
    std::cout << "    " << cloud->points[i].x << " " 
                        << cloud->points[i].y << " " 
                        << cloud->points[i].z << std::endl;
  // 創建濾波器對象
  pcl::PassThrough<pcl::PointXYZ> pass;//設置濾波器對象
  pass.setInputCloud (cloud);//設置輸入點雲
  pass.setFilterFieldName ("z");//設置過濾時所需要點雲類型的z字段
  pass.setFilterLimits (-2.5, 1.0);//設置在過濾字段上的範圍
  //pass.setFilterLimitsNegative (true);//設置保留範圍內的or過濾掉範圍內的
  pass.filter (*cloud_filtered);//執行濾波,保存過濾結果在cloud_filtered


  std::cout<< "Cloud after filtering: " << std::endl;
  for (size_t i = 0; i < cloud_filtered->points.size (); ++i)
    std::cout << "    " << cloud_filtered->points[i].x << " " 
                        << cloud_filtered->points[i].y << " " 
                        << cloud_filtered->points[i].z << std::endl;
  system("pause");
  return (0);

}

運行結果:
在這裏插入圖片描述
結果顯示:隨機產生點雲數據,點雲中Z座標在(0,1)範圍外的點將被過濾。

在此,本文將修改編譯源代碼,添加table_scene文件,進行直通濾波器對象濾波並可視化。

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int
main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
  // 填入點雲數據
  pcl::PCDReader reader;
  // 把路徑改爲自己存放文件的路徑
  reader.read<pcl::PointXYZ> ("E:/PCLcode/PCLtest/table_scene_lms400.pcd", *cloud);
  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;
  // 創建直通濾波器對象
  pcl::PassThrough<pcl::PointXYZ> pass;//設置濾波器對象
  pass.setInputCloud (cloud);//設置輸入點雲
  pass.setFilterFieldName ("z");//設置過濾時所需要點雲類型的z字段
  pass.setFilterLimits (-1.6, 0.0);//設置在過濾字段上的範圍
  //pass.setFilterLimitsNegative (true);//設置保留範圍內的or過濾掉範圍內的
  pass.filter (*cloud_filtered);//執行濾波,保存過濾結果在cloud_filtered
  std::cout<< "Cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;
  //剩下的數據(內部點)將被存入磁盤
  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("table_scene_lms400(濾波).pcd", *cloud_filtered, false);
  pass.setNegative (true);
  pass.filter (*cloud_filtered);
  writer.write<pcl::PointXYZ> ("table_scene_lms400(濾除點).pcd", *cloud_filtered, false);//將數據寫回到磁盤
  system("pause");
  return (0);

}

執行上述代碼:
在這裏插入圖片描述
濾波前點雲有450400,直通濾波後,點雲在(-1.6,0.0)以外的點被過濾(範圍的選擇與採集設備的位置緊密相關,應該弄清楚場景與採集設備之間的幾何關係),剩餘點雲數量389481個。

接下來,利用cloud_viewer類對table_scene_lms400(濾波).pcd,table_scene_lms400(濾除點).pcd進行可視化。

在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章