基于ICP的点云融合拼接

3 篇文章 0 订阅

基于ICP的点云融合拼接

实际应用中基于单个雷达扫描的局限性(遮挡,特征信息不全问题),我们需要将不同坐标系下的点云进行拼接融合,以最大程度上还原真实场景

一、ICP

​ ICP即迭代最近点算法,通过不断调整,把不同角度的3D点数据整合到一个完整的模型中。它的目的在于在一个全局坐标系下找到不同视角的定位与定向,两个视角交叉部分重叠完好为最优,给定输入数据集,首先做一个估计,然后通过旋转和平移变换一个数据集,找到一个正确的点集对应方式完美匹配

二、PCD文件读取与可视化

数据集源自于通过RSview保存的两个不同坐标系下的Pcap文件,通过RSlidar雷达驱动编译运行转化为了Pcd文件,其可视化如下图

在这里插入图片描述
​ 测顶雷达
在这里插入图片描述
​ 测边雷达

三、滤除异常点

数据显示如下

在这里插入图片描述
由上图可知,PCD点云数据中存在nan异常点,对于融合拼接效果有影响,因此我们需要去除异常点,执行以下操作

#include <pcl/filters/filter.h>//过滤头文件
std::vector<int> index;
pcl::removeNaNFromPointCloud(*cloud_in, *cloud_out, index);//过滤后的新点云储存在cloud_out

在这里插入图片描述
由上图可知,异常点过滤成功!!!

四、点云拼接融合

#include <string>
#include <vector>
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/filter.h>
#include <pcl/registration/icp.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
using namespace std;
using namespace pcl;
typedef pcl::PointXYZ PointType;
  //创建了一个名为cloud的指针,储存XYZ类型的点云数据
   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
   PointType pointSel;
class PcdRead {
public:
    void readPcdFile(const std::string filePath);
};
void PcdRead::readPcdFile(const string filePath) {
   
    /*打开点云文件*/
    if (io::loadPCDFile<PointXYZ>(filePath, *cloud) == -1) {
        PCL_ERROR("Couldn't read file xxx.pcd\n");
      
    }
}
void point1To2(PointType const * const p1, PointType * const p2)
{
  p2->x = p1->x * 0.394694 + p1->y * 0.909508 + p1->z * 0.130444;
  p2->y = p1->x * -0.916368 + p1->y * 0.379305 + p1->z * 0.128056;
  p2->z = p1->x * 0.06699 + p1->y * -0.170077 + p1->z * 0.983152;
}
int main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZ>);
  std::vector<int> index;
  // Fill in the CloudIn data
  PcdRead read;
  read.readPcdFile("/home/ubuntu/pcl_test/B1.pcd");
  pcl::removeNaNFromPointCloud(*cloud, *cloud, index);
  *cloud_in = *cloud;
  std::cout << "Saved " << cloud_in->size () << " data points from B1.pcd:" << std::endl;
  read.readPcdFile("/home/ubuntu/pcl_test/H1.pcd");
  pcl::removeNaNFromPointCloud(*cloud, *cloud, index);
  *cloud_out = *cloud;
  std::cout << "Saved " << cloud_in->size () << " data points from H1.pcd:" << std::endl;

  pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
  icp.setInputSource(cloud_in);
  icp.setInputTarget(cloud_out);
  
  pcl::PointCloud<pcl::PointXYZ> Final;
  icp.align(Final);

  std::cout << "has converged:" << icp.hasConverged() << " score: " <<
  icp.getFitnessScore() << std::endl;
  std::cout << icp.getFinalTransformation() << std::endl;
  for (int i = 0; i <  cloud_in->points.size(); i++) {
      point1To2(&cloud_in->points[i], &pointSel);  //雷达1数据转换到雷达2坐标系中
	    cloud_out -> push_back(pointSel);
    }
  std::cout << "雷达1数据转换到雷达2坐标系中" << std::endl;
   /*点云pcd文件可视化*/
    visualization::PCLVisualizer::Ptr viewer (new visualization::PCLVisualizer ("3D Viewer"));
    viewer->addPointCloud (cloud_out, "rabbit-cloud");
    viewer->spin();
 return (0);
}

结果如下图:

在这里插入图片描述
拼接融合效果良好!!!

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
点云拼接是将多个点云数据集合并成一个整体的过程。而RANSAC(随机抽样一致性算法)是一种经典的模型估计方法,可以用于点云拼接。下面我用300字详细解释一下点云拼接RANSAC的原理和步骤。 首先,点云拼接RANSAC的目标是找到多个点云之间的共同几何关系。这个几何关系通常是由旋转、平移和缩放等变换描述的。 RANSAC算法的步骤如下: 1. 随机从点云中选择一个点作为起始点,并将其作为一个模型的一部分; 2. 从剩余的点云中随机选择一些点,构成一个能够满足当前模型的假设集合; 3. 使用这个假设集合来估计一个模型,通常使用最小二乘法等方法; 4. 计算当前模型对于所有点的拟合误差; 5. 如果误差小于设定的阈值,将这个模型认为是一个好模型; 6. 重复2-5的步骤若干次,选择拟合误差最小的模型; 7. 使用所有被认为是好模型的点云对应的变换,将点云进行拼接。 在点云拼接中,RANSAC算法的关键是通过选择随机的点来构建一组假设集合。然后使用这个假设集合来估计一个模型,并计算拟合误差。根据误差的大小,可以判断该模型是否是一个好模型。通过多次重复这个过程,并选择拟合误差最小的模型,就可以得到最好的点云拼接结果。 总结来说,点云拼接RANSAC是一种通过随机抽样和拟合误差计算来估计点云之间共同几何关系的方法。它可以有效地将多个点云数据拼接成一个整体,用于实现点云拼接和重建等应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值