PCL点云库 学习六(提取、条件剔除、半径剔除)

来自pcl点库从入门到精通

  1. 提取指定区域
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/io/pcd_io.h>
using namespace std;
using namespace pcl;
boost::shared_ptr<pcl::visualization::PCLVisualizer> Simple_viwer(const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud,const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud2){
    //创建句柄
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
    viewer->initCameraParameters ();
    int v1(0),v2(1);
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
    viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
    //设置背景颜色
    viewer->setBackgroundColor(0,0,0,v1);
    viewer->setBackgroundColor(0,0,0,v2);
    //添加点云
    viewer->addPointCloud<pcl::PointXYZ>(cloud,"all data",v1);
    viewer->addPointCloud<pcl::PointXYZ>(cloud2,"filter data",v2);
    //设置点云属性
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"all data",v1);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"filter data",v2);
    //显示坐标系
    viewer->addCoordinateSystem(1.0,v1);
    viewer->addCoordinateSystem(1.0,v2);
    //初始化相机位置
    return(viewer);
}
int main(int argc, const char** argv) {
    PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>());
    PointCloud<PointXYZ>::Ptr cloudout(new PointCloud<PointXYZ>());
    PointCloud<PointXYZ>::Ptr cloudextract(new PointCloud<PointXYZ>());
    PointCloud<PointXYZ>::Ptr cloudouter(new PointCloud<PointXYZ>());
    pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());//系数
      boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
    //ModelCoefficients:以下两部分
    //      ::pcl::PCLHeader header;
    //      std::vector<float> indices;
    pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());//内点索引
    //PointIndices:以下两部分构成
    //     ::pcl::PCLHeader header;
    //      std::vector<int> indices;

    PCDReader rd;
    rd.read("/home/n1/notes/pcl/extract/test.pcd",*cloud);
    //离群点
    StatisticalOutlierRemoval<PointXYZ> SOR;//  初始化对像
    SOR.setInputCloud(cloud);
    SOR.setMeanK(50);               ///最临近距离求取均值点的个数
    SOR.setStddevMulThresh(1);       //设置阈值 阈值=均值+设置系数*标准差 小于阈值为内点,大于阈值为离群点
    SOR.filter(*cloud);
    //降采样
    VoxelGrid<PointXYZ> VOX;
    VOX.setLeafSize(0.01f,0.01f,0.01f);
    VOX.setInputCloud(cloud);
    VOX.filter(*cloudout);

    //点云分割
    pcl::SACSegmentation<PointXYZ> seg;
    seg.setOptimizeCoefficients(true);  //细化系数
    seg.setModelType(SACMODEL_PLANE);                 //设置切割的类型
    seg.setMethodType (pcl::SAC_RANSAC);
    seg.setMaxIterations(1000);         //最大迭代次数
    seg.setDistanceThreshold(0.01);     //距离阈值

    //创建滤波器对象
    pcl::ExtractIndices<PointXYZ> extract;
    int i=0;
    int filter_size=cloudout->size();
    while(cloudout->size()>0.3*filter_size){//点云剩余大小超过0.3
    PointCloud<PointXYZ>::Ptr temp(new PointCloud<PointXYZ>());
        seg.setInputCloud(cloudout);
        seg.segment(*inliers,*coefficients);    //内点和系数
        if (inliers->indices.size () == 0)
        {
            std::cerr << "已经无法分割." << std::endl;
            break;
        }   
        //提取内部点云
        extract.setInputCloud(cloudout);  
        extract.setIndices(inliers);  //索引点 
        extract.setNegative(false);   //false 提取  true 剔除
        extract.filter(*temp);
        *cloudextract+=*temp;
         std::cerr << "平面点云大小::"<<cloudextract->size() << std::endl;
        //提取外部
        extract.setNegative (true);
        extract.filter (*cloudouter);
        cloudout.swap (cloudouter); //删除一寸部分
    }
    
    viewer=Simple_viwer(cloud,cloudextract);
    while (!viewer->wasStopped ())
    {
        viewer->spinOnce (100);
        boost::this_thread::sleep (boost::posix_time::microseconds (100000));
    }
    
    return 0;
}

  1. 条件剔除&半径剔除
    半径剔除:剔除在点指定邻域半径R内,点的数量少于指定数量的点
    条件剔除:注意如何设置条件
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace pcl;
using namespace std;
void create_points(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud){
    srand((unsigned int)time(0));
    cloud->width=30;
    cloud->height=1;
    cloud->points.resize (cloud->width * cloud->height);
    for (size_t i = 0; i < cloud->points.size (); ++i)
    {
        cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
        cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
        cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
    }
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> Simple_viwer(const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud,const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud2,const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud3){
    //创建句柄
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
    viewer->initCameraParameters ();
    int v1(0),v2(1),v3(2);
    viewer->createViewPort(0.0, 0.0, 0.33, 1.0, v1);
    viewer->createViewPort(0.33, 0.0, 0.66, 1.0, v2);
    viewer->createViewPort(0.66, 0.0, 1, 1.0, v3);
    //设置背景颜色
    viewer->setBackgroundColor(0,0,0,v1);
    viewer->setBackgroundColor(0,0,0,v2);
    viewer->setBackgroundColor(0,0,0,v3);
    //添加点云
    viewer->addPointCloud<pcl::PointXYZ>(cloud,"all data",v1);
    viewer->addPointCloud<pcl::PointXYZ>(cloud2,"filter data",v2);
    viewer->addPointCloud<pcl::PointXYZ>(cloud3,"filter1 data",v3);
    //设置点云属性
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"all data",v1);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"filter data",v2);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"filter1 data",v3);
    //显示坐标系
    viewer->addCoordinateSystem(1.0,v1);
    viewer->addCoordinateSystem(1.0,v2);
    viewer->addCoordinateSystem(1.0,v3);
    //初始化相机位置
    return(viewer);
}
int main(int argc,char** argv){
    PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>());
    PointCloud<PointXYZ>::Ptr cloudout(new PointCloud<PointXYZ>());
    PointCloud<PointXYZ>::Ptr cloudout2(new PointCloud<PointXYZ>());
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> ROR;//初始化对象
    create_points(cloud);
    ROR.setInputCloud(cloud);           //输入点云
    ROR.setRadiusSearch(0.8);           //搜索半径
    ROR.setMinNeighborsInRadius(2);     //在半径点内临近点个数少于该值的点会被删除
    ROR.filter(*cloudout);

    pcl::ConditionAnd<PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<PointXYZ>());   //创建条件 ConditionOr或
    range_cond->addComparison(pcl::FieldComparison<PointXYZ>::ConstPtr (new pcl::FieldComparison<PointXYZ>("z",pcl::ComparisonOps::GT,0.0)));//大于0.0
    //pcl::ComparisonOps
    //          GT:大于, GE:大于等于 LT:小于 LE:小于等于 EQ:等于
    range_cond->addComparison(pcl::FieldComparison<PointXYZ>::ConstPtr(new pcl::FieldComparison<PointXYZ>("z",pcl::ComparisonOps::LE,0.5)));//小于0.5
    pcl::ConditionalRemoval<PointXYZ> COND(range_cond);//创建滤波器
    COND.setInputCloud(cloud);
    COND.setKeepOrganized(true);    //是否保存剔除点,默认false:剔除 可能会破坏结构 true:重定义点,保存原始结构
    COND.filter(*cloudout2);
    viewer=Simple_viwer(cloud,cloudout,cloudout2);
    while(!viewer->wasStopped()){
        viewer->spinOnce();
        boost::this_thread::sleep (boost::posix_time::microseconds (100000));
    }
    return 0;
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值