Point Cloud Library学习之ICP迭代最近点匹配法NDT2D正态分布转换法

2023-10-26

参考来源:

https://pointclouds.org/documentation/classpcl_1_1_registration.html#ab1d64f86162b2df716ead8d978579c11

http://epsilonjohn.club/2020/02/29/Autoware.ai/2D-NDT-%E5%8C%B9%E9%85%8D%E7%AE%97%E6%B3%95/

https://pcl.readthedocs.io/projects/tutorials/en/pcl-1.11.0/iterative_closest_point.html#iterative-closest-point

NDT进行匹配时耗时较多,且角度误差较大;

NDT参数不明确:对于我的情况GridStep一般设置0.6以上,默认1,GridExtent设置2或以上,默认值为20;

pcl::PointCloud<PointXYZ>::makeShared()函数可以得到已知点云的指针

tictoc()函数可以得到运行时间;

icp.hasConverged()可以得到是否收敛;

注意匹配时的source和Target区分;

其中具体参数需要调整

  
#include <pcl/registration/icp.h>
#include <pcl/registration/ndt_2d.h>
#include <pcl/console/time.h>
#include <pcl/registration/sample_consensus_prerejective.h>
#include <pcl/features/brisk_2d.h>
typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
typedef pcl::BRISKSignature512 FeatureT;
typedef pcl::BRISK2DEstimation<pcl::PointXYZ> FeatureEstimationT;
typedef pcl::PointCloud<FeatureT> FeatureCloudT;
typedef pcl::PointWithScale KeyPointT; 
typedef pcl::PointCloud<KeyPointT> KeyPointCloudT;
pcl::console::TicToc tt;
tt.tic ();

  //  // Initializing Normal Distributions Transform (NDT).
  // pcl::NormalDistributionsTransform2D<pcl::PointXYZ, pcl::PointXYZ> ndt;

  // // Setting scale dependent NDT parameters
  // // Setting minimum transformation difference for termination condition.
  // ndt.setTransformationEpsilon (NDT_EPSILON);
  // // Setting maximum step size for More-Thuente line search.

  // //Setting Resolution of NDT grid structure (VoxelGridCovariance).
  // //ndt.setResolution (1.0);
  // ndt.setGridStep (Eigen::Vector2f(NDT_GRID_STEP, NDT_GRID_STEP));
  // ndt.setGridExtent (Eigen::Vector2f(NDT_GRID_EXTEND, NDT_GRID_EXTEND));
  // // Setting max number of registration iterations.
  // //ndt.setMaximumIterations (100);

  // // Setting point cloud to be aligned.
  // ndt.setInputSource (cloud_out.makeShared());
  // // Setting point cloud to be aligned to.
  // ndt.setInputTarget (cloud_in.makeShared());
  // // Set initial alignment estimate found using robot odometry.
  // Eigen::AngleAxisf init_rotation(initial_rad, Eigen::Vector3f::UnitZ ());
  // Eigen::Translation3f init_translation (0, 0, 0);
  // Eigen::Matrix4f init_guess = (init_translation * init_rotation).matrix ();

  // // Calculating required rigid transform to align the input cloud to the target cloud.
  // pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud (new pcl::PointCloud<pcl::PointXYZ>);
  // ndt.align (*output_cloud, init_guess);


  
  //icp
  pcl::IterativeClosestPoint<PointT, PointT> icp;
  PointCloudT::Ptr finalCloud(new PointCloudT);
  icp.setInputSource(curr_keypoints.makeShared());
  icp.setInputTarget(templates[id].pointcloud_data.makeShared());
  icp.setMaximumIterations (ICP_MAX_ITERATIONS);
  icp.setTransformationEpsilon (ICP_TRANSFORM_EPSILON);
  icp.setMaxCorrespondenceDistance (ICP_MAX_CORRESPONDANCE_DISTANCE);
  icp.setEuclideanFitnessEpsilon (ICP_EUCLIDEAN_FITNESS_EPSILON);
  icp.setRANSACOutlierRejectionThreshold (ICP_OUTLIER_REJECTION_THRESHOLD);

  //icp.setMaxCorrespondenceDistance(100);
  //icp.setMaximumIterations(100);
  //icp.setTransformationEpsilon(1e-6);
  //icp.setEuclideanFitnessEpsilon(1e-6);
  //icp.setRANSACIterations(0);
  //Set initial alignment estimate found using robot odometry.
  Eigen::AngleAxisf init_rotation(vt_relative_rad*M_PI/180.0, Eigen::Vector3f::UnitZ ());
  Eigen::Translation3f init_translation (0, 0, 0);
  Eigen::Matrix4f init_guess = (init_translation * init_rotation).matrix ();
  icp.align(*finalCloud, init_guess);
  if (icp.hasConverged() == false)
  {
    cout << "icp alignment failed score = " <<  icp.getFitnessScore() << " time: " << tt.toc () << "ms" << endl;
    cout.flush();
    return;
  }
  float x, y, z, roll, pitch, yaw;
  Eigen::Affine3f correctionCameraFrame;
  correctionCameraFrame = icp.getFinalTransformation(); // get transformation in camera frame (because points are in camera frame)
  pcl::getTranslationAndEulerAngles(correctionCameraFrame, x, y, z, roll, pitch, yaw); 
  cout << "icp alignment x:" <<  x << " y:" << y << " yaw:" << yaw*180/M_PI << " score:" << icp.getFitnessScore() << " time: " << tt.toc () << "ms"  << endl;
  cout.flush();    

