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

news2024/11/28 14:44:30

目录

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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/537605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言基础:static关键字

本文结合工作经验&#xff0c;研究C语言中static关键字的用法。 文章目录 1 static关键字概念2 用法与使用场景2.1 修饰全局变量2.1.1 代码示例2.1.2 使用场景 2.2 修饰函数2.2.1 代码示例2.2.2 使用场景 2.3 修饰局部变量2.3.1 代码示例2.4.2 使用场景 3 总结 1 static关键字…

第13章:存储过程和存储函数

一、存储过程 1.1理解 含义&#xff1a; 存储过程stored procedure&#xff0c;思想是一组经过预先编译的SQL语句的封装。 存储过程预先存储在MySQL服务器上&#xff0c;需要执行的时候&#xff0c;客户端向服务器端发出调用存储过程的命令&#xff0c;服务器段把这组SQL执…

当我和ChatGPT-4聊完后,我觉得一切可能已经来不及了

飞机上有wifi&#xff0c;了然无味&#xff0c;在万米高空&#xff0c;和ChatGPT-4开始了一场坦诚的沟通&#xff0c;它全程都表现出高情商&#xff0c;以及不断尽量安抚我的情绪&#xff0c;而这&#xff0c;恰恰令我脊背发凉。 部分文字截取 ZM&#xff1a;我能不能理解每次对…

k8s学习-CKS真题-ImagePolicyWebhook容器镜像扫描

目录 题目环境搭建imagePolicyWebhook搭建 解题任务二任务三任务一检查 模拟考题参考 题目 Context cluster上设置了容器镜像扫描器&#xff0c;但尚未完全集成到 cluster 的配置中。 完成后&#xff0c;容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。 Task 注意&#xff…

5.17 ARM 作业

1. 2.用for循环实现1~100之间的和 13BA 3.xmind

可以找工作的C端的低代码产品,终于让我找到了

目录 写在前面 低代码平台 平台怎么选 各平台区别 为什么选它 写在前面 大家都知道低代码这个叫法是从B端叫起来的&#xff0c;也就是说不管是业务人员还是开发人员&#xff0c;都是企业内部使用。那么有没有C端的&#xff0c;且免费使用的低代码产品呢&#xff1f; 低代码…

一次性能优化思考过程

前言 最近业务上空闲了下来&#xff0c;也是把之前在开发时自身感受比较大的白屏时间放在了主线上去排查优化&#xff0c;这里记录一下笔者对于移动端vConsole脚本的引入问题全过程。 网络脚本与问题定位 对于白屏时间&#xff0c;与网络传输有很大关系&#xff0c;如图&…

该怎样学习网络安全知识?

首先&#xff0c;必须&#xff08;时刻&#xff09;意识到你是在学习一门可以说是最难的课程&#xff0c;是网络专业领域的顶尖课程&#xff0c;不是什么人、随随便便就能学好的。不然&#xff0c;大家都是黑客&#xff0c;也就没有黑客和网络安全的概念了。 很多朋友抱着学一…

#systemverilog# 之 event region 和 timeslot 仿真调度(五)实战

目录 一 问题代码 二 解决方法 2.1 调换代码顺序 2.2 #0 Delay 2.3 uvm class 执行移到re-avtive 2.4 搭建完备的UVM 验证平台 三 预期波形 经过之前文章的学习&#xff0c;想必大家对systemverilog 仿真调度的理解&#xff0c;应该八九不离十了。今天&#xff0c;我们…

基于STM32的NRF24L01 2.4G通讯模块的驱动实验(HAL库)

前言&#xff1a;本文为手把手教学NRF24L01 2.4G通讯模块的驱动实验&#xff0c;本教程的 MCU 采用STM32F103ZET6与STM32F103C8T6&#xff0c;彼此进行互相通讯。通过 CubeMX 软件配置 SPI 协议驱动NRF24L01 2.4G通讯模块&#xff08;HAL库&#xff09;。NRF24L01 2.4G是嵌入式…

渗透测试--5.2.hash密码的破解

