【点云配准】刚性物体的鲁棒姿态估计

news2024/11/17 3:37:08

目录

什么是刚性物体的鲁棒姿态估计?

刚性物体的姿态估计时可能会遇到的问题及解决方法:

采样一致性(SAC)算法的原理

预配准采样一致性(Prerejective Sample Consensus, PRSAC)算法的原理

SAC算法与PRSAC算法的不同点

代码


什么是刚性物体的鲁棒姿态估计?

刚性物体是指在三维空间中保持形状和尺寸不变的物体,例如物体中的一个刚性工具或一个稳定的物体。姿态估计是确定物体在三维空间中的旋转和平移变换的过程,即确定物体的位置和方向。

刚性物体的鲁棒性姿态估计是指对刚性物体进行姿态估计的时候,考虑到噪声、局部变形或不完整点云等因素,通过采用鲁棒性较强的方法来提高准确性

刚性物体的姿态估计时可能会遇到的问题及解决方法:

问题:

  1. 噪声:输入的点云数据可能包含噪声,干扰姿态估计的准确性。

  2. 不完整点云:点云数据可能不完整,可能存在缺失或遮挡的部分。

  3. 局部变形:由于物体的几何形状可能存在变形或形状扭曲,局部区域的点云可能与整体形状不一致。

为了解决这些问题,鲁棒姿态估计方法通常使用一些技术,包括但不限于以下内容

  1. 采样一致性(Sample Consensus, SAC)算法:通过随机采样和一致性判断来估计刚性变换矩阵,可以优化对噪声和异常值的鲁棒性。

  2. 迭代最近点(Iterative Closest Point, ICP)算法:通过迭代优化匹配点云之间的最小平方距离,来估计刚性变换矩阵,可用于对齐点云和估计刚性物体的姿态。

  3. 特征描述子:使用几何或局部特征描述子,例如法线、曲率、SHOT等,帮助提高在噪声和不完整点云情况下的匹配和姿态估计准确性。

  4. 鲁棒对应关系:通过过滤不正确的匹配对、剔除噪声和异常值等,建立可靠的对应关系,提高姿态估计的鲁棒性。

采样一致性(SAC)算法的原理

当我们想要找到一组数据中的某种模式或规律时,采样一致性(Sample Consensus, SAC)算法可以帮助我们。

想象一下,我们手上有一堆点的数据,并且我们认为这些点可以被拟合成一条直线或者一个平面。但是,数据中可能会有一些异常值或者噪声,它们可能偏离了我们期望的模式。

SAC算法的任务就是找到最适合我们数据的模型。它的工作原理是这样的

  1. 首先,我们从数据中随机选择一些点,作为我们的候选点。我们假设这些点符合我们期望的模式。

  2. 接下来,我们根据这些选定的点来计算出模型的参数,也就是拟合这些点的最佳直线或平面。

  3. 然后,我们计算其他的点与估计出来的模型之间的距离。如果某个点与模型的距离小于某个阈值,我们认为这个点是符合模型的点,也就是内点。

  4. 如果我们找到了足够多的内点,我们可以通过优化参数来进一步提高模型的准确性。

  5. 最后,我们根据内点的数目或者一致性标准来评估模型的好坏。如果我们达到了预设的一致性标准,我们就认为我们找到了合适的模型。

通过反复迭代这个过程,SAC算法能够帮助我们找到一个最能够描述数据的模型,即使在有些数据点可能是异常值或者噪声的情况下也可以做到。我们可以通过调整阈值和一致性标准等参数来控制算法的准确性和效率。

用通俗的话来说,SAC算法就像是用一颗懂得计算和评估的大脑,帮我们从一堆点的数据中找到最合适的模式或规律,即使有些点离谱也能做到。这个算法在很多领域中都有应用,特别在点云处理方面,帮助我们处理和分析复杂的数据。

预配准采样一致性(Prerejective Sample Consensus, PRSAC)算法的原理

