『分割』 分割圆柱

news2024/12/28 20:28:38
原始点云

 

直通滤波过滤后(z:0~1.5)

 

分割到的平面

 

分割得到的圆柱形

 

代码:

#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h> // 用于提取指定索引的数据
#include <pcl/filters/passthrough.h>

#include <pcl/features/normal_3d.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>

#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/pcl_visualizer.h>

typedef pcl::PointXYZ PointT;

int main(){
    pcl::PCDReader reader;
    pcl::PassThrough<PointT> pass;
    pcl::NormalEstimation<PointT, pcl::Normal> ne;
    pcl::SACSegmentationFromNormals<PointT, pcl::Normal> seg;
    pcl::PCDWriter writer;
    pcl::ExtractIndices<PointT> extract;
    pcl::ExtractIndices<pcl::Normal> extract_normals;
    pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);


    pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
    pcl::PointCloud<PointT>::Ptr cloud_filtered(new pcl::PointCloud<PointT>);
    pcl::PointCloud<PointT>::Ptr cloud_filtered2(new pcl::PointCloud<PointT>);

    pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
    pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2(new pcl::PointCloud<pcl::Normal>);

    pcl::ModelCoefficients::Ptr coefficient_plane(new pcl::ModelCoefficients), coefficient_cylinder(new pcl::ModelCoefficients);

    pcl::PointIndices::Ptr inliers_plane(new pcl::PointIndices), inliers_cylinder(new pcl::PointIndices);


    // 读取点云数据
    reader.read("/home/jason/file/pcl-learning/12segmentation分割/2cylinder_segmentation/table_scene_mug_stereo_textured.pcd", *cloud);
    std::cerr << "PointCloud has: " << cloud->points.size() << " data points." << std::endl;

    // 直通滤波
    pass.setInputCloud(cloud);
    pass.setFilterFieldName("z");
    pass.setFilterLimits(0, 1.5);
    pass.filter(*cloud_filtered);
    std::cerr << "PointCloud after filtering has: " << cloud_filtered->points.size() << " data points." << std::endl;

    // 过滤后的点云进行法线估计,为后续进行基于法线分割准备数据
    ne.setSearchMethod(tree);
    ne.setInputCloud(cloud_filtered);
    ne.setKSearch(50);
    ne.compute(*cloud_normals);

    // 分割平面模型
    seg.setOptimizeCoefficients(true);
    seg.setModelType(pcl::SACMODEL_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);
    seg.setNormalDistanceWeight(0.1);
    seg.setMaxIterations(100);
    seg.setDistanceThreshold(0.03);
    seg.setInputCloud(cloud_filtered);
    seg.setInputNormals(cloud_normals);

    // 获取平面模型的系数和处在平面的内点
    seg.segment(*inliers_plane, *coefficient_plane);
    std::cerr << "plane coefficients: " << *coefficient_plane << std::endl;

    // 从点云中抽取分割的处在平面上的点集
    extract.setInputCloud(cloud_filtered);
    extract.setIndices(inliers_plane);
    extract.setNegative(false); // 不提取索引的补集,仅提取与索引匹配的点,即提取属于平面的点


    // 存储分割得到的平面上的点到点云文件
    pcl::PointCloud<PointT>::Ptr cloud_plane(new pcl::PointCloud<PointT>);
    extract.filter(*cloud_plane);
//    std::cerr << "PointCloud representing the planar component: " << cloud_plane->points.size() << " data points." << std::endl;
//    writer.write("result.pcd", *cloud_plane, false); // 不以二进制写入点云数据,即ASCII编码的文本形式写入点云数据到文件中

//    // Remove the planar inliers, extract the rest
    extract.setNegative(true); // 索引的补集
    extract.filter(*cloud_filtered2); // 提取点云数据

    extract_normals.setNegative(true); // 索引的补集
    extract_normals.setInputCloud(cloud_normals); // 输入法线数据
    extract_normals.setIndices(inliers_plane); // 设置索引
    extract_normals.filter(*cloud_normals2); // 提取法线数据

    // Create the segmentation object for cylinder segmentation and set the parameters
    seg.setOptimizeCoefficients(true);          // 设置对估计模型优化
    seg.setModelType(pcl::SACMODEL_CYLINDER);   // 设置分割模型为圆柱形
    seg.setMethodType(pcl::SAC_RANSAC);         // 参数估计方法
    seg.setNormalDistanceWeight(0.1);           // 设置表面法线权重系数
    seg.setMaxIterations(10000);                // 设置迭代的最大次数
    seg.setDistanceThreshold(0.05);             // 设置内点到模型的距离允许最大值
    seg.setRadiusLimits(0, 0.1);               // 设置估计出的圆柱模型的半径的范围, 这个蛮重要的
    seg.setInputCloud(cloud_filtered2);
    seg.setInputNormals(cloud_normals2);

    // Obtain the cylinder inliers and coefficients
    seg.segment(*inliers_cylinder, *coefficient_cylinder);
    std::cerr << "Cylinder coefficients: " << *coefficient_cylinder << std::endl;

    // write the cylinder inliers to disk
    extract.setInputCloud(cloud_filtered2);
    extract.setIndices(inliers_cylinder);
    extract.setNegative(false);
    pcl::PointCloud<PointT>::Ptr cloud_cylinder(new pcl::PointCloud<PointT>);
    extract.filter(*cloud_cylinder);
    if (cloud_cylinder->points.empty())
        std::cerr << "Can't find the cylindercal companent." << std::endl;
    else
    {
        std::cerr << "PointCloud representing the cylindrical component: " << cloud_cylinder->points.size() << " data points." << std::endl;
        writer.write("result2.pcd", *cloud_cylinder, false); //
    }

    // 可视化
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("viewer"));



