PCL 点云配准-4PCS算法(粗配准)

目录

一、概述

1.1原理

1.2实现步骤

1.3应用场景

二、代码实现

2.1关键函数

2.1.1 加载点云数据

2.1.2 执行4PCS粗配准

2.1.3 可视化源点云、目标点云和配准结果

2.2完整代码

三、实现效果

3.1原始点云

3.2配准后点云


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

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


一、概述

        4PCS(四点一致集)算法是一种用于点云配准的粗配准方法。该算法通过寻找目标点云和源点云之间具有几何约束的四点集合进行匹配,继而估计出变换矩阵。4PCS 算法具有较好的抗噪性和计算效率,适用于较大尺度的点云配准场景。

1.1原理

4PCS 算法通过以下步骤进行粗配准:

  1. 点云采样:从源点云和目标点云中采样若干点,形成四点集合。
  2. 几何一致性验证:计算这四个点在两个点云中的相对距离,通过几何一致性约束找到符合要求的四点集合。
  3. 估计变换矩阵:使用一致的四点集合,计算源点云到目标点云的变换矩阵。
  4. 应用变换矩阵:将计算得到的变换矩阵应用到源点云上,使其与目标点云对齐。

配准结果的质量依赖于:

  • 重叠率:设置源点云和目标点云的近似重叠率。
  • 采样点数量:设置参与匹配的采样点数量。
  • 精度参数 Delta:控制配准的精度,通过对配准点云的稀疏化进行加速。

1.2实现步骤

  1. 加载源点云和目标点云。
  2. 设置4PCS配准参数:包括近似重叠率、采样点数量、精度参数等。
  3. 执行4PCS粗配准:通过设置参数执行粗配准,得到变换矩阵。
  4. 应用变换矩阵:将源点云应用变换矩阵对齐至目标点云。
  5. 可视化结果:将源点云、目标点云以及对齐后的点云进行可视化对比。

1.3应用场景

  1. 粗配准阶段:4PCS 可以用于点云配准的初步阶段,提供较为快速的粗略对齐结果,后续可以使用更精细的算法(如ICP)进行精配准。
  2. 多场景拼接:在多视角点云场景下,4PCS 可以帮助快速匹配不同视角的点云数据。
  3. 点云地图生成:在SLAM(同步定位与地图构建)中,4PCS 可以用于不同帧之间的点云匹配与对齐。

二、代码实现

2.1关键函数

2.1.1 加载点云数据

void loadPointClouds(pcl::PointCloud<pcl::PointXYZ>::Ptr& source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& target_cloud)
{if (pcl::io::loadPCDFile<pcl::PointXYZ>("hand_trans.pcd", *target_cloud) == -1) {PCL_ERROR("读取目标点云失败 \n");}if (pcl::io::loadPCDFile<pcl::PointXYZ>("hand.pcd", *source_cloud) == -1) {PCL_ERROR("读取源点云失败 \n");}
}

2.1.2 执行4PCS粗配准

void perform4PCSRegistration(pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr aligned_cloud, Eigen::Matrix4f& transformation_matrix)
{pcl::registration::FPCSInitialAlignment<pcl::PointXYZ, pcl::PointXYZ> fpcs;fpcs.setInputSource(source_cloud);fpcs.setInputTarget(target_cloud);fpcs.setApproxOverlap(0.7);         // 设置近似重叠率fpcs.setDelta(0.01);                // 精度参数fpcs.setNumberOfSamples(100);       // 采样点数量fpcs.align(*aligned_cloud);         // 执行配准transformation_matrix = fpcs.getFinalTransformation(); // 获取变换矩阵
}

2.1.3 可视化源点云、目标点云和配准结果

// 可视化源点云、目标点云和配准结果
void visualizePointClouds(pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud)
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Point Cloud Registration Viewer"));viewer->setBackgroundColor(1.0, 1.0, 1.0);  // 设置背景颜色为黑色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> target_color(target_cloud, 255, 0, 0);viewer->addPointCloud(target_cloud, target_color, "target cloud"); // 目标点云(红色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_color(source_cloud, 0, 0, 255);viewer->addPointCloud(source_cloud, source_color, "source cloud"); // 源点云(蓝色)viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "target cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "source cloud");while (!viewer->wasStopped()) {viewer->spinOnce();}
}