SampleConsensusPrerejective是PCL库中的一种用于点云配准的算法,它基于Sample Consensus(SAC)算法进行改进和扩展,并引入了两个阶段的策略

该算法的原理如下:

  1. Prerejection阶段:根据参考点云,使用特征描述子的比较快速筛选出可能的匹配点。特征描述子可以帮助进行点云的局部特征匹配,提高配准的准确性。

  2. Rejection阶段:在Prerejection阶段基础上,采用采样一致性的迭代优化算法,通过估计刚性变换参数来寻找最佳的配准结果。算法会尝试不同的变换,并通过评估变换的一致性得分来选择最佳的匹配。

通过这两个阶段的策略,SampleConsensusPrerejective算法可以更准确地找到点云间的最佳刚性变换,实现更精确的点云配准。

SAC算法与PRSAC算法的不同点

  1. SampleConsensusPrerejective是一种基于点模型配准的方法,而SAC算法则是用于估计点云的模型参数,如平面、直线等。

  2. SampleConsensusPrerejective采用了两个阶段的策略:Prerejection和Rejection,先筛选匹配点,然后通过迭代和优化达到最佳配准结果。而SAC算法通常是单一阶段的,直接根据采样的点和数据对模型参数进行估计。

  3. SampleConsensusPrerejective在配准过程中会使用到特征描述子,通过比较特征描述子来确定匹配点。而SAC算法通常不涉及特征描述子,主要依靠点之间的距离和几何一致性。

代码

#include <Eigen/Core>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>

#include <pcl/common/time.h>
#include <pcl/console/print.h>

#include <pcl/features/normal_3d_omp.h>
#include <pcl/features/fpfh_omp.h>

#include <pcl/filters/filter.h>
#include <pcl/filters/voxel_grid.h>

#include <pcl/io/pcd_io.h>

#include <pcl/registration/icp.h>
#include <pcl/registration/sample_consensus_prerejective.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/pcl_visualizer.h>

typedef pcl::PointNormal PointNT; //点类型, 位置信息和法线信息
typedef pcl::PointCloud<PointNT> PointCloudT; // 点云类型

typedef pcl::FPFHSignature33 FeatureT; // 特征类型,用来表示点云的局部特征
typedef pcl::PointCloud<FeatureT> FeatureCloudT; // 特征点云类型

typedef pcl::FPFHEstimationOMP<PointNT, PointNT, FeatureT> FeatureEstimationT; // 估计特征的类,在此实例化;使用OMP(Open Multi-Processing)进行并行计算;输入点云为PointNT,输出特征为FeatureT
typedef pcl::visualization::PointCloudColorHandlerCustom<PointNT> ColorHandlerT;// 点云颜色处理器

