PCL点云库(6) — Filters模块空间裁剪器类

目录

6.1 3D包围盒裁剪器Class BoxClipper3D< PointT >

6.2 平面裁剪器Class pcl::PlaneClipper3D< PointT >

6.3 立方体过滤Class pcl::CropBox< PointT >

6.4 曲面或多边形过滤 Class pcl::CropHull< PointT > 

6.5 完整代码


6.1 3D包围盒裁剪器Class BoxClipper3D< PointT >

类BoxClipper3D实现用一个以原点为中心、XYZ各个方向尺寸为2、经过用户指定仿射变换的立方体进行"空间裁剪",通过设置一个仿射变换矩阵先对立方体进行"变换处理",之后输出仿射变换后落在该立方体内的点集。

void boxclip3d(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    Eigen::Affine3f transformation = Eigen::Affine3f::Identity();
    
    //查找点云中心
    Eigen::Vector4f center;
    pcl::compute3DCentroid(cloud_in,center);
    cout << center.x() << "," << center.y() << "," << center.z() << endl;
    // 将点云中心移到centor
    transformation.translation() << -center.x(), -center.y() , -center.z()-1;

    // BoxClipper3D
    pcl::BoxClipper3D<pcl::PointXYZRGB>bclip3d(transformation);
    pcl::Indices cliped;
    bclip3d.clipPointCloud3D(cloud_in,cliped);

    cout << cliped.size() << endl;
    // 将过滤的点云变色
    for(auto &idx : cliped)
    {
        cloud_in.points[idx].r = 255;
        cloud_in.points[idx].g = 0;
    }
}

 

6.2 平面裁剪器Class pcl::PlaneClipper3D< PointT >

   类PlaneClipper3D在三维空间实现平面裁剪。

void planeClip3D(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    // 设置裁减平面
    Eigen::Vector4f plane(20,20,-1,1);
    pcl::PlaneClipper3D<pcl::PointXYZRGB> pclip(plane);

    // pcl::PlaneClipper3D
    pcl::Indices clipped;
    pclip.clipPointCloud3D(cloud_in,clipped);

    // 将过滤的点云变色
    for(const auto &idx : clipped)
    {
        cloud_in.points[idx].r = 0;
        cloud_in.points[idx].b = 0;
    }

    cout << clipped.size() << endl;
}

 

6.3 立方体过滤Class pcl::CropBox< PointT >

类CropBox过滤掉在用户给定立方体内的点云数据。

void cropBox(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    Eigen::Vector4f center;
    pcl::compute3DCentroid(cloud_in,center);
    cout << center.x() << "," << center.y() << "," << center.z() << endl;
    // 设置过滤的立方体
    pcl::CropBox<pcl::PointXYZRGB> cropbox;
    cropbox.setInputCloud(cloud_in.makeShared());
    cropbox.setMin(Eigen::Vector4f(-0.5,0,1.5,1)); //设置最小点
    cropbox.setMax(Eigen::Vector4f(0,0.5,2,1));//设置最大点


    // pcl::CropBox
    pcl::Indices clipped;
    cropbox.filter(clipped);

    // 将过滤的点云变色
    for(const auto &idx : clipped)
    {
        cloud_in.points[idx].r = 0;
        cloud_in.points[idx].b = 0;
    }
    cout << clipped.size() << endl;
}

6.4 曲面或多边形过滤 Class pcl::CropHull< PointT > 

类CropBox过滤在给定三维封闭曲面或二维封闭多边形内部或外部的点云数据,封闭曲面或多边形由类ConvexHull或ConcaveHull 处理产生。

oid cropHull(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    Eigen::Vector4f center;
    pcl::compute3DCentroid(cloud_in,center);
   
    //定义2D平面点云
    pcl::PointCloud<pcl::PointXYZRGB> boundingbox_ptr;
    boundingbox_ptr.push_back(pcl::PointXYZRGB(10, 10, 0,255,0,0));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(10, -10, 0, 255,0,0 ));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(-10, 10, 0 ,255,0,0));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(-10, -10, 0 ,255,0,0));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(15, 10, 0 ,255,0,0));
   
    pcl::ConvexHull<pcl::PointXYZRGB> hull;               //创建凸包对象
    hull.setInputCloud(boundingbox_ptr.makeShared());     //设置输入点云
    hull.setDimension(2);                                 //设置凸包维度
    std::vector<pcl::Vertices> polygons;                  //设置向量,用于保存凸包定点
    pcl::PointCloud<pcl::PointXYZRGB> surface_hull;       //该点运用于描述凸包形状
    hull.reconstruct(surface_hull, polygons);            //计算2D凸包结果
   
    pcl::CropHull<pcl::PointXYZRGB> bb_filter;            //创建crophull对象
    bb_filter.setDim(2);                                  //设置维度:该维度需要与凸包维度一致
    bb_filter.setInputCloud(cloud_in.makeShared());       //设置需要滤波的点云
    bb_filter.setHullIndices(polygons);                   //输入封闭多边形的顶点
    bb_filter.setHullCloud(surface_hull.makeShared());    //输入封闭多边形的形状
    pcl::Indices clipped;
    bb_filter.filter(clipped);                           //执行CropHull滤波,存出结果在objects
   
    cout << clipped.size() << endl;
    for(auto &idx : clipped)
    {
        cloud_in.points[idx].r = 255;
        cloud_in.points[idx].g = 0;
    }
}