2.2完整代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/registration/ia_fpcs.h>
#include <pcl/console/time.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>// 加载点云数据
void loadPointClouds(pcl::PointCloud<pcl::PointXYZ>::Ptr& source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& target_cloud)
{if (pcl::io::loadPCDFile<pcl::PointXYZ>("hand_trans.pcd", *target_cloud) == -1) {PCL_ERROR("读取目标点云失败 \n");}if (pcl::io::loadPCDFile<pcl::PointXYZ>("hand.pcd", *source_cloud) == -1) {PCL_ERROR("读取源点云失败 \n");}
}// 执行4PCS粗配准
void perform4PCSRegistration(pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr aligned_cloud, Eigen::Matrix4f& transformation_matrix)
{pcl::registration::FPCSInitialAlignment<pcl::PointXYZ, pcl::PointXYZ> fpcs;fpcs.setInputSource(source_cloud);fpcs.setInputTarget(target_cloud);fpcs.setApproxOverlap(0.7);         // 设置近似重叠率fpcs.setDelta(0.01);                // 精度参数fpcs.setNumberOfSamples(1000);       // 采样点数量fpcs.align(*aligned_cloud);         // 执行配准transformation_matrix = fpcs.getFinalTransformation(); // 获取变换矩阵
}// 可视化源点云、目标点云和配准结果
// 可视化源点云、目标点云和配准结果
void visualizePointClouds(pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud)
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Point Cloud Registration Viewer"));viewer->setBackgroundColor(1.0, 1.0, 1.0);  // 设置背景颜色为黑色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> target_color(target_cloud, 255, 0, 0);viewer->addPointCloud(target_cloud, target_color, "target cloud"); // 目标点云(红色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_color(source_cloud, 0, 0, 255);viewer->addPointCloud(source_cloud, source_color, "source cloud"); // 源点云(蓝色)viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "target cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "source cloud");while (!viewer->wasStopped()) {viewer->spinOnce();}
}int main(int argc, char** argv)
{pcl::console::TicToc time;pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud(new pcl::PointCloud<pcl::PointXYZ>);loadPointClouds(source_cloud, target_cloud);pcl::PointCloud<pcl::PointXYZ>::Ptr aligned_cloud(new pcl::PointCloud<pcl::PointXYZ>);Eigen::Matrix4f transformation_matrix;time.tic();perform4PCSRegistration(source_cloud, target_cloud, aligned_cloud, transformation_matrix);cout << "FPCS配准用时: " << time.toc() << " ms" << endl;cout << "变换矩阵:" << transformation_matrix << endl;//显示原始点云visualizePointClouds(source_cloud, target_cloud);//显示配准后点云visualizePointClouds(target_cloud, aligned_cloud);return 0;
}

三、实现效果

3.1原始点云

3.2配准后点云

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

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

相关文章

猫分鱼干 -算法题解

题目 假如有一群猫排成一行&#xff0c;要分配鱼干&#xff0c;每一只猫都有一个等级值。你作为管理员有很多鱼干但是需要按下边的分配制度分配&#xff1a; 1. 每一只猫至少要分配一斤鱼干&#xff0c;鱼干分配最小单位是斤&#xff0c;必须保证是整数。 2. 猫比他们邻居有更高…

沥川的算法学习笔记:基础算法(1)----快速排序

1.快速排序 快速排序是一种高效的排序算法&#xff0c;它利用了分治的思想。快速排序的基本思想是选择一个基准元素&#xff0c;将数组分成两个子数组&#xff0c;其中一个子数组的元素都小于等于基准元素&#xff0c;另一个子数组的元素都大于等于基准元素&#xff0c;然后对这…

Javaweb开发快捷键集锦(Spring boot)

1.动态SQL于xml文件格式化快捷键 Visual Studio: Windows: Ctrl K, Ctrl D IntelliJ IDEA 或 Android Studio: Windows/Linux: Ctrl Alt LmacOS: Command Option L 2.在 IntelliJ IDEA 中&#xff0c;为Java文件添加多行注释的快捷键 Windows/Linux: Ctrl Shift …

JavaCove部署文档

1. 基础配置 1.1服务器&#xff1a; 2 核 2G 1.2. 一个域名 1.3. 项目地址&#xff1a; gitee:https://gitee.com/guo-_jun/JavaCove github:https://github.com/nansheng1212/JavaCove 2. CentOS 安装 Docker 官方网站上有各种环境下的 安装指南&#xff0c;这里主要介绍…

IPD体系中如何构筑E2E的产品成本竞争力

在IPD咨询项目实施过程中&#xff0c;汉捷咨询发现很多企业在新产品开发过程中忽略了对产品的目标成本管控&#xff0c;出现产品开发出来后成本过高&#xff0c;产品竞争力不足&#xff0c;上市后销售不佳等情况。 产品的成本是市场竞争的关键制胜因素之一&#xff0c;也是产品…

jquery实现点击菜单实现高德地图定位点与数据展示联动效果

&#x1f34a;jquery实现点击菜单实现高德地图定位点与数据展示联动效果 版本介绍&#xff1a; jQuery v3.7.1高德地图JS API 2.0 代码仓库 ⭐ Gitee&#xff1a;实现点击菜单实现高德地图定位点与数据展示联动效果 1.启动说明 &#x1f4d4; 推荐VS Code编辑器插件Live Ser…

论文笔记:RelationPrompt :Zero-Shot Relation Triplet Extraction

论文来源: ACL Findings 2022 论文链接:https://arxiv.org/pdf/2203.09101.pdf 论文代码:http://github.com/declare-lab/RelationPrompt 本篇论文是由阿里达摩院自然语言智能实验室于2022年发表的关于零样本关系抽取的顶会论文,本篇博客将记录我在阅读过程中的一些笔记…

