【C++】相机标定源码笔记- RGB 相机与 ToF 深度传感器校准类

news2024/10/5 21:14:18

类的设计目标是为了实现 RGB 相机与 ToF 深度传感器之间的高精度校准,从而使两种类型的数据能够在同一个坐标框架内被整合使用。这在很多场景下都是非常有用的,比如在3D重建、增强现实、机器人导航等应用中,能够提供更丰富的场景信息。

569177efc77f0ad01fb42ce627251614.png

---------------变量-----------------

公有成员变量: 存储RGB和ToF图像的大小、存储物理世界中标定板的坐标点、分别存储在RGB和ToF图像中检测到的棋盘格角点、存储RGB和TOF角点的三维点集、存储RGB和ToF相机的内参矩阵、存储RGB和ToF相机鱼眼畸变系数、存储RGB和ToF相机一般畸变系数、RGB/ToF角点检测是否成功的bool向量。

私有变量: 是否为复杂RGB/ToF相机模型 ,RGB/ToF文件名向量,棋盘格角点的布局大小,角点之间的物理距离,是否使用圆点标定板进行角点检测,在RGB和ToF图像中用于进行角点检测的ROI(感兴趣区域)大小,  RGB/ToF是否采用鱼眼相机模型,RGB/ToF重投影误差阈值,实际计算出的RGB/ToF重投影误差,RGB/ToF点集,RGB和TOF之间的变换矩阵,平均误差距离.

---------------函数-----------------

默认构造函数:  初始化标志位为false表示不是复杂相机模型。初始化RGB、ToF最大重投影误差。 初始化RGB相机角点检测的ROI大小和TOF相机角点检测的ROI大小。

带文件名构造函数:调用加载参数方法加载参数。

析构函数:空。

设置棋盘格标定板参数: 设置角点布局大小,设置角点之间的物理距离,设置是否使用圆点标定板进行角点检测。

设置RGB相机的参数:清除标定点集(世界坐标点),清除RGB图像角点集,清除检测结果,清除点集,清除文件名列表。  设置RGB图像文件名列表,设置RGB图像大小,设置最大重投影误差,设置是否为鱼眼相机模型。设置是否为复杂相机模型。

设置ToF相机的参数:清除标定点集,清除TOF图像角点集,清除检测结果,清除点集,清除文件名列表。设置TOF图像文件名列表,设置TOF图像大小,设置最大重投影误差,设置是否为鱼眼相机模型,设置是否为复杂相机模型。

执行相机标定:清空之前所有的标定结果和临时变量,为新的标定过程做准备(清除标定板世界坐标点数据容器、清除TOF相机的图像角点数据,清除TOF相机的角点检测结果数据,清除TOF相机的点集数据,清除RGB相机的图像角点数据,清除RGB相机的角点检测结果数据,清除RGB相机的点集数据)。 根据RGB图像大小设置角点搜索区域大小,根据TOF图像大小设置角点搜索区域大小。检查RGB和TOF图像数量是否匹配。遍历每一对RGB和TOF图像进行标角点检测处理 {取出一对RGB\TOF图像并读取,定义RGB/TOF图像转换为灰度图的变量,初始化结果false,定义存放RGB/TOF图像检测到的角点。 如果是圆点标定板(检测RGB图像的圆点网格角点,设置检测结果为false并添加到RGB/TOF检测结果列表,打印RGB检测角点失败信息,继续下一对图像。否则检测成功,检查TOF图像,如果检测失败,将false结果添加到检测结果列表并打印tof检测失败信息,继续下一对图像,否则RGB和TOF图像都成功检测到角点,绘制RGB图像角点,标记检测成功并添加到结果列表。将RGB/TOF检测到的图像角点添加到 RGB/TOF校准图像角点集合,打印角点检测成功信息)。 如果是棋盘格角点,检测RGB图像的棋盘角点(如果失败将失败结果添加到结果列表打印失败信息,继续下一对图像),RGB检测成功则检测TOF图像(检测失败添加失败结果到结果列表并打印信息后继续下一对),RGB和TOF图像都成功检测到棋盘角点( 转换RGB图像为灰度图,使用cornerSubPix算法对RGB图像中的角点进行精细化处理,提高角点定位的准确性,将精细化处理后的RGB图像角点添加到容器中,在灰度图像上绘制检测到的角点便于观察。转换TOF图像为灰度图,同样为焦点检测做准备,对TOF图像中的交点进行精细化处理,将精细化处理后的TOF图像角点添加到容器中,在TOF图像的灰度图上绘制检测到的角点。将当前图像对的检测结果标记为成功并记录。再次将RGB和TOF图像的角点数据添加到对应容器中,打印当前图像对成功完成标定的信息) ,如果角点检测成功并且设置为可视化(对灰度图像进行反色处理增强视觉效果,显示处理后的RGB灰度图像,对TOF图像进行同样的反色处理,显示处理后的TOF图像,短暂等待以便图像显示。)} 。  生成世界坐标系中的点[ 计算用于标定的图像数量,根据图像数量生成对应的世界坐标点],根据角点数据计算RGB和TOF图像的各角点夹角, 定义RGB和TOF相机标定过程中计算得到的外参(旋转向量和平移向量),定义存储RGB和TOF相机去畸变后的映射矩阵。

