PCL點雲濾波(直通濾波器與統計濾波器)

利用PCL中的直通濾波器和統計濾波器對原始點雲數據進行濾波處理。通過直通濾波器將Z軸方向上範圍之外的點濾除(在背景與前景有一定距離的情況下,可以除掉背景),再利用統計濾波器去除離羣點(噪聲點)。 
濾波效果視數據和濾波參數而定。

#include <pcl/common/common_headers.h>
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/io/io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/statistical_outlier_removal.h>

int
main(int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>);
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_medium(new pcl::PointCloud<pcl::PointXYZRGBA>);
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZRGBA>);
    //讀取點雲文件
    cloud->points.clear();
    std::string pcd_file_name;
    std::string pcd_file_name_filtered;
    std::cout<<"please input pcd file name:"<<endl;
    std::cin>>pcd_file_name;
    std::cout<<"the filtered pcd named *_filtered.pcd "<<endl;
    pcl::io::loadPCDFile(pcd_file_name, *cloud);

    /*
    //// 創建體素濾波器
    // Create the filtering object
    pcl::VoxelGrid<pcl::PointXYZRGBA> sor;
    sor.setInputCloud(cloud);
    sor.setLeafSize(0.01f, 0.01f, 0.01f);
    sor.filter(*cloud_filtered);
*/

    //濾波之後,有序點雲會變成無序點雲
    //直通濾波器,在Z軸方向上剪除多餘的點
    pcl::PassThrough<pcl::PointXYZRGBA> pass;  //創建濾波器對象
    pass.setInputCloud (cloud);                //設置待濾波的點雲
    pass.setFilterFieldName ("z");             //設置在Z軸方向上進行濾波
    pass.setFilterLimits (0.0, 1);             //設置濾波範圍爲0~1,在範圍之外的點會被剪除
    pass.filter (*cloud_medium);               //存儲

    //統計濾波器,刪除離羣點
    pcl::StatisticalOutlierRemoval<pcl::PointXYZRGBA> Static;   //創建濾波器對象
    Static.setInputCloud (cloud_medium);                           //設置待濾波的點雲
    Static.setMeanK (150);                               //設置在進行統計時考慮查詢點臨近點數
    Static.setStddevMulThresh (0.5);                      //設置判斷是否爲離羣點的閥值
    Static.filter (*cloud_filtered);                    //存儲

    //保存濾波後的點雲
    pcl::PCDWriter writer;
    pcd_file_name_filtered.assign(pcd_file_name,0,pcd_file_name.length()-4);
    pcd_file_name_filtered.append("_filtered.pcd");
    writer.write (pcd_file_name_filtered, *cloud_filtered);

    //雙視口
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("filter Viewer"));
    viewer->initCameraParameters();
    int v1(0), v2(0);
    //原始點雲窗口
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
    viewer->setBackgroundColor(0, 0, 0, v1);
    viewer->addText("original", 10, 10, "v1 text", v1);
    viewer->addPointCloud<pcl::PointXYZRGBA>(cloud, "sample cloud1", v1);
    viewer->addCoordinateSystem(1.0);
    viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud1");
    //濾波窗口
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
    viewer->setBackgroundColor(0, 0, 0, v2);
    viewer->addText("after filtered", 10, 10, "v2 text", v2);
    viewer->addPointCloud<pcl::PointXYZRGBA>(cloud_filtered, "sample cloud2", v2);
    viewer->addCoordinateSystem(1.0);
    viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud2");

    while (!viewer->wasStopped ())
    {
     viewer->spinOnce (100);  //刷新
     boost::this_thread::sleep (boost::posix_time::microseconds (100000));
    }
    return 0;
}

 

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