//    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_red(cloud_filtered2, 255, 0, 0);
//    viewer->addPointCloud(cloud_filtered2, cloud_out_red, "cloud_out1");

//    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_green(cloud_plane, 0, 255, 0);
//    viewer->addPointCloud(cloud_plane, cloud_out_green, "cloud_out2");

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_blue(cloud_cylinder, 0, 255, 0);
    viewer->addPointCloud(cloud_cylinder, cloud_out_blue, "cloud_out3");

    viewer->spin();
    return 0;

}

注意:

这里是先分割平面,然后在点云数据中剔除属于平面的点云,然后才分割圆柱形。

不要觉得分割平面这一步多余,直接分割圆柱形的效果差的一批

参考:

PCL学习笔记(二十五)-- 圆柱体模型分割_pcl 分割圆柱_看到我请叫我学C++的博客-CSDN博客

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

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

相关文章

伪标签(pseudo label)(半监督学习)

使用伪标签进行半监督学习&#xff0c;在机器学习竞赛当中是一个比较容易快速上分的关键点。下面给大家来介绍一下什么是基于伪标签的半监督学习。在传统的监督学习当中&#xff0c;我们的训练集具有标签&#xff0c;同时&#xff0c;测试集也具有标签。这样我们通过训练集训练…

RS485转ETHERCAT连接西门子支持ethercat吗

我们将为大家介绍一款强大的设备——远创智控YC-ECT-RS485/232通讯网关。这是一款自主研发的ETHERCAT从站功能的网关&#xff0c;它能够将ETHERCAT网络和RS485或RS232设备无缝连接。 这款网关在ETHERCAT总线和RS485或RS232总线中均能发挥主站或从站的作用。它的最大特点就是解决…

ICCV 2023 接收结果出炉!再创历史新高!录用2160篇!(附6篇最新论文)

点击下方卡片&#xff0c;关注“CVer”公众号 AI/CV重磅干货&#xff0c;第一时间送达 点击进入—>【计算机视觉】微信交流群 2023 年 7 月 14 日13:03&#xff0c;ICCV 2023 顶会论文接收结果出炉&#xff01;这次直接放出论文 Accepted Paper ID List。这也意味着&#xf…

【大数据趋势】7月15日 汇率,美澳,恒指期货的大数据趋势概率分析。

1. 数据源头之一 : 美元汇率破位&#xff0c;下面有3-7%的空间 从程序模拟趋势来看&#xff0c;如果没有干预&#xff0c;美元这个破位后&#xff0c;下方空间是3-7%。从中期趋势来看&#xff0c;是一次破位寻找新的稳定位置&#xff0c;在RSI的底部附近&#xff0c;现在刚刚开…

6.3.1 利用Wireshark进行协议分析(一)

6.3.1 利用Wireshark进行协议分析&#xff08;一&#xff09; Wireshark是目前全球使用最广泛的抓包软件&#xff0c;也是很强大的抓包软件&#xff0c;不管从事网络测试还是软件开发工程师&#xff0c;Wireshark都是一个非常实用的好工具。单纯的学习网络理论知识很抽象&…

个人笔记:下载及配置maven详细步骤

下载maven以及配置maven 访问 maven 官网&#xff0c;这里我下载的是 3.6.1的版本&#xff0c;尽量不要下载太新的版本&#xff0c;新版本可能会不太稳定&#xff0c;遇到一些奇奇怪怪的问题。 官网地址&#xff1a; https://maven.apache.org/download.cgi点击 download&…

安全开发-PHP应用留言板功能超全局变量数据库操作第三方插件引用后台模块SessionCookieToken身份验证唯一性

文章目录 开发环境数据导入-mysql架构&库表列数据库操作-mysqli函数&增删改查数据接收输出-html混编&超全局变量第三方插件引用-js传参&函数对象调用身份验证-Cookie使用身份验证-Session使用唯一性判断-Token使用具体安全知识点&#xff1a;Cookie和Session都…

