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

类的设计目标是为了实现 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.mzph.cn/news/865179.shtml

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

相关文章

在卷积神经网络(CNN)中为什么可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的感受野

在卷积神经网络&#xff08;CNN&#xff09;中为什么可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的感受野 flyfish 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的…

交叉编译tslib库和上机测试

目录 一、tslib 介绍 二、tslib 框架分析 三、交叉编译、测试 tslib 1.安装工具链 tslib &#xff08;1&#xff09;设置交叉编译工具链 &#xff08;2&#xff09;进入tslib目录 &#xff08;3&#xff09;安装工具链 &#xff08;4&#xff09;确定工具链中头文件、库…

千亿级市场迎来新增量:中老年K歌需求高涨,解读线上+线下创新方向

干货抢先看 1. 我国KTV产业一度达到千亿规模&#xff0c;近年来随着线下娱乐方式多样化&#xff0c;KTV逐渐被年轻用户抛弃&#xff0c;中老年成为行业关键增量。 2. 数据显示&#xff0c;全国量贩式KTV中&#xff0c;60-70岁年龄段用户数同比增长29.6%&#xff0c;订单量同比…

【分布式系统】监控平台Zabbix介绍与部署(命令+截图版)

目录 一.Zabbix概述 1.为什么要做监控 2.zabbix 是什么 3.zabbix 监控原理 4.zabbix 6.0 新特性 5.zabbix 6.0 功能组件 Zabbix Server 数据库 Web 界面 Zabbix Agent Zabbix Proxy Java Gateway 补充 二.部署安装Zabbix 6.0 1.初始化环境 2.安装nginx跟php&am…

计算机网络网络层复习题2

一. 单选题&#xff08;共22题&#xff0c;100分&#xff09; 1. (单选题)如果 IPv4 数据报太大&#xff0c;会在传输中被分片&#xff0c;对分片后的数据报进行重组的是&#xff08; &#xff09;。 A. 中间路由器B. 核心路由器C. 下一跳路由器D. 目的主机 我的答案: D:目的…

图文控件TextImageView

图片文字组合控件&#xff0c;可以灵活的控制图片大小 class TextImageView : AppCompatTextView {private var mStartWidth: Int 0private var mStartHeight: Int 0private var mTopWidth: Int 0private var mTopHeight: Int 0private var mEndWidth: Int 0private var …

不懂PyQt5垂直布局?只需3分钟即可学会

PyQt5中实现垂直布局&#xff0c;主要使用QVBoxLayout类。该布局管理器将子控件垂直排列&#xff0c;并可以根据需要自动调整大小。使用QVBoxLayout可以方便地构建从上到下排列的界面元素。 import sys from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPus…

一个例子理解傅里叶变换的计算过程

假设我们有一个简单的信号&#xff0c;由两个不同频率的正弦波组成&#xff0c;我们希望通过傅里叶变换来分析其频谱。 示例信号 假设我们有一个信号 &#xff1a; 这个信号由两个频率成分组成&#xff1a;一个50 Hz的正弦波和一个120 Hz的正弦波&#xff0c;后者的振幅是前者…

昇思MindSpore学习入门-静态图像加速

使用静态图加速 背景介绍 AI编译框架分为两种运行模式&#xff0c;分别是动态图模式以及静态图模式。MindSpore默认情况下是以动态图模式运行&#xff0c;但也支持手工切换为静态图模式。两种运行模式的详细介绍如下&#xff1a; 动态图模式 动态图的特点是计算图的构建和计…

catia数控加工仿真铣平面粗加工

1&#xff0c;零件建模&#xff0c;毛坯建模 2 在毛坯上建立坐标系 3 添加资料刀具 4&#xff0c;双击对相关加工信息做设置 5 Roughing 加工设置 高亮红色区域是必选的&#xff0c;其他可以默认 6 完成加工仿真 7 加工余量

Upload-Labs靶场闯关