RGB相机标定{如果是鱼眼相机模型[ 定义标定选项是标志位,设置其为重新计算外参、检查条件数 、固定偏斜系数。 对RGB相机进行鱼眼模型标定,初始化去畸变映射矩阵。],如果不是鱼眼相机模型[定义迭代终止条件,定义标志选项,(如果是复杂相机模型,设置标志启用k4 k5 k6三个畸变参数,启用倾斜模型,启用薄棱镜畸变模型), 进行相机标定,计算相机内参和畸变系数,输出重投影误差]。}。计算角点重投影误差[ 初始化单词重投影误差为0,初始化平均重投影误差为0,初始化总的重投影误差为0.定义 用于存放重投影点的向量。遍历所有的世界坐标点集(获取当前索引下的世界坐标点集,通过得到的摄像机内外参数,对空间的三维点进行重投影计算,得到新的投影点(鱼眼相机模型和普通相机分别处理),计算新的投影点与旧的投影点之间的误差,获取当前索引下的图像坐标点集,创建一个用于存储旧的图像点的Mat对象1xN,创建一个用于存储新投影点的Mat对象1xN,将点集转换成Mat(1XN)格式以便计算误差。)使用欧氏距离计算两组点的误差,计算平均误差,将当前的平均误差累加到总误差中,打印重投影误差结果]。  

TOF相机标定{ 如果是鱼眼TOF相机模型[ 初始化标志位,设置重新计算外参、检查条件数、固定倾斜系数,标定鱼眼相机,初始化去畸变矫正映射矩阵 ],如果不是鱼眼TOF相机模型[ 定义迭代终止条件,初始化标志位,如果是复杂相机模型(设置标志位启用k4 k5 k6三个畸变系数,设置倾斜模型,设置薄棱镜模型),进行相机标定计算内外参和畸变系数,输出总的重投影误差。] 。计算重投影误差[ 定义单词重投影误差、平均重投影误差、总重投影误差,遍历每组世界坐标点计算重投影误差( 获取当前的世界坐标点,通过得到的摄像机内外参数对空间的三维点进行重投影计算,得到新的投影点(鱼眼相机和非鱼眼相机分别进行世界坐标点的重投影),计算新的投影点和旧的投影点之间的误差(将当前组的世界坐标点和图像坐标点 转换为1XN的Mat型,使用欧氏距离L2范数通过norm计算误差)计算所有角点的平均误差,累加角点平均误差)。 计算总的平均误差,输出校正后的总重投影误差]。  }