6.5 完整代码

cmake_minimum_required(VERSION 2.6)
project(BoxClipper3D)
 
find_package(PCL 1.10 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable(BoxClipper3D BoxClipper3D.cpp)
target_link_libraries (BoxClipper3D ${PCL_LIBRARIES} )

install(TARGETS BoxClipper3D RUNTIME DESTINATION bin)
#include <iostream>

#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/box_clipper3D.h>
#include <pcl/filters/plane_clipper3D.h>
#include <pcl/filters/crop_box.h>
#include <pcl/filters/crop_hull.h>
#include <pcl/surface/convex_hull.h>
#include <pcl/common/transforms.h>
#include <pcl/common/centroid.h>
#include <pcl/common/common_headers.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/console/parse.h>
using namespace std;

void boxclip3d(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    Eigen::Affine3f transformation = Eigen::Affine3f::Identity();
    
    //查找点云中心
    Eigen::Vector4f center;
    pcl::compute3DCentroid(cloud_in,center);
    cout << center.x() << "," << center.y() << "," << center.z() << endl;
    // 将点云中心移到centor
    transformation.translation() << -center.x()-0.5, -center.y()-1 , -center.z()-1;

    // BoxClipper3D
    pcl::BoxClipper3D<pcl::PointXYZRGB>bclip3d(transformation);
    pcl::Indices cliped;
    bclip3d.clipPointCloud3D(cloud_in,cliped);

    cout << cliped.size() << endl;
    // 将过滤的点云变色
    for(auto &idx : cliped)
    {
        cloud_in.points[idx].r = 255;
        cloud_in.points[idx].g = 0;
    }
}

void planeClip3D(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    // 设置裁减平面
    // 构造函数以Eigen::Vector4f作为平面的齐次表示形式。
    Eigen::Vector4f plane(20,20,-1,1);
    pcl::PlaneClipper3D<pcl::PointXYZRGB> pclip(plane);

    // pcl::PlaneClipper3D
    pcl::Indices clipped;
    pclip.clipPointCloud3D(cloud_in,clipped);

    // 将过滤的点云变色
    for(const auto &idx : clipped)
    {
        cloud_in.points[idx].r = 0;
        cloud_in.points[idx].b = 0;
    }

    cout << clipped.size() << endl;
}

void cropBox(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    Eigen::Vector4f center;
    pcl::compute3DCentroid(cloud_in,center);
    cout << center.x() << "," << center.y() << "," << center.z() << endl;
    // 设置过滤的立方体
    pcl::CropBox<pcl::PointXYZRGB> cropbox;
    cropbox.setInputCloud(cloud_in.makeShared());
    cropbox.setMin(Eigen::Vector4f(-0.5,0,1.5,1)); //设置最小点
    cropbox.setMax(Eigen::Vector4f(0,0.5,2,1));//设置最大点

    // pcl::CropBox
    pcl::Indices clipped;
    cropbox.filter(clipped);

    // 将过滤的点云变色
    for(const auto &idx : clipped)
    {
        cloud_in.points[idx].r = 0;
        cloud_in.points[idx].b = 0;
    }
    cout << clipped.size() << endl;
}


void cropHull(pcl::PointCloud<pcl::PointXYZRGB> &cloud_in)
{
    Eigen::Vector4f center;
    pcl::compute3DCentroid(cloud_in,center);
   
    Eigen::Affine3f transformation = Eigen::Affine3f::Identity();
    transformation.translation() << -center.x(), -center.y() , -center.z();
    pcl::transformPointCloud<pcl::PointXYZRGB>(cloud_in,cloud_in,transformation);
   
    //定义2D平面点云
    pcl::PointCloud<pcl::PointXYZRGB> boundingbox_ptr;
    boundingbox_ptr.push_back(pcl::PointXYZRGB(10, 10, 0,255,0,0));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(10, -10, 0, 255,0,0 ));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(-10, 10, 0 ,255,0,0));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(-10, -10, 0 ,255,0,0));
    boundingbox_ptr.push_back(pcl::PointXYZRGB(15, 10, 0 ,255,0,0));
   
    pcl::ConvexHull<pcl::PointXYZRGB> hull;               //创建凸包对象
    hull.setInputCloud(boundingbox_ptr.makeShared());     //设置输入点云
    hull.setDimension(2);                                 //设置凸包维度
    std::vector<pcl::Vertices> polygons;                  //设置向量,用于保存凸包定点
    pcl::PointCloud<pcl::PointXYZRGB> surface_hull;       //该点运用于描述凸包形状
    hull.reconstruct(surface_hull, polygons);            //计算2D凸包结果
   
    pcl::CropHull<pcl::PointXYZRGB> bb_filter;            //创建crophull对象
    bb_filter.setDim(2);                                  //设置维度:该维度需要与凸包维度一致
    bb_filter.setInputCloud(cloud_in.makeShared());       //设置需要滤波的点云
    bb_filter.setHullIndices(polygons);                   //输入封闭多边形的顶点
    bb_filter.setHullCloud(surface_hull.makeShared());    //输入封闭多边形的形状
    pcl::Indices clipped;
    bb_filter.filter(clipped);                           //执行CropHull滤波,存出结果在objects
   
    cout << clipped.size() << endl;
    for(auto &idx : clipped)
    {
        cloud_in.points[idx].r = 255;
        cloud_in.points[idx].g = 0;
    }
}