由于BRISK2D特征提取点云要求Organized PointCloud 因此不适用 !


  //BRISK2DEstimation
  // Keypoint Description 
    // pcl::BRISK2DEstimation<pcl::PointXYZ> brisk_descriptor_estimation; 

    // // Source Cloud 
    // FeatureCloudT::Ptr Source_descriptors (new FeatureCloudT); 
    // brisk_descriptor_estimation.setInputCloud (cloud_out.makeShared()); 
    // brisk_descriptor_estimation.setKeypoints (keypoints_out.makeShared()); 
    // brisk_descriptor_estimation.compute (*Source_descriptors); 

    // // Target Cloud 
    // FeatureCloudT::Ptr Target_descriptors (new FeatureCloudT); 
    // brisk_descriptor_estimation.setInputCloud (cloud_in.makeShared()); 
    // brisk_descriptor_estimation.setKeypoints (keypoints_in.makeShared()); 
    // brisk_descriptor_estimation.compute (*Target_descriptors); 

    // std::cout << "Target descriptor number : " << Target_descriptors->size() << std::endl; 
    // std::cout << "Source descriptor number : " << Source_descriptors->size() << std::endl; 

    // // // Correspondences matching 
    // // pcl::registration::CorrespondenceEstimation<FeatureT, FeatureT> correspondence_estimation; 

    // // pcl::CorrespondencesPtr correspondences(new pcl::Correspondences); 
    // // correspondence_estimation.setInputSource (Source_descriptors); 
    // // correspondence_estimation.setInputTarget (Target_descriptors); 
    // // correspondence_estimation.determineCorrespondences (*correspondences); 
    // pcl::SampleConsensusPrerejective<PointT,PointT,FeatureT> align;
    // align.setInputSource (cloud_out.makeShared());
    // align.setSourceFeatures (Source_descriptors);
    // align.setInputTarget (cloud_in.makeShared());
    // align.setTargetFeatures (Target_descriptors);
    // align.setMaximumIterations (5000); // Number of RANSAC iterations
    // align.setNumberOfSamples (3); // Number of points to sample for generating/prerejecting a pose
    // align.setCorrespondenceRandomness (5); // Number of nearest features to use
    // align.setSimilarityThreshold (0.9f); // Polygonal edge length similarity threshold
    // align.setMaxCorrespondenceDistance (0.5f); // Inlier threshold
    // align.setInlierFraction (0.25f); // Required inlier fraction for accepting a pose hypothesis

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Point Cloud Library学习之ICP迭代最近点匹配法NDT2D正态分布转换法 的相关文章

  • Lambda、封闭变量、显示类、可序列化性和流行层

    我已经为 Compact Framework 实现了一个流行层 包括BinaryFormatter 类似序列化器 我希望能够在适当的情况下序列化编译器生成的类 这些类是由 lambda 和迭代器等产生的 这样如果 例如 lambda 及其封
  • Windows Server / Datacenter:设置 CPU 关联性 > 64 个核心

    SetThreadAffinityMask 允许为 64 个逻辑核心 处理器 设置关联掩码 但是 Windows Datacenter 最多可以有 64 个 CPU 每个 CPU 都有多个内核 请参阅here http social tec
  • F1 2019 UDP解码

    我目前正在为 F1 方向盘开发自己的显示器 F1 2019 由codemasters提供 通过UDP发送数据 该数据存储在字节数组中 我在解码返回的数组时遇到一些问题 问题是我得到了很多信息 但我不知道如何处理它们 我将向您介绍我所尝试过的
  • 从对象中获取类型正在返回运行时类型[重复]

    这个问题在这里已经有答案了 我有一个简单的功能 public string getType object obj Type type obj getType return type FullName 如果您在运行时创建的字符串对象上使用此函
  • 如何在 Xamarin.Forms 中强制使用浅色模式?

    我的应用程序的 UI 设计为在灯光模式下使用 但如果手机的默认主题是深色模式 我的应用程序也会切换到深色模式 并且 UI 看起来很垃圾 所以我想强制我的应用程序使用灯光模式 我怎样才能做到这一点 In my app xaml我使用的文件Us
  • 为什么 C++11/Boost `unordered_map` 在擦除时不重新散列?

    我想知道为什么 C 11 和 Boost 的 hashmap 在通过迭代擦除元素时不会调整大小 即使这在技术上不是内存泄漏 我认为这可能是应用程序中的一个严重问题 这对我来说是一个隐藏的问题 很难追踪它 并且它实际上可能会影响许多应用程序
  • Qml 中的 FileDialog 在发布中不起作用

    我正在与以下项目合作Qt Quick Control 2 当我尝试在调试模式下运行软件时 FileDialog qml 可以完美打开 但是当我将其部署为发布模式时 它无法工作 这是我的代码 import QtQuick 2 4 import
  • 将 CryptoStream 解密为 MemoryStream

    我编写了一个过程 其中文件被加密并上传到 Azure 然后必须解密下载过程 这会失败并出现 填充无效且无法删除 错误 或 要解密的数据长度为无效的 错误 我在网上尝试了很多解决方案 包括C 使用 RijndaelManaged 和 Cryp
  • 在 C++ 中重用异常处理代码

    我有这两个函数 具有重复的异常处理 其唯一目的是显示错误消息 void func1 noexcept try do task do another task catch const std out of range e show msg O
  • 这个对象的内存会是什么样子?

    我想知道这个类 它的对象 的内存布局是什么样的 class MyClass string myString int myInt public MyClass string str int i myString str myInt i MyC
  • C++ 中的静态虚函数

    我有一个基类和一个派生类 我想更改基函数 同时保持它们静态 因为它们应该作为静态传递给其他函数 我怎样才能做到这一点 ATL 框架通过将基类设为模板 然后让派生类将其类类型作为模板参数传递 从而绕过了无虚拟静态的限制 然后 基类可以在需要时
  • 枚举和枚举类之间的区别[重复]

    这个问题在这里已经有答案了 谁能解释一下两者之间的区别 enum Type1 type2 And enum class Type1 type2 我经常使用前者 可能太频繁而没有足够的封装 但我从未使用过第二个例子 Thanks enum A
  • Windows Phone 8.1 应用程序多语言

    我正在使用 Visual Studio 2015 在 SilverLight 中创建 Windows Phone 应用程序 8 1 我正在用英语和阿拉伯语创建多语言应用程序 为此 我在项目中创建了 Strings 文件夹 其中包含 en U
  • 使用 Entity Framework Core 在运行时迁移

    我正在将 PHP Illuminate 应用程序移植到 ASP NET Core EF Core 其中一部分由类似 Wordpress 的安装过程组成 该过程要求提供数据库凭据 然后创建应用程序运行所需的表 本质上 我想在运行时运行某种迁移
  • 为什么这是一个未定义的行为?

    我的回答这个问题 https stackoverflow com q 18706587 845092这个函数是 inline bool divisible15 unsigned int x 286331153 2 32 1 15 40086
  • C# SerialPort BaseStream ReadAsync - CancellationToken 从未取消?

    我尝试以异步方式从串行端口读取数据 请记住操作所花费的时间不得超过指定的时间段 我使用的代码 private async Task
  • C# 中的自定义按钮:如何删除悬停背景?

    我正在尝试使用 Visual Studio 2005 对我的表单 其 FormBorderStyle none 执行自定义按钮 我在链接到该按钮的 ImageList 中有我的 3 种状态按钮图像 this btnClose AutoSiz
  • 使用全局 Web API 过滤器属性进行 Unity 依赖注入

    参考这个CodePlex 统一文章 http unity codeplex com discussions 446780我能够使用 WebAPI 控制器获取过滤器属性 如下所示 MyFilterAttribute public class
  • 有C语言的解释器吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话
  • 我如何将 C++ 与 VALA 混合起来

    我需要用 C 编写跨平台的 GUI 应用程序 但由于 C 的大多数 GUI 库都有点乏味 而且我对 C NET 非常熟悉 我发现使用 GTK 的代码 Vala 代码非常有趣 并且与其他方式相比有点容易 那么我该如何将 VAlA 与 C 混合