求解相机坐标系下所有帧的角点三维坐标集合:获取标定点集的数量,定义存储RGB相机的三维点集,存储TOF相机的三维点集,并使用reserve预先为以上两容器分配足够的内存,以容纳将要存储的三维点。遍历每一帧图像的标定点集[ 定义RGB相机的旋转矩阵和平移向量,初始化RGB图像世界坐标系角点到相机坐标系角点的旋转矩阵,将标定得到的旋转向量转换为旋转矩阵,将旋转矩阵Mat转换为Eigen]Eigen::Matrix3f ,   将 平移向量Mat转换为Eigen::Vector3f 。获取当前帧图像中的三维点数量,遍历角点( 转换原始世界坐标系三维点为vector3f格式,根据旋转矩阵和平移向量计算 RGB/TOF相机坐标系下的三维点,存储到RGB/TOF点集中)可选的将点集保存到文件] 调整所有帧的RGB/TOF相机坐标系下的点集容器的存储空间至合适大小,将所有帧的RGB/TOF相机坐标系下的点集赋值到成员变量std::vector<Eigen::Vector3f>中。

bc9d559b980e846cfcd6a3a10b8dab39.png

10f98152b4d3e74ee87f2a6511a8c96a.png

3f266d91dbe2650e5790c3c03c608019.jpeg

9f5bad60eb7fce9c1dce591326818643.png

7f141b7cf51093c6f050a06af99ac9a4.png

SVD求解左右相机外参(TOF相机坐标系的三维点到RGB相机坐标系的变换矩阵): 定义对应点集的对象,定义变换矩阵,定义平均点距离,定义均方根误差(RSME),定义内点数量,获取对应点集(所有帧的RGB相机坐标系下的点集)的数量,调整对应点集的大小以容纳所有的对应点,为所有对应点分配索引(初始化对应点集),使用SVD求解两个相机的外参(旋转和平移矩阵),输出变换矩阵(将TOF坐标系下的三维点变换到RGB坐标系下的变换矩阵)。  计算在工作空间范围内的误差:定义平均距离误差为0,遍历每个点(计算当前TOF点经过变换矩阵后的RGB坐标系下的坐标,累积变换后的点与RGB坐标系下三维点的欧氏距离L2范数),计算平均误差距离,输出平均误差距离。保存平均误差距离和TOF相机到RGB相机的变换矩阵。 返回true.

使用RGB和深度数据创建带颜色的点云(输入RGB Mat,深度图mat,输出点云,保存文件名):定义一个用于存储点云的向量,用reserve为该向量预先分配内存以优化性能,定义用于存储变换矩阵的变量,定义深度图的比例尺因子,获取深度相机的内参(fx,fy,cx,cy),【遍历深度图的每一行,遍历深度图的每一列,获取深度图中第v行第u列的深度值,如果深度值为0则跳过此点,定义一个三维点并计算其TOF坐标系下的空间坐标,将计算得到的三维点加入点云向量】。shrink_to_fit调整点云向量的大小以适应实际数据。获取变换矩阵的逆矩阵,对TOF坐标系下三维点云进行坐标变换变换到RGB坐标系下。定义存储rgb物理点的向量,并设置大小为点云尺寸,将变换后的三维点复制到rgb物理点向量中。定义用于存储rgb投影点的向量,定义RGB相机的外参R T为0向量,将RGB三维点投影到图像坐标系下。清空并调整输出点云大小为三维点数。获取rgb图像的列和行数。遍历输出点云,将 RGB 图像的颜色信息分配给点云中的每个点{ 获取rgb投影点i的坐标x,y. 如果重投影点在图像外,则使用黑色(设置输出点云i的r g b为0,坐标即RGB三维点坐标)。如果rgb重投影点在图像内,则使用图像中的颜色。 },最后PCDWriter保存结果点云。

429962bbc3607c01f0cc2b85031b9210.png

7420d7f50bc2f5a5e7d05339df5a8e8e.png

保存标定参数到文件:检查文件名是否是.yml后缀。创建文件写入对象cv::FileStorage,cv::eigen2cv将变换矩阵转换为Mat格式,保存变换矩阵和平均距离误差。  保存RGB相机内参,如果是鱼眼RGB相机保存鱼眼参数模型bool标志和鱼眼RBG相机畸变系数,否则保存普通相机畸变系数。  保存TOF相机内参,如果是鱼眼TOF相机,保存鱼眼模型bool标志和鱼眼TOF相机畸变系数,否则保存普通相机畸变系数。释放文件写入对象,返回true.