int main(int argc, char *argv[])
{
    //load点云
    pcl::PCLPointCloud2 cloud;
    pcl::io::loadPCDFile("../pig.pcd",cloud);
    pcl::PointCloud<pcl::PointXYZRGB> cloud_in;
    pcl::fromPCLPointCloud2(cloud,cloud_in);
    
    //Clipper
    //boxclip3d(cloud_in);
    //planeClip3D(cloud_in);
    //cropBox(cloud_in);
    cropHull(cloud_in);
    
    // 创建窗口
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer());
    viewer->setWindowName("BoxClipper3D");
    
    pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud_in.makeShared());
    viewer->addPointCloud(cloud_in.makeShared(),rgb);
    //viewer->addCube(-0.5,0,0,0.5,1.5,2,1.0,0.0,0.0);
    //viewer->addPolygon<pcl::PointXYZRGB>(boundingbox_ptr,0,1.0,0);
    viewer->setRepresentationToWireframeForAllActors();
    
    while(!viewer->wasStopped())
        viewer->spinOnce(100);

    return 0;
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
裁剪任意多边形点云,可以使用PCL中的CropHull滤波器。CropHull滤波器可以使用凸包或者自定义的多边形边界来裁剪点云数据。具体的步骤如下: 1. 定义多边形的边界。可以使用PCL中的ConvexHull或者手动定义边界点的坐标。 2. 将多边形边界转换成PCL的PolygonMesh数据类型。 3. 使用CropHull滤波器,将点云数据裁剪到多边形边界内。 4. 将裁剪后的点云数据保存到文件或者显示在屏幕上。 需要注意的是,CropHull滤波器只能处理平面的多边形点云。如果点云包含有曲面,则需要进行曲面拟合或者其他处理方法。 下面是一个使用CropHull滤波器来裁剪任意多边形点云的示例代码: ```c++ #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/filters/crop_hull.h> #include <pcl/PolygonMesh.h> int main(int argc, char** argv) { // 读入点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ>("input_cloud.pcd", *cloud); // 定义多边形边界 pcl::PolygonMesh mesh; // TODO: 从文件或者手动设置多边形边界 // 创建CropHull滤波器 pcl::CropHull<pcl::PointXYZ> crop; crop.setInputCloud(cloud); crop.setHullCloud(polygon_cloud); // 设置多边形边界 crop.setHullIndices(mesh.polygons[0].vertices); // 设置多边形的顶点索引 // 裁剪多边形区域 pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>); crop.filter(*filtered_cloud); // 将裁剪后的点云保存到文件 pcl::io::savePCDFileASCII("filtered_cloud.pcd", *filtered_cloud); return 0; } ``` 在上面的示例代码中,我们首先读入点云数据,然后定义多边形边界,创建CropHull滤波器,并设置多边形边界和顶点索引,接着裁剪多边形区域,最后将裁剪后的点云保存到文件。需要注意的是,这里我们使用了手动定义的多边形边界,如果使用ConvexHull来计算凸包,则需要使用PCL中的ConvexHull类。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

几度春风里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值