Ubuntu 20.04.06 PCL C++学习记录(二十六)

@[TOC]PCL中点云配准模块的学习

学习背景

参考书籍:《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,,PCL版本为1.10.0,CMake版本为3.16,可用点云下载地址

学习内容

在代码中使用ICP迭代最近点算法,程序随机生成一个点与作为源点云,并将其沿x轴平移后作为目标点云,然后利用ICP估计源到目标的刚体变换橘子,中间对所有信息都打印出来。在 ICP 配准过程中,算法会迭代地寻找源点云和目标点云之间的最佳变换矩阵,使得两个点云之间的距离最小化。

源代码及所用函数

源代码

//迭代最近点算法
#include<iostream>//标准输入输出头文件
#include<pcl/io/pcd_io.h>//PCD输入输出头文件
#include<pcl/point_types.h>//点类型定义头文件
#include<pcl/registration/icp.h>//ICP(迭代最近点)配准算法头文件。
int main()
{
    //**********************************************初始化点云并填充打印***************************************//
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>(5,1));
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZ>);
    //*******************填充点云第一种写法**************************//
    // // 随机填充点云
    // cloud_in->width    = 5;               //设置点云宽度
    // cloud_in->height   = 1;               //设置点云为无序点
    // cloud_in->is_dense = false;
    // cloud_in->points.resize (cloud_in->width * cloud_in->height);
    // for (size_t i = 0; i < cloud_in->points.size(); i++)
    // {
    //     cloud_in->points[i].x = 1024.0f*rand()/(RAND_MAX +1.0f);
    //     cloud_in->points[i].y = 1024.0f*rand()/(RAND_MAX +1.0f);
    //     cloud_in->points[i].z = 1024.0f*rand()/(RAND_MAX +1.0f);
    // }
    //*********************填充点云第二种方法**********************//
    for (auto& point : *cloud_in)
    {
        point.x = 1024 * rand() / (RAND_MAX + 1.0f);
        point.y = 1024 * rand() / (RAND_MAX + 1.0f);
        point.z = 1024 * rand() / (RAND_MAX + 1.0f);
    }
    //打印点云
    std::cout << "已保存:" << cloud_in->points.size () << "个点,其坐标为:" << std::endl;
    //*******************打印点云第一种方法************************//
    // for (size_t i = 0; i < cloud_in->points.size (); ++i)
    // {
    //     std::cout << "    " << cloud_in->points[i].x << " " << cloud_in->points[i].y << " " << cloud_in->points[i].z << std::endl;
    // }
    //******************打印点云的第二种方法***********************//
    for (auto& point : *cloud_in)
    {
        std::cout << point << std::endl;    
    }
    
    //****************************************实现一个简单的点云刚体变换,以构造目标点云******************************//
    *cloud_out = *cloud_in; 
    std::cout << "点云大小:" << cloud_out->size() << std::endl;
    for (auto& point : *cloud_out)
    {
        point.x += 0.7f;
    }
    std::cout << "转移了 " << cloud_in->size () << "个点" << std::endl;
    for(auto& point : *cloud_out)
    {
        std::cout << point << std::endl;
    }
    pcl::IterativeClosestPoint<pcl::PointXYZ,pcl::PointXYZ> icp;//创建IterativeClosestPoint的对象
    icp.setInputSource(cloud_in); //cloud_in设置为点云的源点
    icp.setInputTarget(cloud_out);//cloud_out设置为与cloud_in对应的匹配目标
    pcl::PointCloud<pcl::PointXYZ> Final;//存储经过配准变换点云后的点云
    icp.align(Final);//打印配准相关输入信息
    std::cout << "已收敛" << icp.hasConverged() << "总共" << icp.getFitnessScore() << std::endl;
    std::cout << icp.getFinalTransformation() << std::endl;

    return 0;

}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16 FATAL_ERROR)#指定CMake的最低版本要求为3.16
project(project)#设置项目名称
find_package(PCL 1.10 REQUIRED)#查找PCL库,要求版本为1.10或更高。
include_directories(${PCL_INCLUDE_DIRS})#将PCL库的头文件目录添加到包含路径中
link_directories(${PCL_LIBRARY_DIRS})#将PCL库的库文件目录添加到链接器搜索路径中。
add_definitions(${PCL_DEFINITIONS})#添加PCL库的编译器定义
add_executable (iterative_closest_point iterative_closest_point.cpp)
target_link_libraries (iterative_closest_point ${PCL_LIBRARIES})#将PCL库链接到可执行文件目标。

运行结果

在这里插入图片描述红色是随机生成点云,绿色是ICP配准后的点云
在这里插入图片描述

函数

  • icp.hasConverged() 是 PCL 库中 IterativeClosestPoint 类的一个成员函数,用于检查 ICP 配准算法是否收敛。hasConverged() 函数返回一个布尔值,表示 ICP 算法是否达到了收敛条件。当 ICP 算法满足收敛条件时,hasConverged() 函数将返回 true,表示配准过程已经完成,得到了最佳的变换矩阵。

  • icp.getFitnessScore()是ICP(迭代最近点)算法中的一个函数,用于计算当前变换矩阵的适应度得分(Fitness Score)用来评估当前变换矩阵的性能。具体来说,getFitnessScore()通常会计算以下指标:
    对应点之间的欧氏距离之和或均值。距离越小,说明对齐效果越好。
    内点(Inlier)的数量或比例。内点指的是在一定误差范围内匹配的点对。内点越多,说明对齐效果越好。
    误差的标准差。误差越集中,说明对齐更加一致。

    关于返回值的大小通常有两种常见的情况:
    得分越小越好:如果getFitnessScore()返回的是误差或距离的度量,如对应点之间的欧氏距离之和或均值,则得分越小表示对齐效果越好。在这种情况下,ICP算法的目标是最小化getFitnessScore()的返回值。
    得分越大越好:如果getFitnessScore()返回的是内点的数量、比例或其他表示对齐质量的指标,则得分越大表示对齐效果越好。在这种情况下,ICP算法的目标是最大化getFitnessScore()的返回值。
    在大多数实现中,这个分数通常是平均平方误差,所以较低的分数意味着两个点云之间的对应点的距离较近,表明配准的质量较高。

补充内容

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值