从文件加载标定参数:检查是否是.yml文件,打开文件,定义变换矩阵Mat,读取变换矩阵Mat后转换为Eigen::Matrix4f格式,赋值给私有变量。 读取RGB相机内参、是否鱼眼RGB相机模型bool标志,如果是鱼眼RGB相机读取鱼眼RGB相机畸变系数,否则读取普通RGB相机畸变系数。  读取TOF相机内参,读取是否鱼眼TOF相机模型bool标志,如果是鱼眼TOF相机则读取鱼眼TOF相机畸变系数,否则读取普通相机畸变系数。释放文件对象,返回true。

https://blog.csdn.net/T_T_T_T_/article/details/125439151

https://blog.csdn.net/oakchina/article/details/130703831

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

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

相关文章

学习笔记(linux高级编程)11

进程间通信 》信号通信 应用&#xff1a;异步通信。 中断&#xff0c;&#xff0c; 1~64&#xff1b;32应用编程。 如何响应&#xff1a; Term Default action is to terminate the process. Ign Default action is to ignore the signal. wait Core Default action is …

Eclipse运行main函数报 launch error

右键run as java application&#xff0c;运行main函数的时候报launch error 解决方式&#xff1a;文件右键run configurations 旧的是Project JRE&#xff0c;改成下图这个样子

视频去水印在线工具,视频去水印网站在线使用

在数字媒体时代&#xff0c;视频创作已成为越来越多人热衷的活动。然而&#xff0c;当我们想要对下载的视频进行二次创作或分享时&#xff0c;视频上的水印常常成为一个头疼的问题。本文将为您介绍几种免费且高效的去水印方法&#xff0c;让您在视频制作中游刃有余&#xff01;…

Studying-代码随想录训练营day28| 122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II、1005.K次取反后最大化的数组和

第28天&#xff0c;贪心算法part02&#xff0c;题目难度在增加&#xff0c;要锻炼贪心思维能力(ง •_•)ง&#xff0c;编程语言&#xff1a;C 目录 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II 1005.K次取反后最大化的数组和 总结&#xff1a; 122.买卖股票的…

npm install puppeteer 报错 npm ERR! PUPPETEER_DOWNLOAD_HOST is deprecated解决办法

npm install puppeteer 报错如下&#xff1a; npm ERR! PUPPETEER_DOWNLOAD_HOST is deprecated. Use PUPPETEER_DOWNLOAD_BASE_URL instead. npm ERR! Error: ERROR: Failed to set up Chrome v126.0.6478.126! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to sk…

绝区零国际服下载 一键下载绝区零国际服教程

绝区零是一款米哈游倾情打造的全新都市幻想动作角色扮演游戏。在游戏中&#xff0c;我们将扮演一名绳匠&#xff0c;这是为出于各种原因需要进入危险空洞的人提供指引的专业人士。您将与独特的角色一起踏上冒险之旅&#xff0c;携手探索空洞&#xff0c;对战强大敌人&#xff0…

每周题解:最大半连通子图

题目链接 最大半连通子图 题目描述 一个有向图 G ( V , E ) G\left(V,E\right) G(V,E) 称为半连通的 (Semi-Connected)&#xff0c;如果满足&#xff1a; ∀ u , v ∈ V \forall u,v\in V ∀u,v∈V&#xff0c;满足 u → v u\to v u→v 或 v → u v\to u v→u&#xff0…

番外篇 | 斯坦福提出即插即用二阶优化器Sophia :相比Adam实现2倍加速,显著节省大语言模型训练成本

前言:Hello大家好,我是小哥谈。大模型的预训练成本巨大,优化算法的改进可以加快模型的训练时间并减少训练开销。目前大模型的训练优化器基本上都采用Adam及其变体,并且Adam的应用已经有9个年头了,在模型优化方面相当于霸主的地位。但是能否够在优化器方面提高模型预训练效…

【每日刷题】Day79

【每日刷题】Day79 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1619. 删除某些元素后的数组均值 - 力扣&#xff08;LeetCode&#xff09; 2. 1365. 有多少小于当前…

python3.8安装详细教程

