OpenCV相机标定与3D重建(59)用于立体相机标定的函数stereoCalibrate()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

标定立体相机设置。此函数找到两个相机各自的内参以及两个相机之间的外参。
cv::stereoCalibrate 是 OpenCV 中用于立体相机标定的函数。它通过一组已知的3D点及其在两个相机中的对应2D投影,来估计两个相机之间的相对位置和方向(旋转矩阵R和平移向量T),同时还可以优化每个相机的内参矩阵和畸变系数。

函数原型

double cv::stereoCalibrate	
(InputArrayOfArrays 	objectPoints,InputArrayOfArrays 	imagePoints1,InputArrayOfArrays 	imagePoints2,InputOutputArray 	cameraMatrix1,InputOutputArray 	distCoeffs1,InputOutputArray 	cameraMatrix2,InputOutputArray 	distCoeffs2,Size 	imageSize,InputOutputArray 	R,InputOutputArray 	T,OutputArray 	E,OutputArray 	F,OutputArrayOfArrays 	rvecs,OutputArrayOfArrays 	tvecs,OutputArray 	perViewErrors,int 	flags = CALIB_FIX_INTRINSIC,TermCriteria 	criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) 
)		

参数

  • 参数objectPoints 校准图案点的向量的向量。结构与 calibrateCamera 中相同。对于每个图案视图,两个相机需要看到相同的物体点。因此,objectPoints.size()、imagePoints1.size() 和 imagePoints2.size() 需要相等,并且对于每个 i,objectPoints[i].size()、imagePoints1[i].size() 和 imagePoints2[i].size() 也需要相等。
  • 参数imagePoints1 第一个相机观测到的校准图案点投影的向量的向量。结构与 calibrateCamera 中相同。
  • 参数imagePoints2 第二个相机观测到的校准图案点投影的向量的向量。结构与 calibrateCamera 中相同。
  • 参数cameraMatrix1 第一个相机的输入/输出内参矩阵,与 calibrateCamera 中相同。对于立体情况,可以使用额外的标志,见下文。
  • 参数distCoeffs1 输入/输出畸变系数向量,与 calibrateCamera 中相同。
  • 参数cameraMatrix2 第二个相机的输入/输出内参矩阵。详见 cameraMatrix1 的描述。
  • 参数distCoeffs2 第二个相机的镜头畸变系数的输入/输出向量。详见 distCoeffs1 的描述。
  • 参数imageSize 仅用于初始化相机内参矩阵的图像尺寸。
  • 参数R 输出旋转矩阵。连同平移向量 T 一起,该矩阵将第一个相机坐标系中的点变换到第二个相机坐标系中的点。更技术性地说,R 和 T 的组合执行了从第一个相机坐标系到第二个相机坐标系的基底变换。由于其对偶性,这个组合等价于第一个相机相对于第二个相机坐标系的位置。
  • 参数T 输出平移向量,参见上述描述。
  • 参数E 输出本质矩阵。
  • 参数F 输出基础矩阵。
  • 参数rvecs 输出旋转向量(Rodrigues 表示)的向量,估计每个立体对中第一相机坐标系下的图案视图。具体来说,每个第 i 个旋转向量连同对应的第 i 个平移向量(见下一个输出参数描述),将校准图案从物体坐标空间变换到立体对中第一相机的相机坐标空间。更技术性地说,第 i 个旋转和平移向量的组合执行了从物体坐标空间到立体对中第一相机的相机坐标空间的基底变换。
  • 参数tvecs 输出平移向量的向量,估计每个图案视图,参见上一个输出参数(rvecs)的参数描述。
  • 参数perViewErrors 每个图案视图的 RMS 重投影误差的输出向量。
  • 参数flags 不同的标志,可能是零或以下值的组合:
    • CALIB_FIX_INTRINSIC 固定 cameraMatrix? 和 distCoeffs?,以便只估计 R、T、E 和 F 矩阵。
    • CALIB_USE_INTRINSIC_GUESS 根据指定的标志优化一些或全部的内参。初始值由用户提供。
    • CALIB_USE_EXTRINSIC_GUESS R 和 T 包含有效的初始值,这些值被进一步优化。否则,R 和 T 初始化为图案视图的中位数(每个维度分别处理)。
    • CALIB_FIX_PRINCIPAL_POINT 在优化过程中固定主点。
    • CALIB_FIX_FOCAL_LENGTH 固定 f y ( j ) f^{(j)}_y fy(j) f y ( j ) f^{(j)}_y fy(j)
    • CALIB_FIX_ASPECT_RATIO 优化 f y ( j ) f^{(j)}_y fy(j) ,固定比率 f x ( j ) / f y ( j ) f^{(j)}_x/f^{(j)}_y fx(j)/fy(j)
    • CALIB_SAME_FOCAL_LENGTH 强制 f x ( 0 ) = f x ( 1 ) f^{(0)}_x=f^{(1)}_x fx(0)=fx(1) f y ( 0 ) = f y ( 1 ) f^{(0)}_y=f^{(1)}_y fy(0)=fy(1)
    • CALIB_ZERO_TANGENT_DIST 将每个相机的切向畸变系数设为零并固定不变。
    • CALIB_FIX_K1,…, CALIB_FIX_K6 在优化过程中不改变相应的径向畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数;否则,将其设置为 0。
    • CALIB_RATIONAL_MODEL 启用系数 k4、k5 和 k6。为了提供向后兼容性,此额外标志应显式指定以使标定函数使用有理模型并返回8个系数。如果不设置此标志,函数计算并返回仅5个畸变系数。
    • CALIB_THIN_PRISM_MODEL 启用系数 s1、s2、s3 和 s4。为了提供向后兼容性,此额外标志应显式指定以使标定函数使用薄棱镜模型并返回12个系数。如果不设置此标志,函数计算并返回仅5个畸变系数。
    • CALIB_FIX_S1_S2_S3_S4 在优化过程中不改变薄棱镜畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的
      distCoeffs 矩阵中的系数;否则,将其设置为 0。
    • CALIB_TILTED_MODEL 启用系数 τX 和 τY。为了提供向后兼容性,此额外标志应显式指定以使标定函数使用倾斜传感器模型并返回14个系数。如果不设置此标志,函数计算并返回仅5个畸变系数。
  • CALIB_FIX_TAUX_TAUY 在优化过程中不改变倾斜传感器模型的系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数;否则,将其设置为 0。
  • criteria 迭代优化算法的终止条件。
    该函数估计了构成立体对的两个相机之间的变换。如果分别计算了一个物体相对于第一个相机和第二个相机的姿态 (R1, T1) 和 (R2, T2),并且对于一个立体相机,两个相机之间的相对位置和方向是固定的,那么这两个姿态肯定相互关联。这意味着,如果已知两个相机之间的相对位置和方向 (R, T),就可以在给定 (R1, T1) 的情况下计算 (R2, T2)。这就是该函数所做的。它计算 (R, T) 使得:

R 2 = R R 1 . R_2=R R_1. R2=RR1.
T 2 = R T 1 + T . T_2=R T_1 + T. T2=RT1+T.

因此,当给定了第一个相机坐标系中的3D点的坐标表示时,可以计算出该点在第二个相机坐标系中的坐标表示:
[ X 2 Y 2 Z 2 1 ] = [ R T 0 1 ] [ X 1 Y 1 Z 1 1 ] . \begin{bmatrix} X_2 \\ Y_2 \\ Z_2 \\ 1 \end{bmatrix} = \begin{bmatrix} R & T \\ 0 & 1 \end{bmatrix} \begin{bmatrix} X_1 \\ Y_1 \\ Z_1 \\ 1 \end{bmatrix}. X2Y2Z21 =[R0T1] X1Y1Z11 .

可选地,该函数还可以计算本质矩阵 E:

E = [ 0 − T 2 T 1 T 2 0 − T 0 − T 1 T 0 0 ] R E = \begin{bmatrix} 0 & -T_2 & T_1 \\ T_2 & 0 & -T_0 \\ -T_1 & T_0 & 0 \end{bmatrix} R E= 0T2T1T20T0T1T00 R

其中 Ti 是平移向量 T 的分量: T = [ T 0 , T 1 , T 2 ] T T=[T_0, T_1, T_2]^T T=[T0,T1,T2]T 。而且,该函数还可以计算基础矩阵 F:

F = c a m e r a M a t r i x 2 − T ⋅ E ⋅ c a m e r a M a t r i x 1 − 1 F = cameraMatrix2^{-T}\cdot E \cdot cameraMatrix1^{-1} F=cameraMatrix2TEcameraMatrix11

除了立体相关的信息外,该函数还可以对两个相机进行完整的标定。然而,由于参数空间的高维性和输入数据中的噪声,函数可能会偏离正确解。如果可以高精度地单独估计每个相机的内参(例如,使用 calibrateCamera),建议这样做并将 CALIB_FIX_INTRINSIC 标志传递给该函数,同时提供计算得到的内参。否则,如果所有参数一次性估计,限制某些参数是有意义的,例如传递 CALIB_SAME_FOCAL_LENGTH 和 CALIB_ZERO_TANGENT_DIST 标志,这通常是一个合理的假设。

类似于 calibrateCamera,该函数最小化来自两个相机所有可用视图的所有点的总重投影误差。函数返回最终的重投影误差值。

代码示例

#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>using namespace cv;
using namespace std;int main()
{// 假设我们有以下数据vector< vector< Point3f > > objectPoints;  // 物体坐标空间中的3D点数组vector< vector< Point2f > > imagePoints1;  // 第一个相机的图像点数组vector< vector< Point2f > > imagePoints2;  // 第二个相机的图像点数组// 检查是否已经填充了足够的点if ( objectPoints.empty() || imagePoints1.empty() || imagePoints2.empty() ){cerr << "Error: No calibration points provided." << endl;return -1;}// 确保所有数组大小一致if ( objectPoints.size() != imagePoints1.size() || objectPoints.size() != imagePoints2.size() ){cerr << "Error: The number of object points, image points from camera 1, and image points from camera 2 do not match." << endl;return -1;}// 相机内参矩阵 (假设有初始估计)Mat cameraMatrix1 = ( Mat_< double >( 3, 3 ) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1 );Mat cameraMatrix2 = ( Mat_< double >( 3, 3 ) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1 );// 畸变系数 (假设有初始估计)Mat distCoeffs1 = Mat::zeros( 8, 1, CV_64F );  // 8参数模型Mat distCoeffs2 = Mat::zeros( 8, 1, CV_64F );  // 8参数模型// 图像尺寸Size imageSize( 640, 480 );// 输出变量Mat R, T, E, F;vector< Mat > rvecs, tvecs;vector< float > perViewErrors;// 标定标志和终止条件int flags = CALIB_FIX_INTRINSIC;TermCriteria criteria( TermCriteria::COUNT + TermCriteria::EPS, 30, 1e-6 );// 执行立体相机标定double rms = stereoCalibrate( objectPoints,   // 输入的物体点imagePoints1,   // 第一个相机的图像点imagePoints2,   // 第二个相机的图像点cameraMatrix1,  // 第一个相机的内参矩阵distCoeffs1,    // 第一个相机的畸变系数cameraMatrix2,  // 第二个相机的内参矩阵distCoeffs2,    // 第二个相机的畸变系数imageSize,      // 图像尺寸R,              // 输出的旋转矩阵T,              // 输出的平移向量E,              // 输出的本质矩阵F,              // 输出的基础矩阵rvecs,          // 每个视图的旋转向量tvecs,          // 每个视图的平移向量perViewErrors,  // 每个视图的重投影误差flags,          // 标定标志criteria        // 终止条件);cout << "RMS re-projection error: " << rms << endl;cout << "Rotation Matrix:\n" << R << endl;cout << "Translation Vector:\n" << T << endl;cout << "Essential Matrix:\n" << E << endl;cout << "Fundamental Matrix:\n" << F << endl;// 可选:打印每个视图的重投影误差for ( size_t i = 0; i < perViewErrors.size(); ++i ){cout << "Reprojection error for view " << i << ": " << perViewErrors[ i ] << endl;}return 0;
}