int main(){
    // 实例化必要的数据容器
    PointCloudT::Ptr object(new PointCloudT);
    PointCloudT::Ptr object_aligned(new PointCloudT);
    PointCloudT::Ptr scene(new PointCloudT);

    FeatureCloudT::Ptr object_features(new FeatureCloudT);
    FeatureCloudT::Ptr scene_features(new FeatureCloudT);

    // Load obejct and scene
    std::string path1 = "/home/jason/file/pcl-learning/14registration配准/5刚性物体的鲁棒姿态估计/chef.pcd"; // 源点云
    std::string path2 = "/home/jason/file/pcl-learning/14registration配准/5刚性物体的鲁棒姿态估计/rs1.pcd"; // 目标点云,没有法线字段信息;所以后续需要计算法线
    if (pcl::io::loadPCDFile<PointNT>(path1,*object) < 0 || pcl::io::loadPCDFile<PointNT>(path2, *scene) < 0) {
        pcl::console::print_error("Error loading obejct/scene file!\n");
    }

    // 下采样
    pcl::console::print_highlight("Downsampling....\n");
    pcl::VoxelGrid<PointNT> grid;
    const float leaf = 0.005f;
    grid.setLeafSize(leaf, leaf, leaf);
    grid.setInputCloud(object);
    grid.filter(*object);

    grid.setInputCloud(scene);
    grid.filter(*scene);

    // Estimate normals for scene
    // 对目标点云计算法线
    pcl::console::print_highlight("Estimate scene normals...\n");
    pcl::NormalEstimationOMP<PointNT, PointNT> nest;
    nest.setRadiusSearch(0.01); // 法线的搜索半径为0.01,即估计场景点云的每个点的法线时,仅仅考虑该点半径范围内的邻居点
    nest.setInputCloud(scene);
    nest.compute(*scene);

    // Estimate features
    // 计算目标点云、源点云的特征描述符
    // 对于下采样点云中每个点,使用PCL的pcl::FPFHEstimationOMP<>类来计算用于对齐过程中,用于匹配的快速点特征直方图(FPFH)描述符
    pcl::console::print_highlight("Estimating features...\n");
    FeatureEstimationT fest;
    fest.setRadiusSearch(0.025);
    fest.setInputCloud(object);
    fest.setInputNormals(object);
    fest.compute(*object_features);

    fest.setInputCloud(scene);
    fest.setInputNormals(scene);
    fest.compute(*scene_features);

    // peform alignment
    // 对齐配准对象创建于配置
    pcl::console::print_highlight("Starting alignment...\n");
    pcl::SampleConsensusPrerejective<PointNT, PointNT, FeatureT> align; // 预配准采样一致性(Prerejective Sample Consensus, PRSAC)算法
    align.setInputSource(object); // 待配准点云为object,即物体点云
    align.setSourceFeatures(object_features); // 设置源点云的特征

    align.setInputTarget(scene); // 设置配准的目标点云为scene,即场景点云
    align.setTargetFeatures(scene_features); // 设置目标点云的特征

    // 下面设置的其实都是默认值!即可以省略
    align.setMaximumIterations(50000); // 设置RPSAC算法的最大迭代次数
    align.setNumberOfSamples(3); // 设置PRSAC算法每次采样的点数
    align.setCorrespondenceRandomness(5); // 设置PRSAC算法中用于计算变换矩阵的匹配对数

    align.setSimilarityThreshold(0.9f); // 设置相似度阈值,用于过滤不相关的匹配对
    align.setMaxCorrespondenceDistance(2.5f * leaf); // 设置最大对应距离,用于拒绝远离目标点的匹配对i
    align.setInlierFraction(0.25f); // 设置内点比例阈值,用于判断配准的成功与否

    {
        pcl::ScopeTime t("alignment");
        align.align(*object_aligned); // 配准
    }

    pcl::visualization::PCLVisualizer vis("Alignment-刚性物体的鲁棒姿态估计");
    if(align.hasConverged()){
        printf("\n");
        Eigen::Matrix4f transformation = align.getFinalTransformation();
        pcl::console::print_info ("    | %6.3f %6.3f %6.3f | \n", transformation (0,0), transformation (0,1), transformation (0,2));
        pcl::console::print_info ("R = | %6.3f %6.3f %6.3f | \n", transformation (1,0), transformation (1,1), transformation (1,2));
        pcl::console::print_info ("    | %6.3f %6.3f %6.3f | \n", transformation (2,0), transformation (2,1), transformation (2,2));
        pcl::console::print_info ("\n");
        pcl::console::print_info ("t = < %0.3f, %0.3f, %0.3f >\n", transformation (0,3), transformation (1,3), transformation (2,3));
        pcl::console::print_info ("\n");
        pcl::console::print_info ("Inliers: %i/%i\n", align.getInliers ().size (), object->size ()); // Inliers: 1384/3432

        // show alignment

        vis.addPointCloud(scene, ColorHandlerT(scene, 0.0, 255.0, 0.0), "scene");
        vis.addPointCloud(object_aligned, ColorHandlerT(object_aligned, 0.0, 0.0, 255.0), "object_aligned");


    }
    else {
        pcl::console::print_error("Alignment failed!\n");
        return -1;
    }

    while (!vis.wasStopped()) {
        vis.spinOnce();
    }

    return 0;
}

输出:

 

