PCL 将点云投影到拟合平面

news2024/12/24 13:42:53

PCL点云算法汇总及实战案例汇总的目录地址链接:

PCL点云算法与项目实战案例汇总(长期更新)


一、概述

        点云投影到拟合平面是指将三维点云数据中的点投影到与其最接近的二维平面上。通过投影到平面,可以消除数据的高度变化或Z轴信息,使得点云数据在平面上更加集中和规整。这在点云简化、平面特征提取和2D视觉分析中非常有用。

1.1原理

        平面拟合和投影的过程通常涉及以下几个步骤:

        1.平面拟合:使用最小二乘法拟合点云的主平面,即找到一个平面,使得所有点到该平面的距离之和最小。拟合平面的方程为:

                                                ax+by+cz+d=0

        其中(a,b,c)是平面法向量,d是平面的偏移量。

        2.点云投影:将点云投影到该平面上,计算每个点到平面的垂直投影。投影点的计算公式为:

1.2实现步骤

  1. 加载点云数据。
  2. 通过PCA或最小二乘法拟合一个平面
  3. 将点云数据投影到拟合平面上。
  4. 可视化原始点云和投影后的点云。

1.3应用场景

  1. 数据降维:在三维点云中,通过将点云投影到二维平面,可以实现数据降维处理。
  2. 形状分析:在表面分析中,通过平面投影可以分析平面内的特征。
  3. 点云简化:将曲面简化为平面后,便于进行后续特征分析或轮廓提取。

二、代码实现

2.1关键函数

2.1.1 平面投影

#include <pcl/filters/project_inliers.h>
#include <pcl/ModelCoefficients.h>

// 将点云投影到平面
void projectPointCloudToPlane(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr projectedCloud)
{
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    coefficients->values.resize(4);
    coefficients->values[0] = 0;  // 设置平面系数 a
    coefficients->values[1] = 0;  // 设置平面系数 b
    coefficients->values[2] = 1.0;  // 设置平面系数 c,投影到 X-Y 平面
    coefficients->values[3] = 0;  // 设置平面常数 d

    pcl::ProjectInliers<pcl::PointXYZ> proj;
    proj.setModelType(pcl::SACMODEL_PLANE);
    proj.setInputCloud(cloud);
    proj.setModelCoefficients(coefficients);
    proj.filter(*projectedCloud);  // 将点云投影到平面上
}

 2.1.2 可视化原始点云和投影点云

#include <pcl/visualization/pcl_visualizer.h>

// 可视化原始点云和投影点云
void visualizePointClouds(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr projectedCloud)
{
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Point Cloud Visualization"));

    int vp1, vp2;
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp1);
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp1);  // 白色背景
    viewer->addText("Original Point Cloud", 10, 10, "vp1_text", vp1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 255, 0, 0);  // 红色
    viewer->addPointCloud(cloud, cloud_color, "original_cloud", vp1);

    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp2);
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp2);  // 浅灰色背景
    viewer->addText("Projected Point Cloud", 10, 10, "vp2_text", vp2);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> projected_color(projectedCloud, 0, 255, 0);  // 绿色
    viewer->addPointCloud(projectedCloud, projected_color, "projected_cloud", vp2);

    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
}

2.2完整代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/project_inliers.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

// 将点云投影到平面
void projectPointCloudToPlane(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr projectedCloud)
{
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    coefficients->values.resize(4);
    coefficients->values[0] = 0;  // 设置平面系数 a
    coefficients->values[1] = 0;  // 设置平面系数 b
    coefficients->values[2] = 1.0;  // 设置平面系数 c,投影到 X-Y 平面
    coefficients->values[3] = 0;  // 设置平面常数 d

    pcl::ProjectInliers<pcl::PointXYZ> proj;
    proj.setModelType(pcl::SACMODEL_PLANE);
    proj.setInputCloud(cloud);
    proj.setModelCoefficients(coefficients);
    proj.filter(*projectedCloud);  // 将点云投影到平面上
}