运行结果

数据提供了就会有运行结果

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

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

相关文章

《Keras 3 神经网络紧凑型卷积转换器(Transformers)》

Keras 3 神经网络紧凑型卷积转换器&#xff08;Transformers&#xff09; 作者&#xff1a;Sayak Paul创建日期&#xff1a;2021/06/30最后修改时间&#xff1a;2023/08/07描述&#xff1a;用于高效图像分类的紧凑型卷积变压器。 &#xff08;i&#xff09; 此示例使用 Keras …

本地部署Web-Check网站检测与分析利器并实现远程访问实时监测

文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 本文我们将详细介绍如何在Ubuntu系统上使用Docker部署Web-Check&#xf…

Linux自学指南(学习路线大纲)

Linux入门与进阶指南 目录 第一部分 入门篇 第一章 Linux 系统 1.1 Unix&#xff1a;Linux的“祖师爷” 1.2 Linux 操作系统的诞生与发展历程 1.3 Linux 主要应用领域的归纳 1.4 开源社区的兴起 第二章 如何选择Linux发行版&#xff1f; 2.1 Debian GNU/Linux 2.2 Ubu…

常见好用的PHP CMS开源系统有哪些?

开源的系统&#xff0c;网站大家估计也见过很多&#xff0c;尤其是用PHP写的开源系统也很受用户们欢迎&#xff0c;这类系统通常以简单、使用、开源为优势&#xff0c;为用户提供更好的服务。以下就为大家介绍几个常见且好用的PHP CMS开源系统。欢迎补充&#xff01; 1、WordP…

Mybatis Plus 分页实现

目录 前言&#xff1a; 一、分页插件 1、添加配置类 &#xff08;1&#xff09;创建配置类方式: &#xff08;2&#xff09;启动类中配置分页插件方式(推荐): 2、测试 二、XML自定义分页 1、UserMapper中定义接口方法 2、UserMapper.xml中编写SQL ​编辑 3、测试 前…

玩转大语言模型——使用graphRAG+Ollama构建知识图谱

系列文章目录 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 文章目录 系列文章目录前言下载和安装用下载项目的方式下载并安装用pip方式下载并安装 生成知识图谱初始化文件夹修改模型配置修改知识库生成配置创…

[AUTOSAR通信篇] - AutoSAR通信架构

点击订阅专栏不迷路 文章目录 一、通信驱动二、通信硬件抽象三、通信服务3.1 CAN通信协议栈3.2 J1939通信协议栈3.3 LIN通信协议栈3.4 FlexRay通信协议栈3.5 ETH通信协议栈 返回总目录 先看一张图&#xff0c;这是整个BSW层可以提供的服务&#xff0c;今天我们重点来讲一讲这个…

mac配置 iTerm2 使用lrzsz与服务器传输文件

mac配置 1. 安装支持rz和sz命令的lrzsz brew install lrzsz2. 下载iterm2-send-zmodem.sh和iterm2-recv-zmodem.sh两个脚本 # 克隆仓库 git clone https://github.com/aikuyun/iterm2-zmodem ~/iterm2-zmodem# 进入到仓库目录 cd ~/iterm2-zmodem# 设置脚本文件可执行权限 c…

两级式三相光伏并网逆变器Matlab/Simulink仿真模型

忘记更新最经典的光伏并网仿真模型了&#xff0c;作为包含经典的MPPT和并网恒功率因素的双闭环控制模型&#xff0c;也是很多相关专业学生的入门研究内容&#xff0c;光伏并网模型三相的和单相都有。 其中三相光伏并网逆变器有大功率和小功率的两种&#xff0c;之前早在硕士期…

人工智能之深度学习_[2]-PyTorch入门

PyTorch 1.PyTorch简介 1.1 什么是PyTorch PyTorch是一个基于Python的科学计算包 PyTorch安装 pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simplePyTorch一个基于Python语言的深度学习框架&#xff0c;它将数据封装成张量&#xff08;Tensor&#xff09;来进行…