随机推荐

  • ElasticSearch 查询语法

    环境 ElasticSearch6 4 2 以下查询请求方式均为Post 索引名 book 索引结构 mappings novel properties word count type interger author type keywor
  • Vue基础之指令与过滤器

    vue 简介 1 什么是 vue 官方给出的概念 Vue 读音 vju 类似于 view 是一套用于构建用户界面的前端框架 2 vue 的特性 vue 框架的特性 主要体现在如下两方面 数据驱动视图 双向数据绑定 2 1 数据驱动视图 在使
  • unity第一人称射击游戏,枪击游戏,功能完整可以当大作业或者毕设

    unity第一人称射击游戏 枪击游戏 含源码和exe导出文件 下载链接在文末 unity第一人称枪击游戏 分为海岛地图和沙漠地图 可以开镜射击 敌人可以移动 菜单页面有开始游戏 游戏说明 退出三个按钮 游戏有音效 可以通过ASDW移动人物
  • 查看jks证书内容

    keytool list v keystore xxx jks 输入密钥库口令
  • C++进阶必读书籍

    结合一些我的学习经历 希望对于想学C 的人有些帮助 大家有什么好想法望提出 我老师最初是从C语言教起的 用的是潭浩强的 lt
  • ajax day3

    3 将普通对象转为查询参数字符串形式 创建URLSearchParams参数 再用toString方法转为字符串 4 xhr对象 请求参数 body参数 5 promise promise对象一旦被兑现或拒绝 就是已敲定了 状态无法再被改变
  • Python模块之操作数据库MySQL篇

    目录 一 安装PyMySQL模块 二 操作数据库 1 连接数据库 2 执行sql语句 execute和executemany 3 创建数据表 三 操作MySQL数据表 1 新增数据 2 查询数据 3 修改数据 4 删除数据 5 踩到的坑 一
  • python批量读取Excel文件

    将同一个文件夹下的xlsx文件读取 import os import pandas as pd path r path of file for i in os listdir path df pd read excel os path jo
  • [读论文]CAAD-2018 Targeted Attack方向季军技术报告

    这次分享的是CAAD 2018比赛中Northwest Security团队的技术报告 该团队在此次比赛中取得了了targeted Attack 方向第三名 non targeted Attack方向第四名的成绩 题目 Leverage O
  • 构建 fluentd 镜像与部署应用

    本文将具体介绍如何在基础镜像 ubuntu 20 04 上搭建 fluentd 镜像 并且实现监控指定目录的日志文件 构建镜像 首先 从 docker hub 中挑选一个合适的基础镜像 例如 ubuntu 20 04 docker pull
  • 区块链+物联网=?

    链客 专为开发者而生 有问必答 此文章来自区块链技术社区 未经允许拒绝转载 区块链与物联网 IoT 的交叉应用已成为最有前途的区块链用例之一 在过去的几个月里 IoTeX一直与我们的战略合作伙伴合作 并进行了独立的研究 为了能够在短期内采用
  • 新闻

    4月 中国科技产业智库甲子光年发布 AIGC应用与实践研究展望报告 及AIGC产业图谱 面向AIGC技术创新者 产业参与者 资本机构和政府等各方展现AIGC产业的整体生态环境和行业发展 华院数智人凭借其在生成式AI技术 人机交互能力和市场应
  • esp32+vscode环境搭建速记

    esp32idf vscode环境搭建速记 建议按照入下步骤进行 在vscode插件里安装esp32idf 或者用在线的下载器安装会出现一些莫名奇妙的问题 第一步 安装esp32idf 官方网址 https dl espressif cn
  • gridlayout java_Swing-布局管理器之GridLayout(网格布局)-入门

    网格布局特点 l 使容器中的各组件呈M行 N列的网格状分布 l 网格每列宽度相同 等于容器的宽度除以网格的列数 l 网格每行高度相同 等于容器的高度除以网格的行数 l 各组件的排列方式为 从上到下 从左到右 l 组件放入容器的次序决定了它在
  • idea中thymeleaf语法不提示的所有原因

    首先pom xml里面要导入thymeleaf的依赖 然后在html中加入 xmlns th http www thymeleaf org 最后点击file gt settings 查看插件是否使用 未使用点击打勾重启
  • AMS1117典型电路

    AMS1117 3 3V 5V 封装 常见应用连接 1 输入旁路电容Input Bypass Capacitor A 10uF tantalum on the input is a suitable input bypassing fora
  • 解决 SyntaxError:Unexpected end of JSON input 或 Unexpected token u in JSON at position 0 问题

    1 报错原因 JSON 接收的数据不完整 或者数据格式不符合要求 如 undefined 2 JSON 数据格式要求 1 JSON文件都是被包裹在一个大括号中 通过key value的方式来表达数据 2 JSON的Key必须包裹在一个双引号
  • Python 魔法方法(三) __getattr__,__setattr__, __delattr__

    1 getattr 当我们访问一个不存在的属性的时候 会抛出异常 提示我们不存在这个属性 而这个异常就是 getattr 方法抛出的 其原因在于他是访问一个不存在的属性的最后落脚点 作为异常抛出的地方提示出错再适合不过了 看例子 我们找一个
  • 调试最长的一帧(第27天)

    对于几个多线程渲染中的成员变量 继续抄一抄 Block阻塞器 BlockCount 计数器类 它与阻塞器类的使用方法基本相同 block 阻塞线程 release 释放线程 不过除此之外 BlockCount的构造函数还可以设置一个阻塞计数
  • Point Cloud Library学习之ICP迭代最近点匹配法NDT2D正态分布转换法

    参考来源 https pointclouds org documentation classpcl 1 1 registration html ab1d64f86162b2df716ead8d978579c11 http epsilonjo