// 可视化原始点云和投影点云
void visualizePointClouds(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr projectedCloud)
{
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Point Cloud Visualization"));

    int vp1, vp2;
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp1);
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp1);  // 白色背景
    viewer->addText("Original Point Cloud", 10, 10, "vp1_text", vp1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 255, 0, 0);  // 红色
    viewer->addPointCloud(cloud, cloud_color, "original_cloud", vp1);

    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp2);
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp2);  // 浅灰色背景
    viewer->addText("Projected Point Cloud", 10, 10, "vp2_text", vp2);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> projected_color(projectedCloud, 0, 255, 0);  // 绿色
    viewer->addPointCloud(projectedCloud, projected_color, "projected_cloud", vp2);

    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
}

int main(int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile<pcl::PointXYZ>("bunny.pcd", *cloud);

    // 将点云投影到平面
    projectPointCloudToPlane(cloud, cloud_projected);

    // 保存投影后的点云
    pcl::io::savePCDFileBinary("cloud_projected.pcd", *cloud_projected);

    // 可视化原始点云和投影后的点云
    visualizePointClouds(cloud, cloud_projected);

    return 0;
}

三、实现效果

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

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

相关文章

小程序会取代APP吗?——零工市场小程序和APP的区别

小程序在某些场景下有着取代了APP的潜力&#xff0c;特别是零工市场这样的领域中&#xff0c;单其中能不能完全取代还有待分析。 1.小程序无需下载&#xff0c;想用的时候随时打开&#xff0c;在零工市场领域&#xff0c;小程序可以快速连接求职者和雇主&#xff0c;满足临时工…

秋天来临,猫咪又到换毛季,掉毛严重怎么办?宠物空气净化器有用吗?

秋天到了&#xff0c;新一轮的宠物换毛季又来了。谁能想到这只胖猫和之前刚接回来时的皮包骨小猫是同一只&#xff01;除了养了一年长了些肉外&#xff0c;更多的都是换毛季掉毛”膨胀“的。每天下班回家都要搞卫生&#xff0c;家里衣服上、地板上&#xff0c;目光所及之处都有…

GNU链接器(LD):PROVIDE、PROVIDE_HIDDEN关键字介绍

0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分&#xff1a; &#xff08;1&#xff09;编译器 &#xff08;2&#xff09;汇编器 &#xff08;3&#xff09;链接器 &#xff08;4&#xff09;lib库 在GNU工具链中&…

用布尔表达式巧解数字电路图

1.前置知识 明确AND,OR,XOR,NOR,NOT运算的规则 参见:E25.【C语言】练习:修改二进制序列的指定位 这里再补充一个布尔运算符:NOR,即先进行OR运算,再进行NOT运算 如下图为其数字电路的符号 注意到在OR符号的基础上,在尾部加了一个(其实由简化而来) 附:NOR的真值表 2.R-S触发…

第二十章 番外 混淆矩阵

混淆矩阵&#xff08;Confusion Matrix&#xff09;是一种用于描述监督学习中分类模型性能的特定表格布局。它提供了直观的方式来理解分类器的性能&#xff0c;特别是对于多类别分类任务。混淆矩阵通过比较实际类别标签与分类器预测的类别标签来展示分类结果。 混淆矩阵的基本…

2-118 基于matlab的六面体建模和掉落仿真

基于matlab的六面体建模和掉落仿真&#xff0c;将对象建模为刚体来模拟将立方体扔到地面上。同时考虑地面摩擦力、刚度和阻尼所施加的力&#xff0c;在三个维度上跟踪平移运动和旋转运动。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-118 基于matla…

Microsoft Edge 离线安装包制作或获取方法和下载地址分享

方法一&#xff1a;自制压缩包 进入目录 "C:\Program Files (x86)\Microsoft\Edge\Application" 或 "C:\Program Files (x86)\Microsoft\EdgeCore\Edge版本号"&#xff0c;将所有文件打包&#xff0c;再放到没有安装到 Edge 的电脑里解压&#xff0c;运行…

打破常规,BD仓储物流的效能提升!

当前&#xff0c;随着国家战略的推进&#xff0c;JS与民用领域的融合不断加深&#xff0c;物流业也步入了军民融合的新时代。在智能仓储物流方面&#xff0c;JS物流的智能化进展受到了BD系统的高度关注和重视。 一、建设JS仓储物流RFID基础设施 JS物流领域引入RFID技术的基础工…

入门端到端第一步!最新综述回顾基于深度学习的规划方法发展历程

这篇新的综述,系统的回顾了基于深度学习的预测和规划方法, 端到端方法的发展历程, 非常适合初学者了解领域背景. The Integration of Prediction and Planning in Deep Learning Automated Driving Systems: A Review 0. 摘要 自动化驾驶系统有潜力彻底改变个人、公共和货物…