python3.8下载及安装详细教程 Python 3.8 是一个重要的Python版本&#xff0c;它引入了一系列新功能和改进。以下是对Python 3.8的详细概述&#xff0c;包括其关键特性、安装方法以及版本状态等信息。 Python 3.8的关键特性 海象运算符&#xff08;Walrus Operator&#xff09…

保障性住房数字化运营平台助力租赁住房智能化管理

保障性住房能提供合理的价格、良好的配套设施和优越的租住体验&#xff0c;租赁将不是问题。 一、发力租赁型保障房建设 随着城镇化进程的加速和流动人口规模的扩大&#xff0c;进城务工人员、新就业大学生等新市民、青年人的住房困难问题日益凸显。加快发展租赁型保障性住房…

深圳技术大学oj C : 生成r子集

Description 输出给定序列按字典序的 &#xfffd; 组合&#xff0c;按照所有 &#xfffd; 个元素出现与否的 01 标记串 &#xfffd;&#xfffd;&#xfffd;&#xfffd;−1,...,&#xfffd;1 的字典序输出. 此处01串的字典序指&#xff1a;先输入的数字对应低位&#x…

使用高斯混合模型识别餐厅热点

使用 GMM 识别加拿大多伦多的直观餐厅集群&#xff08;附 Python 代码&#xff09; 聚类算法&#xff08;例如 GMM&#xff09;是一种有用的工具&#xff0c;可帮助识别数据中的模式。它们使我们能够识别数据集中的子组&#xff0c;从而提高你的理解或增强预测模型。在本文中&a…

中国国产AI芯片的崛起

一、CUDA的垄断 当讨论半导体行业面临的挑战时&#xff0c;你首先想到的是什么&#xff1f;光刻机&#xff1f;3纳米或者5纳米技术&#xff1f;我们无法生产的完美方形芯片&#xff1f;是的&#xff0c;但也不完全是。 人们经常把半导体芯片归类为硬件产业&#xff0c;但实际上…

mmcv安装失败及解决方案

假如想安装的版本是mmcv1.4.0, 但是pip install mmcv1.4.0总是失败&#xff0c;若是直接pip install mmcv会安装成功&#xff0c;但是安装的就是最新版本&#xff0c;后面代码跑起来还会报错&#xff0c;怎么办呢&#xff1f; 接下来分享一个mmcv指定版本安装的方式。 网页&a…

PCL小笔记

一、常用概念 1&#xff0c;过滤器Filters 消除噪音 2&#xff0c;特征Features 集合点属性&#xff1a;曲面的曲率估计和查询点的法线 通过k-neighborhood计算得到这两个属性作为特征 查找方法&#xff1a;KD-tress、八叉树等 3&#xff0c;关键点Keypoints 可以利用明确标…

ios-实验室暑假培训(1)

一 组队 在正式培训之前&#xff0c;也是数模比赛的众中之重。 一定要商讨好组队的相关事宜&#xff01;要求建模/编程/写作/写作三方能力交叉&#xff01; 而这三个当中&#xff0c;决定比赛拿奖上限的是编程手&#xff0c;决定比赛能不能拿奖的是写作手。而建模的更像是一个…

【JavaWeb】登录校验-会话技术(一)Cookie与Session

登录校验 实现登陆后才能访问后端系统页面&#xff0c;不登陆则跳转登陆页面进行登陆。 首先我们在宏观上先有一个认知&#xff1a; HTTP协议是无状态协议。即每一次请求都是独立的&#xff0c;下一次请求并不会携带上一次请求的数据。 因此当我们通过浏览器访问登录后&#…

Cyuyan中的自定义类型——结构体

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、结构体基础知识&#xff08;一&#xff09;、结构体类型的声明、变量的创建与初始化&#xff08;二&#xff09;、结构成员访问操作符&#xff08;三&#…

近红外光谱脑功能成像(fNIRS):1.光学原理、变量选取与预处理

一、朗伯-比尔定律与修正的朗伯-比尔定律 朗伯-比尔定律 是一个描述光通过溶液时被吸收的规律。想象你有一杯有色液体&#xff0c;比如一杯红茶。当你用一束光照射这杯液体时&#xff0c;光的一部分会被液体吸收&#xff0c;导致透过液体的光变弱。朗伯-比尔定律告诉我们&#…