ros2 bag 详解

一&#xff0e;命令行详解 ros2 bag 是一个命令行工具&#xff0c;用于记录系统中发布的主题数据。它积累传递给任意数量主题的数据&#xff0c;并将其保存在数据库中。然后可以重放数据以再现测试和实验的结果。记录主题也是分享你的工作并让别人重新创造它的好方法。 &…

pyflink过滤kafka数据

from pyflink.table import (TableEnvironment, EnvironmentSettings)# 输入、输出、过滤条件 columns_in [ ... ]columns_out [ ... ] filter_condition "name 蒋介石 and sex 男"# 创建执行环境t_env TableEnvironment.create(EnvironmentSettings.in_stream…

jmeter中对于有中文内容的csv文件怎么保存

jmeter的功能很强大&#xff0c;但是细节处没把握好就得不到预期的结果。今天来讲讲有中文内容的csv文件的参数化使用中需要注意的事项。 对于有中文内容&#xff0c;涉及到编码格式&#xff0c;为了让jmeter能正确地读取csv文件中的中文&#xff0c;需要把文件转码为UTF-8BOM…

EFFPLMN(Forbidden PLMNs)

EFFPLMN&#xff08;Forbidden PLMNs&#xff09;文件包含了被禁止的公共陆地移动网络&#xff08;PLMN&#xff09;的编码。当网络拒绝位置更新请求&#xff0c;并给出“PLMN不允许”的原因时&#xff0c;这些PLMN会被写入到这个文件中。移动设备&#xff08;UE&#xff09;在…

OPENSSL-2023/11/10学习记录-C/C++对称分组加密DES

对称分组加密常用算法&#xff1a; DES 3DES AES 国密SM4 对称分组加密应用场景&#xff1a; 文件或者视频加密 加密比特币私钥 消息或者配置项加密 SSL通信加密 对称分组加密 使用异或实现一个简易的对称加密算法 A明文 B秘钥 AB密文AB (AB)B A 密码补全和初始化 数…

学习第三十六行

QValidator::State里面state为0&#xff0c;完全不匹配&#xff0c;1&#xff0c;部分匹配&#xff0c;2&#xff0c;完全匹配,对于label或者textedit里面的字符均为QString类型&#xff0c;特别是遇到数字&#xff0c;需要QString::number转化&#xff0c;对于正则表达式&…

数据操作学习

1.导入torch。虽然被称为PyTorch&#xff0c;但应导入torch而不是pytorch import torch 2.张量表示一个数值组成的数组&#xff0c;这个数组可能有多个维度 xtorch.arange(12)x 3.通过张量的shape属性来访问张量的形状和张量中元素的总数 x.shape x.numel() 4.要改变张量的形…

LangGraph - Hierarchical Agent Teams

本文翻译整理自 Hierarchical Agent Teams https://langchain-ai.github.io/langgraph/tutorials/multi_agent/hierarchical_agent_teams/ 文章目录 一、前言二、设置三、创建工具四、Helper Utilities五、定义代理 Team研究 Team文档写作Team 六、添加图层 一、前言 在前面的…

存在重复元素 II

题目 给定一个整数数组和一个整数 k&#xff0c;判断数组中是否存在两个不同的索引 i 和 j&#xff0c;使得 nums [i] nums [j]&#xff0c;并且 i 和 j 的差的 绝对值 至多为 k。 示例 1: 输入: nums [1,2,3,1], k 3 输出: true示例 2: 输入: nums [1,0,1,1], k 1 输…

【高阶数据结构】揭开红黑树‘恶魔’的面具:深度解析底层逻辑

高阶数据结构相关知识点可以通过点击以下链接进行学习一起加油&#xff01;二叉搜索树AVL树 大家好&#xff0c;我是店小二&#xff0c;欢迎来到本篇内容&#xff01;今天我们将一起探索红黑树的工作原理及部分功能实现。红黑树的概念相对抽象&#xff0c;但只要我们一步步深入…

自定义注解和组件扫描在Spring Boot中动态注册Bean(二)

在Spring Boot中&#xff0c;自定义注解和组件扫描是实现动态注册Bean的两种重要手段。通过它们&#xff0c;开发者可以灵活地管理Spring容器中的Bean&#xff0c;提高开发效率和代码的可维护性。本文将详细讲解自定义注解和组件扫描在Spring Boot中如何动态注册Bean。 自定义…

html嵌入vue如何使用?

html嵌入vue如何使用&#xff1f; <script src"https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script> <script src"https://cdn.bootcdn.net/ajax/libs/vuex/3.6.2/vuex.min.js"></script> <script src&q…

Java使用HttpClient5实现发送HTTP请求

1、HttpClient5 的介绍 HttpClient5 是 Apache HttpComponents 项目中的一个重要组件&#xff0c;它是一个功能齐全且高度可定制的 HTTP 客户端库&#xff0c;专门用于发送 HTTP 请求、处理 HTTP 响应并支持各种 HTTP 协议特性。 以下是对 HttpClient5 的详细介绍&#xff1a…