【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.mfbz.cn/a/767931.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

64位Office API声明语句第120讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…

工厂模式之简单工厂模式

文章目录 工厂模式工厂模式分为工厂模式的角色简单工厂模式案例代码定义一个父类&#xff0c;三个子类定义简单工厂客户端使用输出结果 工厂模式 工厂模式属于创造型的模式&#xff0c;用于创建对象。 工厂模式分为 简单工厂模式&#xff1a;定义一个简单工厂类&#xff0c;根…

Vue3的模板语法插值表达式用法

在template中输入“5 3” &#xff0c;是没有运算能力的&#xff0c;只会把字符直接显示出来&#xff0c;代码如下&#xff1a; <template><view>这是demo</view><view>5 3</view><navigator open-type"navigateBack"><vi…

永劫无间国服延迟高、报错、卡顿的处理措施一览

永劫无间国服延迟高、报错、卡顿怎么办&#xff1f;快速解决办法分享 第一个办法&#xff1a;改善延迟 如果是一直遇到永劫无间国服延迟高、报错、卡顿的问题&#xff0c;重启游戏也不管用的话&#xff0c;那应该就是网络问题&#xff0c;玩家可以启动雷神&#xff0c;让其快速…

服了!DELETE 同一行记录也会造成死锁!!

1 问题背景 “哥们&#xff0c;又双叒叕写了个死锁&#xff0c;秀啊&#xff01;&#x1f60f;” 就算是经常写死锁的同学看到估计都会有点懵&#xff0c;两条一模一样的 DELETE 语句怎么会产生死锁呢&#xff1f; 2 MySQL 锁回顾 看到这里的靓仔肯定对 MySQL 的锁非常了解&…

红酒与建筑:品味历史与艺术的交汇

在时间的长河中&#xff0c;红酒与建筑都是人类智慧的结晶&#xff0c;它们各自承载着历史的厚重与艺术的韵味。当这两者交汇时&#xff0c;仿佛是一场穿越时空的对话&#xff0c;将我们带入一个既古老又现代、既深沉又温柔的世界。今天&#xff0c;就让我们一起走进这个奇妙的…

企业消费采购成本和员工体验如何实现“鱼和熊掌“的兼得?

有企业说企业消费采购成本和员工体验的关系好比是“鱼和熊掌”&#xff0c;无法兼得&#xff1f; 要想控制好成本就一定要加强管控&#xff0c;但是加强管控以后&#xff0c;就会很难让员工获得满意的体验度。如果不加以管控&#xff0c;员工自由度增加了&#xff0c;往往就很难…

为什么要在成像应用中使用图像采集卡?

达到最大产量是工业和工厂自动化的关键标准之一。提高传感器分辨率和帧速率有助于实现这一目标&#xff0c;但也使带宽达到极限&#xff0c;并提出了新的传输问题。当前高带宽接口(如10GigE、相机直接与PC连接和嵌入式系统)的实现促使成像应用的许多用户询问如何以最佳配置最优…

Day63 代码随想录打卡|回溯算法篇---电话号码的字母组合

题目&#xff08;leecode T17&#xff09;&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 方法&#xff1a;…

CCS方形低角度光源实现更均匀的照射

机器视觉系统中&#xff0c;光源设计作为图像成像效果的关键&#xff0c;今天的光源系列分享——FPQ3系列。 特点&#xff1a; ・从4个方向以低角度照射均匀扩射光的方型低角度光源。 ・实现比上一代产品2倍的高输出。白色和蓝色的亮度提高至2倍&#xff0c;红色的亮度提高至…

app单页下载页源码带管理后台

新版带后台管理APP应用下载页,自动识别安卓苹果下载页&#xff0c;带管理后台&#xff0c;内置带3套App下载模板带中文模板/英文模板随时切换。 app单页下载页源码带管理后台

保存到redis中的token乱码了

示图&#xff1a; 原因是缓存保存到redis需要序列化操作&#xff0c;没有序列化会出现这样的问题 序列化redis第一步&#xff1a; package com.abliner.test.configure.redis;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annota…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01 环境搭建验证码倒计时短信服务邮件服务验证码短信形式&#xff1a;邮件形式&#xff1a; 异常机制MD5参考 环境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…

西南交通大学【算法分析与设计实验3】

实验3.3 任务分配问题 实验目的 &#xff08;1&#xff09;理解穷举法典型算法的求解过程。 &#xff08;2&#xff09;学习穷举法的时间复杂度分析方法&#xff0c;并通过实验验证算法的执行效率。 &#xff08;3&#xff09;学会如何利用穷举法求解具体问题&#xff0c;了…

51单片机嵌入式开发:STC89C52操作8八段式数码管原理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 STC89C52操作8八段式数码管原理 1 8位数码管介绍1.1 8位数码管概述1.2 8位数码管原理1.3 应用场景 2 原理图图解2.1 74HC573原理2.2 74HC138原理2.3 数码管原理 3 数码管程序…

现代智能宠物喂食器方案定制

现代智能宠物喂食器不仅具备定时喂食功能&#xff0c;帮助宠物主人管理宠物的饮食时间和食量&#xff0c;还加入了录音功能和摄像头&#xff0c;使得宠物主人即使不在家也能与宠物保持互动&#xff0c;并实时监控宠物的状况。此外&#xff0c;一些产品还具备紧急预警功能&#…

Docker加速器配置指南:提升镜像下载速度的秘诀 加速安装Mysql Redis ES

在安装 Docker 镜像时&#xff0c;由于官方镜像下载速度较慢&#xff0c;我们可以使用阿里云的镜像加速器来提升下载速度。 使用阿里云镜像加速器 首先&#xff0c;找到并配置阿里云的镜像加速器。安装教程如下&#xff1a; 登录阿里云&#xff0c;进入容器镜像服务。直达链…

PyTorch之nn.Module与nn.functional用法区别

文章目录 1. nn.Module2. nn.functional2.1 基本用法2.2 常用函数 3. nn.Module 与 nn.functional3.1 主要区别3.2 具体样例&#xff1a;nn.ReLU() 与 F.relu() 参考资料 1. nn.Module 在PyTorch中&#xff0c;nn.Module 类扮演着核心角色&#xff0c;它是构建任何自定义神经网…

大数据------JavaWeb------JSP(完整知识点汇总)

JSP 定义 JSP&#xff08;Java Server Pages&#xff09;&#xff0c;即Java服务端页面。它是一种动态的网页技术&#xff0c;其中可以定义HTML、CSS、JS等静态内容&#xff0c;还可以定义Java代码的动态内容JSP HTML Java 说白了JSP就是一个页面&#xff0c;它既可以写HTML标…

【每日刷题】Day79

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