目录 1.hashcat简介 2.hashcat参数 常见参数 哈希类型&#xff08;-m&#xff09; 破解模式&#xff08;-a&#xff09; 3.实例 步骤一&#xff1a;使用hash-identifier工具判断哈希值类型 步骤二&#xff1a;使用字典攻击进行破解 1.hashcat简介 hashcat号称世界上最…

js实现点击改变文字大小

目录 一、前言二、代码实现 一、前言 在编写代码之前我们先来看看通过js获取元素有几种方式&#xff1a; 1.第一种 document.querySelector() 返回文档中匹配指定的选择器组的第一个元素document.querySelectorAll(); 返回文档中匹配指定的选择器组的所有元素 <!DOCTYPE ht…

vector容器 [上]

目录 一、 对于vector的介绍 二、vector的定义 0x01 无参构造 0x02 构造并初始化n个val 0x03 使用迭代器进行初始化构造 0x04 拷贝构造 0x05 比较 三、 vector的遍历 0x01 push_back() 0x02 operator[] 和at() 0x03 遍历 四、vector 容量空间 0x01 max_size : 返回v…

【设置教程】未使用系统分配DNS地址 如何设置?答:

未使用系统分配DNS地址&#xff0c;是你的域名解析DNS地址不是当前系统的DNS地址。 设置方法&#xff1a;先关闭更新。域名控制台--域名列表--安全设置&#xff1a; 通过短信验证。 2、修改DNS地址&#xff1a;域名控制台--域名列表&#xff1a;点击域名&#xff1a; 3、点击&…

C语言函数速查

scanf函数 函数概要&#xff1a; scanf 函数从标准输入流中读取格式化字符串。 与 printf 格式化输出函数相反&#xff0c;scanf 函数是格式化输入函数。 函数原型&#xff1a; #include <stdio.h> ... int scanf(const char *format, ...);参数解析&#xff1a; 1…

事务 ---MySQL的总结(六)

事务 多进程进行并改变同一个数据&#xff0c;如果没有进行版本控制&#xff0c;就会出现数据不确定的问题&#xff0c;为此引入了事务的概念。可以进行数据回滚&#xff0c;解决潜在的问题。 事务的概念 一组的DML组成&#xff0c;这一些的DML要么同时成功&#xff0c;要么同…

Linux上开启coredump

Linux上开启core dump Core dump&#xff08;核心转储&#xff09;是在程序崩溃时生成的一种文件&#xff0c;其中包含了程序在崩溃时的内存状态信息。它可以帮助程序员在调试程序时快速定位问题&#xff0c;并且是一种非常有用的调试工具。core dump的作用如下&#xff1a; 帮…

Java面向对象程序设计实验报告(实验二 面向对象基础练习)

✨作者&#xff1a;命运之光 ✨ 专栏&#xff1a;Java面向对象程序设计实验报告 目录 ✨一、需求设计 ✨二、概要设计 ✨三、详细设计 ✨四、调试结果 ✨五、测试结果 ✨附录&#xff1a;源程序代码&#xff08;带注释&#xff09; 测试类demo2 Address类 Employee类…

Docker之DockerFile相关基础知识

DockerFile相关基础知识 一、Docker镜像原理1、操作系统组成部分1.1 七大子系统1.2 Linux文件系统 2、Docker镜像原理介绍2.1 原理图2.2 Docker镜像本质2.3 统一文件系统2.4 复用性2.5 统一性 二、容器转为镜像1、Docker镜像的制作1.1 容器转换为镜像1.2 镜像转为压缩文件1.3 导…

【SpringBoot】三:访问数据库

文章目录 1.DataSource2.JdbcTemplate2.1 准备环境2.2 准备表和数据2.3 配置数据源2.4 JdbcTemplate访问mysql2.5 创建实体类 ArticlePO2.6 测试2.6.1 测试聚合函数 3.mybatis3.1 单表CRUMD3.1.1 创建模块3.1.2 查询3.1.3 插入3.1.4 更新3.1.5 删除 3.2 ResultMap3.3 SQL 提供者…