当前位置: 首页 > article >正文

PCL 将点云投影到拟合平面

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.kler.cn/news/353583.html

相关文章:

  • SpringBoot+MyBatis+MySQL项目基础搭建
  • AI智能聊天问答系统源码+AI绘画系统+图文搭建部署教程,文生图图生图,TTS语音识别输入,AI智能体,文档分析
  • 当贝投影双十一战报揭晓:天猫投影品类销量稳居首位
  • Android MQTT调试助手开发
  • Spring Boot学习助手:答疑解惑平台
  • 蛮久没更新自己的状态了,今天趁机更新一下吧
  • 【手写数字识别】Python+CNN卷积神经网络算法+人工智能+深度学习+模型训练
  • 【Python】Conda离线执行命令
  • 架构师之路-学渣到学霸历程-19
  • react hooks中在setState后输出state为啥没有变化,如何解决
  • SpringBoot概览及核心原理
  • 深入解析 Flutter兼容鸿蒙next全体生态的横竖屏适配与多屏协作兼容架构
  • 高效录制 PPT 秘籍:四款卓越录屏软件深度解析
  • 插齿刀的齿数选择不同会有什么影响?
  • 公网IP and 局域网IP
  • 网页复制粘贴助手,Chrome网页复制插件(谷歌浏览器复制插件)
  • servlet基础与环境搭建(idea版)
  • 解决 MySQL 连接数过多导致的 SQLNonTransientConnectionException 问题
  • 25四非网安保研回忆录(北航网安/东南网安/重大计科等)
  • 更加灵活便捷!Fortinet统一SASE解决方案全新增强功能来袭