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

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

相关文章:

  • Tbox编译注意问题
  • java基于SpringBoot+Vue+uniapp微信小程序的自助点餐系统的详细设计和实现(源码+lw+部署文档+讲解等)
  • 基于Springboot+Vue的宠物援助平台(含源码+数据库)
  • 【编程语言】Kotlin快速入门 - 集合与Lambda
  • 删除 Word 空白页的 3 种方法总结
  • 中标麒麟v5安装qt512.12开发软件
  • Python进阶知识2
  • 2024第七届全国大学生数学竞赛暨数学精英挑战赛第二场,第一场获奖名单已公布
  • 重生之我爱上了k8s!
  • 【论文分享】ShEF: Shielded Enclaves for Cloud FPGAs 22‘ASPLOS
  • [Windows]文件搜索利器Everything(附zip)
  • 《探索 Python 音频利器:sounddevice》
  • 大数据治理:确保数据质量与合规性的战略
  • 【SpringCloud】02-Nacos注册中心
  • 【Flutter】Dart:类
  • 2024金九银十版Java基础、中级、高级面试题总结(1000道题含答案解析)
  • ChatGPT撰写开题报告教程——研究目标、内容及方案
  • Java 异步编程——常用线程池 ThreadPoolExecutor
  • 消息展示区(一)
  • Spring Boot知识管理系统:数据驱动的决策