文章目录 Pass-01Pass-02Pass-03Pass-04Pass-05Pass-06Pass-07Pass-08Pass-09Pass-10Pass-11Pass-12Pass-13Pass-14Pass-15Pass-16Pass-17Pass-18Pass-19Pass-20 以下是文件上传绕过的各种思路&#xff0c;不过是鄙人做题记下来的一些思路笔记罢了。 GitHub靶场环境下载&#x…

如果只能选一款老挝语翻译工具,那么只保留《老挝语翻译通》App!一款支持老挝文OCR识别提取文字的翻译神器!

准备去探索老挝这个国家&#xff0c;语言不同怎么办&#xff1f;推荐使用《老挝语翻译通》App&#xff0c;一款专为老挝语学习者和旅行者设计的翻译和学习工具&#xff0c;让你轻松掌握老挝语&#xff0c;无需打字对着说话就能翻译的老挝语翻译通&#xff0c;一定能得到你的认可…

STM32第八课:Su-03t语音识别模块

文章目录 需求一、SU03T语音识别模块二、模块配置流程1.固件烧录2.配置串口和传输引脚3.中断函数4.double类型转换5 数据发送6.接收处理 三、该模块完整代码总结 需求 基于上次完成空气质量传感器&#xff0c;利用SU03T语音识别模块&#xff0c;实现空气质量的语音问答播报。 …

从零开始:如何设计一个现代化聊天系统

写在前面: 此博客内容已经同步到我的博客网站,如需要获得更优的阅读体验请前往https://mainjaylai.github.io/Blog/blog/system/chat-system 在当今数字化时代,聊天系统已成为我们日常生活和工作中不可或缺的一部分。从个人交流到团队协作,从客户服务到社交网络,聊天应用…

HY Lisp 读取宏(reader macro)学习

在学习HY lisp语言的时候HY编程快速入门实践课第三章 HY宏入门-CSDN博客&#xff0c;学习到了读取宏&#xff08;reader macro&#xff09;&#xff0c;尝试将其概念弄明白。 首先&#xff0c;读取宏是Lisp语言中都有的一种概念&#xff0c;所以可以通过任意一种Lisp语言的文档…

免费可视化工具如何提升智慧物流管理效率

在现代智慧物流中&#xff0c;免费可视化工具正扮演着越来越重要的角色。这些工具通过数据的可视化展示&#xff0c;使物流管理更加高效、透明和智能化。免费可视化工具可以将复杂的物流数据转换为直观的图表和图形&#xff0c;帮助管理者实时监控和分析物流运作情况&#xff0…

九浅一深Jemalloc5.3.0 -- ⑥浅*boot

目前市面上有不少分析Jemalloc老版本的博文&#xff0c;但最新版本5.3.0却少之又少。而且5.3.0的架构与5之前的版本有较大不同&#xff0c;本着“与时俱进”、“由浅入深”的宗旨&#xff0c;我将逐步分析最新release版本Jemalloc5.3.0的实现。 另外&#xff0c;单讲实现代码是…

第二证券:可转债基础知识?想玩可转债一定要搞懂的交易规则!

可转债&#xff0c;全称是“可转化公司债券”&#xff0c;是上市公司为了融资&#xff0c;向社会公众所发行的一种债券&#xff0c;具有股票和债券的双重特点&#xff0c;投资者可以选择按照发行时约定的价格将债券转化成公司一般股票&#xff0c;也可作为债券持有到期后收取本…

Load Tensor to local Nvidia GPU

0. 安装Nvidia驱动 ubuntu24.04的安装非常简单&#xff0c;在安装界面&#xff0c;选择为"图形化和其他硬件安装驱动"&#xff0c;重启后即有原版Nvidia驱动(如图Nvidia X xxx) 1.确定电脑上是否有NvidiaGPU且安装好Nvidia驱动 import torch print(torch.version…

机器学习 C++ 的opencv实现SVM图像二分类的训练 (二)【附源码】

本节讲机器学习 C 的opencv实现SVM图像二分类的训练&#xff0c;下节讲测试&#xff1a; 数据集合data内容如下&#xff1a; 下载地址为&#xff1a;https://download.csdn.net/download/hgaohr1021/89506900 #include <stdio.h> #include <time.h> #include…