点云是绿色,蓝色是源点云,实现较好的配准

 之前用ICP对房间点云配准的时候,效果就不太好;这里RPSAC算法还不错,其实肉眼都有点看不出来,源点云与目标点会能存在共同目标。

但是这个与姿态估计有啥子关系,从配准的输出矩阵来看吗?

声明:代码来自PCL库官网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/730519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java用for循环打印三角形菱形

目录 一、打印矩形 二、打印直角三角形 1.直角三角形 2.打印九九乘法表 三、打印等腰三角形 四、打印平行四边形 五、打印菱形 六、打印两个直角三角形 1.打印两个直角三角形 2.打印倒着的两个直角三角形 七、打印“蝴蝶” 一、打印矩形 //打印矩形for (int i 0; i < a;…

[USACO23FEB] Equal Sum Subarrays G

题目描述 FJ gave Bessie an array aa of length N ( 2 ≤ N ≤ 500 , − 1 0 15 ≤ a i ≤ 1 0 15 ) N(2≤N≤500,−10^{15}≤ai≤10^{15}) N(2≤N≤500,−1015≤ai≤1015) with all N ( N 1 ) 2 \frac{N(N1)}2 2N(N1)​​ contiguous subarray sums distinct. For each i…

【随手记】使用Flask做代理为虚拟机提供pip源

最近在重做虚拟机环境&#xff0c;虚拟机不可连外网&#xff0c;最初python包都是通过离线whl进行安装。但是离线文件已经找不到了&#xff0c;不想重新去一个个下载&#xff0c;而且本地环境跟虚拟机环境也不一致&#xff0c;pip download可能会遇到版本问题&#xff0c;遂考虑…

【SQL】群辉 NAS 安装 Mysql 远程访问连接

群辉安装MySQL具有高效、安全、可靠、灵活等优势&#xff0c;可以为用户提供一个优秀的数据管理和分析环境。同时具有良好的硬件性能和稳定性&#xff0c;可以保障MySQL数据库的高效运行和数据安全. cpolar 是一款内网穿透工具,通过简单的设置,我们即可实现远程访问群辉中mysq…

地下饮用水除硝酸盐技术、生活用水提质增效

项目名称 北京某地下水除硝酸盐项目&#xff0c;出水未检出 工艺选择 两处水源&#xff0c;运行方式为一用一备 工艺原理 树脂官能团耐受硫酸盐、氯离子的干扰&#xff0c;实现选择性吸附硝酸根 项目背景 近年来由于农业活动及排污物的影响&#xff0c;部分地表…

qt---应用窗口创建

运行结果&#xff1a; 此处仅显示widget.cpp文件的代码 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->setFixedSize(500,500); //设置固定尺寸this->setWindowTitle("QQ2024");//设置标题this->setWindowIcon(Q…

c++语言基本语法

今天&#xff0c;我带来c语言基本语法。互联网流行着一个段子&#xff0c;求职者在自己的简历上写精通c&#xff0c;面试官看完以后&#xff0c;微微一笑&#xff0c;疯狂拷问&#xff0c;最后&#xff0c;求职的人回答不出来一两个问题。正如段子所表达的意思&#xff0c;c语言…

【Java基础】CAS (Compare And Swap) 操作

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、使用场景四、原理五、优劣5.1 缺点&#xff1…

【Linux之拿捏信号2】核心转储文件core dump

文章目录 核心转储文件的概念ulimit命令Term和core 核心转储文件的概念 Linux系统级别提供了一种能力&#xff0c;在一个进程出现异常的时候&#xff0c;OS可以将该异常进程的核心代码部分进行核心转储&#xff0c;将内存中进程的相关代码数据&#xff0c;全部dump到磁盘中&am…

飞桨出海!百度飞桨携手联合国教科文组织共促全球高等教育数字化进程

百度飞桨响应联合国教科文组织&#xff0c;积极践行“共商、共建、共享”的全球合作理念&#xff0c;紧跟全球教育创新的步伐&#xff0c;推出面向全球高校教学人员的微认证英文课程——《AI科普与零代码实践》。百度基于丰厚的人工智能技术沉淀打造了本系列课程&#xff0c;携…

