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

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.lryc.cn/news/462406.html

相关文章:

  • 12、论文阅读:利用生成对抗网络实现无监督深度图像增强
  • Axure重要元件三——中继器表单制作
  • DMAIC赋能智能家居:解锁未来生活新篇章!
  • 代码随想录算法训练营第二天| 209.长度最小的子数组 59.螺旋矩阵II 区间和 开发商购买土地
  • mysql隐藏索引
  • etcd入门到实战
  • Build an Android project and get a `.apk` file on a Debian 11 command line
  • 解读 Java 经典巨著《Effective Java》90条编程法则,第4条:通过私有构造器强化不可实例化的能力
  • Vivado HLS学习
  • 一款AutoXJS现代化美观的日志模块AxpLogger
  • 成都睿明智科技有限公司共创抖音电商新篇章
  • Spark的安装配置及集群搭建
  • 网络编程基础-IO模型深入理解
  • go 语言学习路线图(一)
  • 前端自动化部署,Netlify免费满足你
  • Linux的开发工具gcc Makefile gdb的学习
  • 基于SSM出租车管理系统的设计
  • iPhone照片内存怎么清理,参考这些方法
  • 【Triton教程】向量相加
  • 关于CSS中毛玻璃和滤镜使用总结
  • 陷入产出危机的我聊聊近况
  • HarmonyOS 开发知识总结
  • [WPF初学到大神] 1. 什么是WPF, MVVM框架, XAML?
  • matlab怎样自动搜索文件夹中的所有txt文件,并将每个txt文件中的数据存放到一个cell数组中——MATLAB批量处理数据
  • LabVIEW智能可变温循环PCT测试系统
  • SparkSQL整合Hive
  • Vue 3 和 Vue 2区别
  • React.memo和useMemo
  • Android中实现网络请求的方式有哪些?
  • 安卓13usb触摸唤醒系统 android13触摸唤醒