PCL 将点云投影到拟合直线

news2024/12/24 9:05:44

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

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


一、概述

该代码通过拟合直线模型,将点云投影到该直线上,并输出投影后的点云。

1.1原理

点云投影到直线的过程主要包括以下两步:

  1. 空间直线拟合:利用随机采样一致性(RANSAC)算法拟合一条空间直线,选择出点云中最符合直线模型的内点。
  2. 点云投影:通过几何模型的参数,将原始点云中的每个点投影到拟合的直线上。

直线的参数由直线的起点 (x₀, y₀, z₀) 和方向向量 (a, b, c) 共同决定,投影点的位置通过直线的几何公式进行计算。

1.2实现步骤

  1. 加载点云数据。
  2. 使用RANSAC算法拟合直线模型,提取符合模型的内点。
  3. 获取拟合直线的参数。
  4. 创建滤波器,将点云投影到拟合的直线上。
  5. 保存并输出投影后的点云数据。

1.3应用场景

  1. 工业检测:适用于检测长直杆状物体或轨迹的点云数据处理。
  2. 3D重建:在3D场景中,通过拟合直线和投影来简化建模。
  3. 自动化装配:直线投影可以用于物体路径规划。

二、代码实现

2.1关键函数

2.1.1 RANSAC直线拟合

#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_line.h>

// 使用RANSAC拟合直线
void fitLineWithRANSAC(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    Eigen::VectorXf& lineCoefs, std::vector<int>& inliers)
{
    pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr modelLine(
        new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));  // 创建直线模型
    pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(modelLine);  // 创建RANSAC对象
    ransac.setDistanceThreshold(0.01);  // 设置内点距离阈值
    ransac.setMaxIterations(1000);  // 设置最大迭代次数
    ransac.computeModel();  // 执行RANSAC拟合
    ransac.getInliers(inliers);  // 获取内点索引
    ransac.getModelCoefficients(lineCoefs);  // 获取直线模型参数
}

2.1.2 点云投影到拟合直线

#include <pcl/filters/project_inliers.h>

// 投影点云到拟合的直线
void projectPointCloudToLine(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    Eigen::VectorXf& lineCoefs,
    pcl::PointCloud<pcl::PointXYZ>::Ptr projectedCloud)
{
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    coefficients->values.resize(6);
    for (int i = 0; i < 6; ++i) {
        coefficients->values[i] = lineCoefs[i];  // 获取直线的6个参数
    }

    pcl::ProjectInliers<pcl::PointXYZ> proj;
    proj.setModelType(pcl::SACMODEL_LINE);
    proj.setInputCloud(cloud);
    proj.setModelCoefficients(coefficients);
    proj.filter(*projectedCloud);  // 投影点云到直线上
}

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

#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 <pcl/io/pcd_io.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_line.h>
#include <pcl/filters/project_inliers.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

using namespace std;

// 使用RANSAC拟合直线
void fitLineWithRANSAC(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    Eigen::VectorXf& lineCoefs, std::vector<int>& inliers)
{
    pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr modelLine(
        new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));  // 创建直线模型
    pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(modelLine);  // 创建RANSAC对象
    ransac.setDistanceThreshold(0.01);  // 设置内点距离阈值
    ransac.setMaxIterations(1000);  // 设置最大迭代次数
    ransac.computeModel();  // 执行RANSAC拟合
    ransac.getInliers(inliers);  // 获取内点索引
    ransac.getModelCoefficients(lineCoefs);  // 获取直线模型参数
}

