Ubuntu 20.04.06 PCL C++学习记录(二十一)【切记使用rm * -rf前先确认是否是对应文件夹】

@[TOC]PCL中点云分割模块的学习

学习背景

参考书籍:《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,,PCL版本为1.10.0,CMake版本为3.16,测试点云下载地址

学习内容

根据欧几里得距离和需要保持的用户可自定义条件对点进行聚类,点云文件可从上述地址下载。

源代码及所用函数

源代码

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/console/time.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/segmentation/conditional_euclidean_clustering.h>typedef pcl::PointXYZI PointTypeIO;
typedef pcl::PointXYZINormal PointTypeFull;bool enforceIntensitySimilarity (const PointTypeFull& point_a, const PointTypeFull& point_b, float /*squared_distance*/){if (std::abs (point_a.intensity - point_b.intensity) < 5.0f)return (true);elsereturn (false);
}bool enforceNormalOrIntensitySimilarity (const PointTypeFull& point_a, const PointTypeFull& point_b, float /*squared_distance*/){Eigen::Map<const Eigen::Vector3f> point_a_normal = point_a.getNormalVector3fMap (), point_b_normal = point_b.getNormalVector3fMap ();if (std::abs (point_a.intensity - point_b.intensity) < 5.0f)return (true);if (std::abs (point_a_normal.dot (point_b_normal)) > std::cos (30.0f / 180.0f * static_cast<float> (M_PI)))return (true);return (false);}boolcustomRegionGrowing (const PointTypeFull& point_a, const PointTypeFull& point_b, float squared_distance){Eigen::Map<const Eigen::Vector3f> point_a_normal = point_a.getNormalVector3fMap (), point_b_normal = point_b.getNormalVector3fMap ();if (squared_distance < 10000){if (std::abs (point_a.intensity - point_b.intensity) < 8.0f)return (true);if (std::abs (point_a_normal.dot (point_b_normal)) > std::cos (30.0f / 180.0f * static_cast<float> (M_PI)))return (true);}else{if (std::abs (point_a.intensity - point_b.intensity) < 3.0f)return (true);}return (false);}intmain (){// Data containers usedpcl::PointCloud<PointTypeIO>::Ptr cloud_in (new pcl::PointCloud<PointTypeIO>), cloud_out (new pcl::PointCloud<PointTypeIO>);pcl::PointCloud<PointTypeFull>::Ptr cloud_with_normals (new pcl::PointCloud<PointTypeFull>);pcl::IndicesClustersPtr clusters (new pcl::IndicesClusters), small_clusters (new pcl::IndicesClusters), large_clusters (new pcl::IndicesClusters);pcl::search::KdTree<PointTypeIO>::Ptr search_tree (new pcl::search::KdTree<PointTypeIO>);pcl::console::TicToc tt;// Load the input point cloudstd::cerr << "Loading...\n", tt.tic ();pcl::io::loadPCDFile ("/home/jojo/PointCloud/Statues_4.pcd", *cloud_in);std::cerr << ">> Done: " << tt.toc () << " ms, " << cloud_in->size () << " points\n";// Downsample the cloud using a Voxel Grid classstd::cerr << "Downsampling...\n", tt.tic ();pcl::VoxelGrid<PointTypeIO> vg;vg.setInputCloud (cloud_in);vg.setLeafSize (80.0, 80.0, 80.0);vg.setDownsampleAllData (true);vg.filter (*cloud_out);std::cerr << ">> Done: " << tt.toc () << " ms, " << cloud_out->size () << " points\n";// Set up a Normal Estimation class and merge data in cloud_with_normalsstd::cerr << "Computing normals...\n", tt.tic ();pcl::copyPointCloud (*cloud_out, *cloud_with_normals);pcl::NormalEstimation<PointTypeIO, PointTypeFull> ne;ne.setInputCloud (cloud_out);ne.setSearchMethod (search_tree);ne.setRadiusSearch (300.0);ne.compute (*cloud_with_normals);std::cerr << ">> Done: " << tt.toc () << " ms\n";// Set up a Conditional Euclidean Clustering classstd::cerr << "Segmenting to clusters...\n", tt.tic ();pcl::ConditionalEuclideanClustering<PointTypeFull> cec (true);cec.setInputCloud (cloud_with_normals);cec.setConditionFunction (&customRegionGrowing);cec.setClusterTolerance (500.0);cec.setMinClusterSize (cloud_with_normals->size () / 1000);cec.setMaxClusterSize (cloud_with_normals->size () / 5);cec.segment (*clusters);cec.getRemovedClusters (small_clusters, large_clusters);std::cerr << ">> Done: " << tt.toc () << " ms\n";// Using the intensity channel for lazy visualization of the outputfor (const auto& small_cluster : (*small_clusters))for (const auto& j : small_cluster.indices)(*cloud_out)[j].intensity = -2.0;for (const auto& large_cluster : (*large_clusters))for (const auto& j : large_cluster.indices)(*cloud_out)[j].intensity = +10.0;for (const auto& cluster : (*clusters)){int label = rand () % 8;for (const auto& j : cluster.indices)(*cloud_out)[j].intensity = label;}// Save the output point cloudstd::cerr << "Saving...\n", tt.tic ();pcl::io::savePCDFile ("output.pcd", *cloud_out);std::cerr << ">> Done: " << tt.toc () << " ms\n";return (0);}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16 FATAL_ERROR)#指定CMake的最低版本要求为3.16
project(project)#设置项目名称
find_package(PCL 1.10 REQUIRED)#查找PCL库,要求版本为1.10或更高。
include_directories(${PCL_INCLUDE_DIRS})#将PCL库的头文件目录添加到包含路径中
link_directories(${PCL_LIBRARY_DIRS})#将PCL库的库文件目录添加到链接器搜索路径中。
add_definitions(${PCL_DEFINITIONS})#添加PCL库的编译器定义
add_executable (conditional_euclidean_clustering conditional_euclidean_clustering.cpp)
target_link_libraries (conditional_euclidean_clustering ${PCL_LIBRARIES})#将PCL库链接到可执行文件目标。

运行结果

注意:当使用 PCL 的标准 PCD 查看器打开输出点云时,按“5”将切换到强度通道可视化。 太小的簇将被涂成红色,太大的簇将被涂成蓝色,而实际的簇/感兴趣的物体将被随机着色为黄色和青色, 如果不按则都为一个颜色。
在这里插入图片描述

函数

补充内容

  • std::cout << “降采样中\n”,tt.tic();和std::cout << “降采样中\n”,tt.tic()<<std::endl;的区别
    1. std::cout << “降采样中\n”, tt.tic();
      这个语句使用了逗号运算符 ,。逗号运算符会按照从左到右的顺序依次计算其左右两侧的表达式,并返回右侧表达式的值。在这个语句中,首先会输出字符串 “降采样中\n”,然后计算 tt.tic(),但是 tt.tic() 的返回值会被丢弃,因为它没有被使用或输出。
    2. std::cout << “降采样中\n”, tt.tic() << std::endl;
      这个语句也使用了逗号运算符 ,。同样地,它会先输出字符串 “降采样中\n”,然后计算 tt.tic()。但是,这里的 tt.tic() 的返回值会被传递给 std::cout,然后再输出一个换行符 std::endl。

第二个语句不仅会输出字符串 “降采样中\n”,还会输出 tt.tic() 的返回值,并在最后添加一个换行符

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

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

相关文章

【分析 GClog 的吞吐量和停顿时间、heapdump 内存泄漏分析】

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容GClog分析以优化吞吐量和停顿时间步骤1: 收集GClog步骤2: 分析GClog步骤3: 优化建议步骤4: 实施优化 Heapdump内存泄漏分析步骤1: 获取Heapdump步骤2: 分析Heapdump步骤3: 定位泄漏对象步骤4: 分析泄漏原因步骤5: 修复泄漏…

预训练的启蒙:浅谈BERT、RoBERTa、ALBERT、T5

文章目录 Transformer揭开预训练序幕为什么RNN/LSTM需要从头训练&#xff1f; BERT核心特点预训练任务架构应用和影响 RoBERTa改进点BERT和RoBERTa的MASK策略对比BERT的静态MASK策略RoBERTa的动态MASK策略效果 总结 ALBERT改进点参数共享因式分解嵌入参数和LoRa对比 总结 T5核心…

Electron打包vue+java+nginx 踩坑记录

记录下遇到的问题&#xff1a; ⚠注意&#xff1a;64位系统和32位系统的配置不太一样 1、运行npm run packager失败 原因&#xff1a;在package.json没有对应命令 解决&#xff1a;在package.json 中添加对应命令&#xff0c;其中testApp是你想要的输入的项目名称&#xff0…

element用户上传头像组件带大图预览,和删除功能

element 用户上传组件不支持大图预览&#xff0c;拿组件的简单修改一些&#xff0c;发表上来主要是记一下&#xff0c;以后可以用 效果图 <template><div class"flex-img"><div class"el-upload-list el-upload-list--picture-card" v-sh…

word从零基础到高手【办公】

第1课 - word基础操作快速入门第2课 - 让你效率10倍提升的快捷操作第3课 - word排版快速入门第4课 - 排版实战案例讲解第5课 - 搞定论文排版全过程第6课 - 让你的word更强大的神技第7课 - 提高工作效率必备的批量操作 资料截图如下: 发送: "word办公" 获取提取码

动态规划-入门理解

一、什么情况可以使用动态规划 动态规划 最优子结构 重叠子问题 转移方程 最优子结构&#xff1a;保证能从局部解推出全局解&#xff0c;也就是保证能够写出转移方程 重叠子问题&#xff1a;说明暴力解法太耗时&#xff0c;我们可以使用动态规划进行优化 转移方程&#xff…

基于GAN的图像补全实战

数据与代码地址见文末 论文地址:http://iizuka.cs.tsukuba.ac.jp/projects/completion/data/completion_sig2017.pdf 1.概述 图像补全,即补全图像中的覆盖和缺失部分, 网络整体结构如下图所示,整体网络结构还是采取GAN,对于生成器,网络结构采取Unet的形式,首先使用卷积…

rac数据库默认网关不通导致集群异常

集群CSSD进程reconfiguration完成&#xff0c;显示2个节点都在线。但ora.net1.network服务启动失败&#xff0c;且有依赖关系的资源随后启动失败并且已经达到上限。 查看两个节点的网络信息&#xff0c;发现两个节点的默认网关是不一致的。 修改故障节点网关 在RAC中&#xff0…

基于springboot+vue+Mysql的职称评审管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

在线人数统计功能怎么实现?

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 在线人数统计这个功能相信大家一眼就明白是…

基于奇异值分解(Singular Value Decomposition,SVD)的信号去噪算法

01.基于奇异值分解(SVD)去噪原理 奇异值分解&#xff08;Singular Value Decomposition, SVD&#xff09;是线性代数中一种重要的矩阵分解方法&#xff0c;它可以用于信号处理、图像去噪、数据压缩等多种应用。在图像去噪的过程中&#xff0c;SVD可以用来分离图像中的信号和噪…

Transformer详解和知识点总结

目录 1. 注意力机制1.1 注意力评分函数1.2 多头注意力&#xff08;Multi-head self-attention&#xff09; 2. Layer norm3. 模型结构4. Attention在Transformer中三种形式的应用 论文&#xff1a;https://arxiv.org/abs/1706.03762 李沐B站视频&#xff1a;https://www.bilibi…

SpringBoot Starter子模块下无法生成spring-configuration-metadata.json文件

一.SpringBoot Starter的作用 Starter的机制极大的方便了业务系统接入相关能力&#xff0c;它有一个非常友好的能力就是引入starter后&#xff0c;在配置相关的配置项时&#xff0c;能自动提示&#xff0c;极大的提升了使用的友好度。 二.遇到的问题 我在为Juggle开发系统star…

CLI举例:上下行连接路由器(路由引流)

CLI举例&#xff1a;上下行连接路由器&#xff08;路由引流&#xff09; 介绍了集群设备&#xff0c;上下行连接路由器的配置举例。 组网需求 如图1所示&#xff0c;上行网络使用BGP&#xff0c;下行网络使用OSPF&#xff0c;多数据中心统一通过路由器R4接入Internet。 希望…

HarmonyOS 开发-多模态页面转场动效实现案例

介绍 本示例介绍多模态页面转场动效实现&#xff1a;通过半模态转场实现半模态登录界面&#xff0c;通过配置NavDestinationMode类型为DIALOG&#xff0c;实现半模态的背景为透明&#xff0c;再与全屏模态和组件转场结合实现多模态组合登录场景&#xff0c;其中手机验证码登录…

从零开始为香橙派orangepi zero 3移植主线linux——2.kernel + rootfs

从零开始为香橙派orangepi zero 3移植主线linux——2.kernel rootfs 参考文章&#xff1a;一、linux kernel移植二、根文件系统2.1 buildroot构建1.修改toolchain下的交叉编译链2.修改系统配置3.去除内置kernel和uboot编译4.添加rootfs.tar格式的输出 2.2 ubuntu-base移植 三、…

Linux gcc day4 权限

首先来看比如ls、pwd等究竟是什么呢&#xff1f; 那ls是如何在shell中执行起来的呢&#xff1f;shell命令又是什么呢&#xff1f; shell命令&#xff1a;命令行解释器&#xff1a;表现&#xff1a;你看到的命令行提示符&#xff0c;以及可以输入指令并且可以执行&#xff08;是…

贪心算法简介

目录 一、什么是贪心算法&#xff1f; 二、贪心算法的特点 三、贪心算法解决找零问题、最短路径问题、背包问题 1.找零问题 2.最短路径问题 3.背包问题 一、什么是贪心算法&#xff1f; 贪心算法就是希望通过局部最优来解决全局最优 基本步骤&#xff1a;1.将问题分为若…

【I/O】Unix IO 介绍

IO 模型&#xff08;一&#xff09; Unix IO 一个输入操作共包含两个阶段&#xff1a; 等待数据准备好从内核将数据复制到进程 对于一个套接字上的输入操作&#xff0c;通常第一步是等待数据从网络中到达&#xff0c;当数据到达时&#xff0c;先将数据复制到内核缓冲区中&a…

【UE 委托】如何利用函数指针理解委托的基本原理

目录 0 引言1 函数指针模拟多播委托 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;UE虚幻引擎专栏&#x1f4a5; 标题&#xff1a;【UE 委托】如何利用函数指针理解委托的基本原理❣️ 寄语&#xff1a;书到用时方恨少&#xff0c;事非经过不知难…