aes加密解密算法流程

有了https加密传输为何还要使用AES加密 HTTPS&#xff08;HTTP Secure&#xff09;是基于 SSL/TLS 协议的安全通信协议&#xff0c;通过对传输的数据进行加密和认证来确保通信的机密性、完整性和身份验证。它使用了公钥加密来建立安全通道&#xff0c;并使用对称密钥加密来加密…

分享一个创意滚筒按钮

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>滚筒按钮</title><style>* {border: 0;box-sizing: border-box;margin: 0;padding: 0;}:ro…

COMP527数据分析:中心性度量

在数据分析中&#xff0c;中心性度量通常是指描述数据集中心位置的统计量。

gorm实现动态sql

文章目录 前言需求实现步骤 前言 书接上回&#xff0c;解决了选择性的忽略某些字段这个问题&#xff0c;新的问题出现&#xff0c;想要使用gorm完成动态sql&#xff0c;我只知道mybatis中使用标签可以完成动态sql&#xff0c;不会使用gorm完成动态sql&#xff0c;下面通过一个…

基于linux下的高并发服务器开发(第一章)- 文件属性操作函数

08 / 文件属性操作函数 1、access.c #include <unistd.h>int access(const char *pathname, int mode); 作用&#xff1a;判断某个文件是否有某个权限&#xff0c;或者判断文件是否存在 参数&#xff1a; - pathname: 判断的文件路径 - mode: …

nacos注册中心+Ribbon负载均衡+完成openfeign的调用(超详细步骤)

目录 1.注册中心 1.1.nacos注册中心 1.2. 微服务注册和拉取注册中心的内容 2.3.修改订单微服务的代码 3.负载均衡组件 3.1.什么是负载均衡 3.2.什么是Ribbon 3.3.Ribbon 的主要作用 3.4.Ribbon提供的负载均衡策略 4.openfeign完成服务调用 4.1.什么是OpenFeign 4.2…

搜索引擎elasticsearch :安装elasticsearch (包含安装组件kibana、IK分词器、部署es集群)

文章目录 安装elasticsearch1.部署单点es1.1.创建网络1.2.加载镜像1.3.运行 2.部署kibana2.1.部署2.2.DevTools2.3 分词问题(中文不友好) 3.安装IK分词器3.1.在线安装ik插件&#xff08;较慢&#xff09;3.2.离线安装ik插件&#xff08;推荐&#xff09;1&#xff09;查看数据卷…

相机图像质量研究(1)Camera成像流程介绍

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

检测到目标X-XSS-Protection响应头缺失

详细描述 HTTP X-XSS-Protection 响应头是 Internet Explorer&#xff0c;Chrome 和 Safari 的一个特性&#xff0c;当检测到跨站脚本攻击 (XSS)时&#xff0c;浏览器将停止加载页面。 X-XSS-Protection响应头的缺失使得目标URL更易遭受跨站脚本攻击。 解决办法 将您的服务…

清华青年AI自强作业hw7:基于Yolo实现位置检测任务

清华青年AI自强作业hw7&#xff1a;基于Yolo实现位置检测任务 简述作业实现相关链接 一起学AI系列博客&#xff1a;目录索引 简述 hw7作业为基于Yolo模型&#xff0c;对PASCAL_VOC_2007数据集的20类物体进行位置探测。数据集为600张图像&#xff0c;因此建议训练迭代次数小于10…

chrome插件”hello-world“开发详细流程以及日志定位

本插件开发文档翻译于Google官方文档Chrome Extension development basics - Chrome Developers 一、插件开发 hello-world插件开发的具体流程如下&#xff1a; 创建目录hello-world&#xff0c; 存放源代码 在此目录中创建一个名为manifest.json的新文件并添加以下代码&…

会声会影2023旗舰版Corel VideoStudio Ultimate 2023 V26.0.0.136整合盘版本

会声会影2023旗舰版Corel VideoStudio Ultimate 2023 V26.0.0.136整合盘版本是一款有趣且直观的视频编辑器&#xff0c;包含高级工具和高级效果&#xff0c;智能功能和最佳性能的高级视频编辑软件&#xff0c;将您最美好的时刻和生活体验变成令人惊叹的电影。 从自定义标题和过…

克服“一支笔,一双手,一道力扣(Leetcode)做一宿”的窘境:我的烦恼和建议

文章目录 每日一句正能量前言原因建议自己相关的经历可能存在的问题根据问题进行分解或建立思维导图分享好用的刷题网站并进行介绍后记 每日一句正能量 想升高&#xff0c;有两样东西&#xff0c;那就是必须作鹰&#xff0c;或者作爬行动物。——巴尔扎克 前言 作为一名计算机…