Cesium 获取当前视角信息

通过 浏览器控制台&#xff0c;直接获取到当前地球视角的信息&#xff0c;然后通过 flyTo 跳转视角。 方法&#xff1a; 控制台内输入下列代码&#xff0c;控制台就会输出视角信息&#xff1a; const camera viewer.camera; const position camera.positionCartographic; c…

Python:条件分支 if 语句全讲解

Python&#xff1a;条件分支 if 语句全讲解 如果我拿出下面的代码&#xff0c;阁下该做何应对&#xff1f; if not reset_excuted and (terminated or truncated):... else:...---- 前言&#xff1a; 消化论文代码的时候看到这个东西直接大脑冻结&#xff0c;没想过会在这么…

高含金量WebGIS学习教程?

智慧校园——适合0基础入门 智慧交通——适合0基础入门 VUE-适合前端进阶 Mapbox项目开发实例 Openlayers零基础入门 智慧机场——适合有前端基础 threejs三维开发入门 三维进阶&#xff1a;cesium零基础入门教程 面试讲解&#xff1a;剖析地信大厂技术面试真题&#x…

【算法】DP系列之 斐波那契数列模型

【ps】本篇有 4 道 leetcode OJ。 目录 一、算法简介 二、相关例题 1&#xff09;第 N 个泰波那契数 .1- 题目解析 .2- 代码编写 2&#xff09;三步问题 .1- 题目解析 .2- 代码编写 3&#xff09;使用最小花费爬楼梯 .1- 题目解析 .2- 代码编写 4&#xff09;解码…

vue3实现 长列表虚拟滚动

1、直接看代码 <template><!--定义一个大容器&#xff0c;此容器可以滚动--><div class"view" ref"viewRef" scroll"handleScroll"><!--定义一个可以撑满整个data的容器&#xff0c;主要是让父元素滚动起来--><div …

EasyExcel读入数字类型数据时出现小数位丢失精度问题

这里写自定义目录标题 问题现象解决方案 问题现象 目前使用easyExcel读取导入文档时发现文档中的小数值4076204076.65会被读取为4076204076.6500001 尝试去查看了excel解压后的文件&#xff0c;发现这条数据在xml里存储的值就是4076204076.6500001&#xff0c;即是excel存储小…

java中的I/O(8个案例+代码+效果图)

目录 1.File类 1&#xff09;常用构造方法 1&#xff09;File(String pathname) 2&#xff09;File(String parent, String child) 3&#xff09;File(File parent, String child) 2&#xff09;常用方法 1&#xff09;boolean canRead() 2&#xff09;boolean canWrite() 3&am…

诺奖现场采访2024物理学得主Hinton:当前AI革命堪比工业革命,且将在智力上全面超越人类

当地时间昨天&#xff0c;2024年10月8日&#xff0c;瑞典皇家科学院宣布将本年度诺贝尔物理学奖授予两位被誉为AI教父的科学家&#xff1a;约翰J霍普菲尔德&#xff08;John J. Hopfield&#xff09;和杰弗里E辛顿&#xff08;Geoffrey E. Hinton&#xff09;。该奖项旨在表彰他…

Leetcode 买卖股票的最佳时机

这段代码的目的是解决“买卖股票的最佳时机”这个问题&#xff0c;即在给定的股票价格数组中&#xff0c;找到一次买入和卖出所能获得的最大利润。 算法思想&#xff1a; 定义两个变量&#xff1a; minPrice: 这个变量用于记录迄今为止遇到的最小股票价格&#xff08;买入价格…

软件项目必须进行验收测试吗?专业验收测试报告如何获取?

软件项目验收测试是一种关键的质量保证活动&#xff0c;旨在确保软件产品符合用户需求和预期功能。它通常是在软件开发完成后&#xff0c;由客户或第三方测试机构进行的最终测试环节。验收测试的目的是确认软件的性能、功能、安全性和其他特性&#xff0c;以确保交付的产品能够…

【开源免费】基于SpringBoot+Vue.JS医院电子病历管理系统(JAVA毕业设计)

本文项目编号 T 008 &#xff0c;文末自助获取源码 \color{red}{T008&#xff0c;文末自助获取源码} T008&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 医…