ASP.NET Core - 配置系统之配置添加

ASP.NET Core - 配置系统之配置添加 2. 配置添加 2. 配置添加 配置系统可以读取到配置文件中的信息&#xff0c;那必然有某个地方可以将配置文件添加到配置系统中。之前的文章中讲到 ASP.NET Core 入口文件中&#xff0c;builder(WebApplicationBuilder 对象) 中有一个 Config…

GIS大模型:交通领域方面的应用

文章目录 1. 实时交通流量预测&#xff1a;2. 动态信号灯控制&#xff1a;3. 交通流模式识别&#xff1a;4. 交通事故预警&#xff1a;5. 路径推荐与导航优化&#xff1a;6. 长期交通规划&#xff1a;7. 事件影响分析&#xff1a;8. 智能停车管理&#xff1a; 大模型在交通流量…

Redis复制(replica)

Redis主从复制 [Redis主从复制]&#xff08;replica&#xff09;是一个多Redis实例进行数据同步的过程&#xff0c;其中一个实例是主实例&#xff08;Master&#xff09;&#xff0c;其他实例是从实例&#xff08;Slave&#xff09;。主实例负责处理命令请求&#xff0c;而从实…

零基础构建最简单的 Tauri2.0 桌面项目 Star 88.4k!!!

目录 预安装环境 安装nodejs windows下安装 linux下安装 nodejs常遇问题 安装C环境 介绍 下载 安装 安装Rust语言 Tauri官网 安装 vscode 安装 rust 插件 安装 Tauri 插件 运行成果 预安装环境 安装nodejs windows下安装 NodeJs_安装及下载_哔哩哔哩_bilibi…

wproxy客户端安装,代理返回JSON

文章目录 一、wproxy基础信息二、使用wproxy客户端代理返回参数 一、wproxy基础信息 https://github.com/avwo/whistle github https://wproxy.org/whistle/quickstart.html 快速上手 Whistle 是基于 Node.JS 实现的操作简单、功能强大的跨平台抓包调试工具&#xff0c;可作为…

Ubuntu本地部署网站

目录 1.介绍 2.安装apache 3.网页升级 1.介绍 网站其实就相当于一个文件夹&#xff0c;用域名访问一个网页&#xff0c;就相当于访问了一台电脑的某一个文件夹&#xff0c;在网页中看见的视频&#xff0c;视频和音乐其实就是文件夹里面的文件。为什么网页看起来不像电脑文件夹…

jenkins-node节点配置

一.简述&#xff1a; Jenkins有一个很强大的功能&#xff1a; 即&#xff1a;支持分布式构建(jenkins配置中叫节点(node),也被称为slave)。分布式构建通常是用来吸收额外的负载。通过动态添加额外的机器应对构建作业中的高峰期&#xff0c;或在特定操作系统或环境运行特定的构建…

20.<Spring图书管理系统①(登录+添加图书)>

PS&#xff1a;关于接口定义 接口定义&#xff0c;通常由服务器提供方来定义。 1.路径&#xff1a;自己定义 2.参数&#xff1a;根据需求考虑&#xff0c;我们这个接口功能完成需要哪些信息。 3.返回结果&#xff1a;考虑我们能为对方提供什么。站在对方角度考虑。 我们使用到的…

Vue2+OpenLayers实现点位拖拽功能(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、代码实现 3.1、初始化变量 3.2、创建一个点 3.3、将点添加到地图上 3.4、实现点位拖拽 3.5、完整代码 四、Gitee源码 一、案例截图 可以随意拖拽点位到你想要的位置 二、安装OpenLayers库 npm install ol 三、代码实现…

计算机网络 (46)简单网络管理协议SNMP

前言 简单网络管理协议&#xff08;SNMP&#xff0c;Simple Network Management Protocol&#xff09;是一种用于在计算机网络中管理网络节点的标准协议。 一、概述 SNMP是基于TCP/IP五层协议中的应用层协议&#xff0c;它使网络管理员能够管理网络效能&#xff0c;发现并解决网…