PCL点云库:ICP算法

 ICP(Iterative Closest Point迭代最近点)算法是一种点集对点集配准方法。在VTK、PCL、MRPT、MeshLab等C++库或软件中都有实现,可以参见维基百科中的ICP Algorithm Implementations.

  ICP算法采用最小二乘估计计算变换矩阵,原理简单且具有较好的精度,但是由于采用了迭代计算,导致算法计算速度较慢,而且采用ICP进行配准计算时,其对待配准点云的初始位置有一定要求,若所选初始位置不合理,则会导致算法陷入局部最优。PCL点云库已经实现了多种点云配准算法:

  IterativeClosestPoint类提供了标准ICP算法的实现(The transformation is estimated based on SVD),算法迭代结束条件有如下几个:

  1. 最大迭代次数:Number of iterations has reached the maximum user imposed number of iterations (via setMaximumIterations)
  2. 两次变化矩阵之间的差值:The epsilon (difference) between the previous transformation and the current estimated transformation is smaller than an user imposed value (via setTransformationEpsilon)
  3. 均方误差(MSE):The sum of Euclidean squared errors is smaller than a user defined threshold (via setEuclideanFitnessEpsilon)

  基本用法如下:

复制代码
IterativeClosestPoint<PointXYZ, PointXYZ> icp;
// Set the input source and target icp.setInputCloud (cloud_source); icp.setInputTarget (cloud_target);
// Set the max correspondence distance to 5cm (e.g., correspondences with higher distances will be ignored) icp.setMaxCorrespondenceDistance (0.05); // Set the maximum number of iterations (criterion 1) icp.setMaximumIterations (50); // Set the transformation epsilon (criterion 2) icp.setTransformationEpsilon (1e-8); // Set the euclidean distance difference epsilon (criterion 3) icp.setEuclideanFitnessEpsilon (1);
// Perform the alignment icp.align (cloud_source_registered); // Obtain the transformation that aligned cloud_source to cloud_source_registered Eigen::Matrix4f transformation = icp.getFinalTransformation ();
复制代码

  下面是一个完整的例子:

复制代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/registration/icp.h>

int main (int argc, char** argv)
{
    //Creates two pcl::PointCloud<pcl::PointXYZ> boost shared pointers and initializes them
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZ>);

    // Fill in the CloudIn data
    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 * rand () / (RAND_MAX + 1.0f);
        cloud_in->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
        cloud_in->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
    }


    *cloud_out = *cloud_in;

    //performs a simple rigid transform on the point cloud
    for (size_t i = 0; i < cloud_in->points.size (); ++i)
        cloud_out->points[i].x = cloud_in->points[i].x + 1.5f;

    //creates an instance of an IterativeClosestPoint and gives it some useful information
    pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
    icp.setInputCloud(cloud_in);
    icp.setInputTarget(cloud_out);

    //Creates a pcl::PointCloud<pcl::PointXYZ> to which the IterativeClosestPoint can save the resultant cloud after applying the algorithm
    pcl::PointCloud<pcl::PointXYZ> Final;

    //Call the registration algorithm which estimates the transformation and returns the transformed source (input) as output.
    icp.align(Final);

    //Return the state of convergence after the last align run. 
    //If the two PointClouds align correctly then icp.hasConverged() = 1 (true). 
    std::cout << "has converged: " << icp.hasConverged() <<std::endl;

    //Obtain the Euclidean fitness score (e.g., sum of squared distances from the source to the target) 
    std::cout << "score: " <<icp.getFitnessScore() << std::endl; 
    std::cout << "----------------------------------------------------------"<< std::endl;

    //Get the final transformation matrix estimated by the registration method. 
    std::cout << icp.getFinalTransformation() << std::endl;

    return (0);
}
复制代码

  结果如下,ICP算法计算出了正确的变换

  在PCL官方的tutorial中还有个ICP算法交互的例子(Interactive Iterative Closest Point,网站上该例子的源代码编译时有一点问题需要修改...),该程序中按一次空格ICP迭代计算一次。可以看出,随着迭代进行,两块点云逐渐重合在一起。

 

 

参考:

How to use iterative closest point

http://pointclouds.org/documentation/tutorials/iterative_closest_point.php#iterative-closest-point

Interactive Iterative Closest Point

http://pointclouds.org/documentation/tutorials/interactive_icp.php#interactive-icp

PCL之ICP算法实现

https://segmentfault.com/a/1190000005930422


转载:http://www.cnblogs.com/21207-iHome/p/6034462.html

### 回答1: PCL(Point Cloud Library)是一个开源的点云处理,主要面向点云地形建模、三维物体识别、目标检测、点云分割等方面。其提供了一系列函数和算法,包括点云输入输出、点云几何变换、点云滤波、点云配准、点云分割、点云曲率估计、点云特征描述、立面图提取、寻找平面模型等。 PCL的数据结构主要是点云(PointCloud)、点云索引(PointCloudIndex)、多通道点云(MultiChannelPointCloud)等。这些数据结构都是基于元素类型定义的向量类,可以用来存储各种各样的点云,比如RGB-D点云、三维点云、体素网格等。 PCL中的一些算法有较高的实用性。比如,ICP算法(Iterative Closest Point)可以用于配准点云,以进行物体重建或地形建模。提取法线特征,可以用于点云特征描述、点云分割、点云分类等。提取独立的物体,可以利用聚类算法,以进行目标检测、散点噪音滤波等。 总的来说,PCL是一个高效、可扩展的点云处理,其强大的算法和丰富的数据结构,使它成为目前最重要的点云处理之一。 ### 回答2: PCL(Point Cloud Library)是一种开源的、跨平台的点云处理。它提供了各种点云处理算法,包括点云滤波、特征提取、配准、分割、分类等。PCL支持多种格式的点云数据输入和输出,可以处理多种类型的传感器产生的点云数据。 PCL使用C++语言编写,具有高效、灵活、可扩展的特点,可以自由地进行二次开发和定制,同时具有良好的兼容性。PCL的主要目标是成为点云处理领域的标准开发,可以满足从学术研究到工业应用的不同需求。 值得注意的是,PCL对于初学者来说并不是很友好,存在一定的学习门槛。但是,一旦掌握了PCL的使用方法,就能够快速、高效地完成各种点云处理任务,从而大大提高处理效率和精度。 总之,PCL是一个功能丰富、强大的点云处理,在点云的相关研究和应用中具有广泛的应用前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值