// 投影点云到拟合的直线
void projectPointCloudToLine(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    Eigen::VectorXf& lineCoefs,
    pcl::PointCloud<pcl::PointXYZ>::Ptr projectedCloud)
{
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    coefficients->values.resize(6);
    for (int i = 0; i < 6; ++i) {
        coefficients->values[i] = lineCoefs[i];  // 获取直线的6个参数
    }

    pcl::ProjectInliers<pcl::PointXYZ> proj;
    proj.setModelType(pcl::SACMODEL_LINE);
    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()
{
    // 加载点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile("bunny.pcd", *cloud) < 0)
    {
        PCL_ERROR("点云文件不存在");
        return -1;
    }
    std::cout << "加载点云个数为:" << cloud->points.size() << std::endl;

    // RANSAC直线拟合
    Eigen::VectorXf lineCoefs;
    std::vector<int> inliers;
    fitLineWithRANSAC(cloud, lineCoefs, inliers);

    // 投影到拟合直线
    pcl::PointCloud<pcl::PointXYZ>::Ptr lineProCloud(new pcl::PointCloud<pcl::PointXYZ>);
    projectPointCloudToLine(cloud, lineCoefs, lineProCloud);

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

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

    return 0;
}

三、实现效果

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

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

相关文章

nacos源码修改持久化到postgreSQL数据库

很多业务场景&#xff0c;业务功能必须用pg数据库&#xff0c;这时候注册中心如果用mysql的话&#xff0c;显得浪费资源&#xff0c;基于此&#xff0c;nacos源码修改持久化到postgreSQL数据库是一个必然需求&#xff0c;此处我们修改为只支持pg数据库&#xff0c;2.4版本的源码…

文献阅读Prov-GigaPath模型--相关知识点罗列

文章链接&#xff1a;A whole-slide foundation model for digital pathology from real-world data | NatureDigital pathology poses unique computational challenges, as a standard gigapixel slide may comprise tens of thousands of image tiles1–3. Prior models hav…

联软安全助手卸载 UniAccess Agent,最简单的方法,两步解决!!!

背景&#xff1a; 前段时间因为业务需要安装了这个可恶的安全助手&#xff0c;然后发现卸载不掉&#xff0c;找了网上很多的方法&#xff0c;比如经典的方案一、方案二那个文章&#xff0c;禁用服务根本禁不掉&#xff0c;过两三秒他自己就会把禁用状态改为自动状态&#xff0…

OpenCSG传神社区月度功能更新

9月社区ReleaseNote 在9月的社区更新中&#xff0c;我们继续秉持开放与创新的精神&#xff0c;推出了一系列新功能和技术升级。这些更新不仅扩展了社区的技术支持范围&#xff0c;还为用户提供了更多资源&#xff0c;助力其在人工智能、大数据处理和推理加速等领域的创新。通过…

老男孩mysql系列 1_Mysql 8.0常规安装

1. MySQL安装准备 选择安装的MySQL版本首先判断是否要和公司其他已经安装好的MySQL保持版本一致如果没有上述要求&#xff0c;则一般会安装最新版本&#xff08;目前是5.7&#xff09;如果不是实验新功能性质&#xff0c;则不要选择development release&#xff0c;而要安装Gen…

nuScenes里的目标物体的速度是如何获取的

nuScenes的那些标注文件里并没有标注记录物体的速度数据&#xff0c;而是读取标注数据后根据sample_annotation.json里目标在前后帧里的translation数据相减除以时间差获得x、y、z方向的三个速度分量(Vx,Vy,Vz)的&#xff0c;一版只使用了Vx和Vy&#xff0c;具体实现代码在nusc…

20241007给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Buildroot时使用ADB

20241007给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Buildroot时使用ADB 2024/10/7 17:35 缘起&#xff1a;由于荣品RD-RK3588-AHD开发板使用的是9针的USB-A口&#xff0c;没有使用EVB4默认的type C口。 因此需要拿掉fusb302的驱动/DTS配置部分。 同时&#xff0c;为了简单起见…

腾讯云实时音视频 SDK(TRTC SDK)相关

实时音视频 SDK&#xff08;TRTC SDK&#xff09; 的 RoomID 是什么&#xff1f;取值区间值是多少&#xff1f; RoomID 即房间号&#xff0c;用于唯一标识一个房间。房间号取值区间为1 - 4294967295&#xff0c;由开发者自行维护和分配。 实时音视频 SDK&#xff08;TRTC SDK…

国产工具链GCKontrol-GCAir助力控制律开发快速验证

前言 随着航空领域技术的不断发展&#xff0c;飞机的飞行品质评估和优化成为了航空领域的一个重要任务&#xff0c;为了确保飞行器在各种复杂条件下的稳定性&#xff0c;控制律设计过程中的模型和数据验证需要大量仿真和测试。 本文将探讨基于世冠科技的国产软件工具链GCKont…

Java面试宝典-Java集合01

Java面试宝典-Java集合01 目录 Java面试宝典-Java集合01 1、Java中常用的集合有哪些&#xff1f; 2、Collection 和 Collections 有什么区别&#xff1f; 3、为什么集合类没有实现 Cloneable 和 Serializable 接口&#xff1f; 4、数组和集合有什么本质区别&#xff1f; 5、数组…

flutter 一段长文本实现检索功能,检索的文本加粗标红

先来看效果 做这个功能的原因&#xff0c;因为日志比较长&#xff0c;内容很多&#xff0c;找起来非常不方便 只是简单的加粗标红的话&#xff0c;用TextSpan自己也可以做&#xff0c;主要日志还涉及选择复制&#xff0c;涉及的东西很多&#xff0c;想到了 extended_text&…

基于Python的摄影平台交流系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

美团Java一面

美团Java一面 9.24一面&#xff0c;已经寄了 收到的第一个面试&#xff0c;表现很不好 spring bean生命周期 作用域&#xff08;忘完了&#xff09; 为什么用redis缓存 redis和数据库的缓存一致性问题 redis集群下缓存更新不一致问题 aop说一下 arraylist和linkedlist 数据库的…

H264重点笔记记录

H264格式 目前视频中的H.264流行的NALU包装方式有两种&#xff0c;一种叫做annexB&#xff0c;一种叫做avcC。对于这两种格式&#xff0c;不同的厂商支持程度也不太一样&#xff0c;例如&#xff0c;Android硬解码MediaCodec只接受annexB格式的数据&#xff0c;而Apple的Video…

AI绘画,AI生成图片

分享一个可以免费使用的AI生成图片的网站&#xff1a; https://openart.aihttps://openart.ai/create 1、登陆后点击右上角create 2、在创建页面左侧输入描述文案&#xff0c;下面调整生成图片张数&#xff0c;点击create&#xff0c;右边即可生成 我这里输入了在吃麦当劳的超…

【bug】paddleocr draw_ocr_box_txt ValueError: incorrect coordinate type

【bug】paddleocr draw_ocr_box_txt ValueError: incorrect coordinate type 环境 python 3.10.15pillow 10.4.0 paddleocr 2.8.1错误详情 错误文本 Traceback (most recent call last):....draw_left.polygon(box, fillcolor)ValueError: inco…

社交媒体对人际关系的影响:Facebook的案例分析

随着社交媒体的快速发展&#xff0c;人们的沟通方式和人际关系发生了深刻变化。作为全球最大的社交网络之一&#xff0c;Facebook在这一进程中扮演了重要角色。本文将分析Facebook如何影响人际关系&#xff0c;包括沟通方式的转变、情感连接的变化以及社交互动的质量。 1. 沟通…

echarts的option,设置折线图鼠标悬浮显示数据

在series平级位置加代码 效果看起来还不错

深度学习:词嵌入embedding和Word2Vec模型

目录 前言 一、词嵌入&#xff08;Embedding&#xff09; 1.传统自然语言处理问题 2.什么是词嵌入 3.主要特点 二、Word2vec模型 1.连续词袋模型&#xff08;CBOW&#xff09; 2.跳字模型&#xff08;Skip-gram&#xff09; 三、CBOW模型训练过程 前言 在机器学习里的…

包材推荐中的算法应用|得物技术

目录 一、业务背景 二、算法架构 规则算法 三、算法原理 装箱装袋 四、衍生应用 切箱合包箱型设计包装方案推荐 五、作者结语 一、业务背景 任何一家电商的商品出库场景中&#xff0c;都涉及到打包——即把订单中的商品用包材进行包裹&#xff0c;常见的打包方式有装袋和装箱。…