DRF+Vue.JS前后端分离项目实例(上):使用 Django-Rest-Framework快速实现 RESTful API 接口编程

1. RESTFul API 接口需求及设计 本文以学生信息查询功能为例&#xff0c;采用前后端分离架构&#xff0c;要求后端提供RESTFul 接口。 1.1 本例要求提供如下查询功能&#xff1a; 列表查询、单条查询添加学生信息更改学生信息删除学生信息 1.2 数据库student表结构如下&…

2.3 Web应用 -1 web 应用概述

2.3 Web应用 -1 web 应用概述 Web与HTTPHTTP协议概述 Web与HTTP World Wide Web: Tim Berners-Lee 网页网页互相链接 网页(Web Page)包含多个对象(objects) 对象&#xff1a;HTML文件、JPEG图片、视频文件、动态脚本等基本HTML文件&#xff1a;包含对其他对象引用的链接 对象的…

ValueError: No engine for filetype: ‘‘

目录 pandas 导出数据时报错 解决办法 很简单的原因&#xff0c;一开始我直接百度&#xff0c;发现没有搜到结果&#xff0c;在此记录一下 保存时&#xff0c;文件名结尾没加xlsx&#xff01;&#xff01;&#xff01; 保存其他格式时&#xff0c;文件名里也要记得加上对应后缀…

【C语言进阶(五)】指针进阶详解(上)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C语言学习分享⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C语言知识   &#x1f51d;&#x1f51d; 指针进阶 1. 前言 2. 字符指针 2.…

一个 NPM 包,帮助数十万程序员提高数十倍效率,难道不开源出来?(一)

我就知道你会点进来看看&#xff0c;吹牛逼的&#xff0c;哈哈&#xff0c;不过呢&#xff0c;我正在朝着这个方向前进&#xff0c;希望大家给我鼓励鼓励&#xff0c;希望点击进来小伙伴点点赞&#xff0c;点点关注。 说实话&#xff0c;写这个项目的目的&#xff0c;从我自己写…

ANSYS ACT插件开发基本流程

开发实施路线 以ACT仿真向导的开发为例&#xff0c;整体可以分为IronPython脚本开发和XML界面开发两个阶段&#xff1b;实际上所有的ANSYS产品的仿真向导开发都是遵循相同的路线流程。此外&#xff0c;另外两种类型的ACT插件开发路线亦是如此。 如何去学习 脚本开发是ACT插件…

再度进化,ChatGLM2-6B详细学习实践记录与资料分享

ChatGLM-6B是清华大学基础研究团队前一段时间开源出来的大模型&#xff0c;一经推出就得到了广泛的使用和推广&#xff0c;在我前面的博文中结合我自己的学习实践经历&#xff0c;已经详细的总结记录了一下&#xff0c;感兴趣或者是有需要的朋友可以自行获取即可&#xff0c;如…

【Linux】-Linux基本指令

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Linux】 分享: 屋檐如悬崖 风铃如沧海 我等燕归来 时间被安排 演一场意外 你悄然走开 故事在城外 浓雾散不开 看不清对白 你听不出来 风声不存在 是我在感慨 梦想来是谁在窗台 …

初步尝试调试postgresql源码

准备用VS2005和postgresql 8.x或9.0&#xff0c;搭建源码调试环境&#xff1b; 不成功&#xff1b;结果如下&#xff1b; 把下面文件中用#连着注释掉7行&#xff0c;然后加上一句 $self->{vcver} 8.00; 得到上面结果&#xff1b;如果不改的话上面的结果也没有&#xff1b;…

恒生电子探路金融大模型

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 近日&#xff0c;恒生电子和旗下子公司恒生聚源正式发布基于大语言模型技术打造的数智金融新品&#xff1a;金融智能助手光子和全新升级的智能投研平台WarrenQ。此外&#xff0c;恒生电子金融行业大模型LightGPT也首次对外亮…