OpenCV相机标定与3D重建(35)计算两幅图像之间本质矩阵(Essential Matrix)的函数findEssentialMat()的使用

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

算法描述

从两幅图像中的对应点计算本质矩阵。
cv::findEssentialMat 是 OpenCV 库中用于计算两幅图像之间本质矩阵(Essential Matrix)的函数。本质矩阵描述了两个校准过的摄像机之间的相对旋转和平移,它对于立体视觉、运动结构恢复(Structure from Motion, SfM)和视觉里程计(Visual Odometry)等计算机视觉任务非常重要。

函数原型1


Mat cv::findEssentialMat	
(InputArray 	points1,InputArray 	points2,InputArray 	cameraMatrix,int 	method = RANSAC,double 	prob = 0.999,double 	threshold = 1.0,int 	maxIters = 1000,OutputArray 	mask = noArray() 
)		

参数1

  • 参数points1:来自第一幅图像的 N (N >= 5) 个2D点数组。点的坐标应该是浮点数(单精度或双精度)。
  • 参数points2:第二幅图像的点数组,与 points1 具有相同的大小和格式。
  • 参数cameraMatrix:相机内参矩阵 A = [ f x 0 c x 0 f y c y 0 0 1 ] A = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} A= fx000fy0cxcy1 。注意,此函数假设 points1 和 points2 是来自具有相同内参矩阵的相机的特征点。如果这个假设在你的应用场景中不成立,可以使用 undistortPoints 函数,并为两个相机设置 P=cv::NoArray(),以将图像点转换为适用于单位内参矩阵的归一化图像坐标。当传递这些坐标时,对于此参数应传递单位矩阵。
  • 参数method:计算本质矩阵的方法。
    • RANSAC:用于RANSAC算法。
    • LMEDS:用于最小中值法(LMedS)算法。
  • 参数 prob:仅用于RANSAC或LMedS方法的参数。它指定了估计矩阵正确的期望置信水平(概率)。
  • 参数threshold:仅用于RANSAC方法的参数。它是点到极线的最大距离(以像素为单位),超过该距离的点被认为是离群点,并不用于计算最终的本质矩阵。根据点定位的准确性、图像分辨率和图像噪声,它可以设置为1-3等。
  • 参数mask:输出数组,包含N个元素,每个元素对于离群点设置为0,对于其他点设置为1。该数组仅在RANSAC和LMedS方法中计算。
  • 参数maxIters:稳健方法的最大迭代次数。
    该函数基于五点算法求解器估算本质矩阵。[204] 中描述了该算法,[247] 也与此相关。极几何由以下方程描述:

[ p 2 ; 1 ] T K − T E K − 1 [ p 1 ; 1 ] = 0 [p_2; 1]^T K^{-T} E K^{-1} [p_1; 1] = 0 [p2;1]TKTEK1[p1;1]=0

其中E是本质矩阵,p1 和p2分别是第一幅和第二幅图像中的对应点。此函数的结果可以进一步传递给 decomposeEssentialMat 或 recoverPose 来恢复摄像机之间的相对位姿。

函数原型2


Mat cv::findEssentialMat	
(InputArray 	points1,InputArray 	points2,double 	focal = 1.0,Point2d 	pp = Point2d(0, 0),int 	method = RANSAC,double 	prob = 0.999,double 	threshold = 1.0,int 	maxIters = 1000,OutputArray 	mask = noArray() 
)		

参数2

  • 参数points1:来自第一幅图像的 N (N >= 5) 个2D点数组。点的坐标应该是浮点数(单精度或双精度)。
  • 参数points2:第二幅图像的点数组,与 points1 具有相同的大小和格式。
  • 参数focal:相机的焦距。注意,此函数假设 points1 和 points2 是来自具有相同焦距和主点的相机的特征点。
  • 参数pp:相机的主点。
  • 参数method:计算基本矩阵的方法。
    • RANSAC:用于RANSAC算法。
    • LMEDS:用于最小中值法(LMedS)算法。
  • 参数threshold:仅用于RANSAC方法的参数。它是点到极线的最大距离(以像素为单位),超过该距离的点被认为是离群点,并不用于计算最终的基本矩阵。根据点定位的准确性、图像分辨率和图像噪声,它可以设置为1-3等。
  • 参数prob:仅用于RANSAC或LMedS方法的参数。它指定了估计矩阵正确的期望置信水平(概率)。
  • 参数mask:输出数组,包含N个元素,每个元素对于离群点设置为0,对于其他点设置为1。该数组仅在RANSAC和LMedS方法中计算。
  • 参数maxIters:稳健方法的最大迭代次数。
    说明

这个函数与上述函数的不同之处在于它通过焦距和主点来计算相机内参矩阵

A = [ f 0 x p p 0 f y p p 0 0 1 ] A = \begin{bmatrix} f & 0 & x_{pp} \\ 0 & f & y_{pp} \\ 0 & 0 & 1 \end{bmatrix} A= f000f0xppypp1

代码示例


#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main( int argc, char** argv )
{// 创建虚拟的匹配点数据(假设我们有10对匹配点)vector< Point2f > points1 = { Point2f( 154.0f, 38.0f ),  Point2f( 285.0f, 176.0f ), Point2f( 279.0f, 238.0f ), Point2f( 276.0f, 284.0f ), Point2f( 273.0f, 342.0f ),Point2f( 267.0f, 397.0f ), Point2f( 262.0f, 446.0f ), Point2f( 254.0f, 495.0f ), Point2f( 246.0f, 545.0f ), Point2f( 234.0f, 592.0f ) };vector< Point2f > points2 = { Point2f( 149.0f, 49.0f ),  Point2f( 280.0f, 187.0f ), Point2f( 274.0f, 249.0f ), Point2f( 271.0f, 295.0f ), Point2f( 268.0f, 353.0f ),Point2f( 262.0f, 408.0f ), Point2f( 257.0f, 457.0f ), Point2f( 249.0f, 506.0f ), Point2f( 241.0f, 556.0f ), Point2f( 229.0f, 603.0f ) };// 相机内参矩阵 (示例值)Mat cameraMatrix = ( Mat_< double >( 3, 3 ) << 718.856, 0, 607.193, 0, 718.856, 185.216, 0, 0, 1 );// 定义输出的本质矩阵和掩码Mat essentialMatrix, mask;// 使用 RANSAC 方法计算本质矩阵essentialMatrix = findEssentialMat( points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, 1000, mask );// 打印结果cout << "Essential Matrix:\n" << essentialMatrix << endl;// 打印哪些点被认为是内点cout << "Inliers mask:\n";for ( size_t i = 0; i < mask.total(); ++i ){if ( mask.at< uchar >( i ) ){cout << "Point " << i + 1 << " is an inlier." << endl;}else{cout << "Point " << i + 1 << " is an outlier." << endl;}}// 如果需要,可以进一步分解本质矩阵或恢复姿态// decomposeEssentialMat(essentialMatrix, R1, R2, t);// recoverPose(essentialMatrix, points1, points2, cameraMatrix, R, t, mask);return 0;
}

运行结果

Essential Matrix:
[3.552514976490105e-09, -2.34328248364459e-07, -0.6437262524331034;2.332007722595955e-07, -1.168059907413519e-10, -0.2926029947621791;0.6437262524341074, 0.2926029926567176, 3.212847006212214e-09]
Inliers mask:
Point 1 is an inlier.
Point 2 is an inlier.
Point 3 is an inlier.
Point 4 is an inlier.
Point 5 is an inlier.
Point 6 is an inlier.
Point 7 is an inlier.
Point 8 is an inlier.
Point 9 is an inlier.
Point 10 is an inlier.

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

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

相关文章

Spring事务回滚

Transactional注解 Transactional作用&#xff1a;就是在当前这个方法执行开始之前来开启事务&#xff0c;方法执行完毕之后提交事务。如果在这个方法执行的过程当中出现了异常&#xff0c;就会进行事务的回滚操作。 Transactional注解&#xff1a;我们一般会在业务层当中来控制…

AT24C02学习笔记

看手册&#xff1a; AT24Cxx xx代表能写入xxK bit(xx K)/8 byte 内部写周期很关键&#xff0c;代表每一次页写或字节写结束后时间要大于5ms&#xff08;延时5ms确保完成写周期&#xff09;&#xff0c;否则时序会出错。 页写&#xff1a;型不同号每一页可能写入不同大小的…

Vite内网ip访问,两种配置方式和修改端口号教程

目录 问题 两种解决方式 结果 总结 preview.host preview.port 问题 使用vite运行项目的时候&#xff0c;控制台会只出现127.0.0.1&#xff08;localhost&#xff09;本地地址访问项目。不可以通过公司内网ip访问&#xff0c;其他团队成员无法访问&#xff0c;这是因为没…

Python基础语法知识——列表、字典、元组与集合

列表&#xff08;list&#xff09;、字典(dictionary)、元组(tuple)与集合(set)都可以看成存储数据的容器&#xff0c;但是前两者常用&#xff0c;后两者用得相对较少。 目录 1 列表&#xff08;list) 1.1列表入门 1 列表&#xff08;list) 1.1列表入门 class1["李白…

JVM调优实践篇

理论篇 1多功能养鱼塘&#xff0d;JVM内存 大鱼塘O&#xff08;可分配内存&#xff09;&#xff1a; JVM可以调度使用的总的内存数&#xff0c;这个数量受操作系统进程寻址范围、系统虚拟内存总数、系统物理内存总数、其他系统运行所占用的内存资源等因素的制约。 小池塘A&a…

EKF 自动匹配维度 MATLAB代码

该 M A T L A B MATLAB MATLAB代码实现了扩展卡尔曼滤波( E

C++第五六单元测试

1【单选题】在公有派生类的成员函数不能直接访问基类中继承来的某个成员&#xff0c;则该成员一定是基类中的&#xff08; C &#xff09;。&#xff08;2.0分&#xff09; A、公有成员B、保护成员C、私有成员D、保护成员或私有成员 注意从类外访问与从派生类中访问 2【单…

TDengine 新功能 VARBINARY 数据类型

1. 背景 VARBINARY 数据类型用于存储二进制数据&#xff0c;与 MySQL 中的 VARBINARY 数据类型功能相同&#xff0c;VARBINARY 数据类型长度可变&#xff0c;在创建表时指定最大字节长度&#xff0c;使用进按需分配存储&#xff0c;但不能超过建表时指定的最大值。 2. 功能说明…

rust windwos 两个edit框

use winapi::shared::minwindef::LOWORD; use windows::{core::*,Win32::{Foundation::*,Graphics::Gdi::{BeginPaint, EndPaint, PAINTSTRUCT},System::LibraryLoader::GetModuleHandleA,UI::WindowsAndMessaging::*,}, };// 两个全局静态变量&#xff0c;用于保存 Edit 控件的…

代码随想录Day51 99. 岛屿数量,99. 岛屿数量,100. 岛屿的最大面积。

1.岛屿数量深搜 卡码网题目链接&#xff08;ACM模式&#xff09;(opens new window) 题目描述&#xff1a; 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接…

邮箱手机号脱敏

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 输入框的脱敏&#xff0c;当输入的时候显示正常&#xff0c;失去焦点部分显示**** 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 脱敏可以封装 一下成为一个方法&#xff0c;挂…

C语言----变量与常量

目录 变量 变量的分类 常量 分类&#xff1a; 1. 字符型常量 2. 字符串常量 3. 整形常量 4. 浮点型常量 5. 指数常量 6. 标识常量 变量 概念&#xff1a;在程序运行中发生改变的量 定义格式&#xff1a; 存储类型(一般存储类型是可以省略的) 数据类型 变量名 aut…

SQLite本地数据库的简介和适用场景——集成SpringBoot的图文说明

前言&#xff1a;现在项目普遍使用的数据库都是MySQL&#xff0c;而有些项目实际上使用SQLite既足矣。在一些特定的项目中&#xff0c;要比MySQL更适用。 这一篇文章简单的介绍一下SQLite&#xff0c;对比MySQL的优缺点、以及适用的项目类型和集成SpringBoot。 1. SQLite 简介 …

线性代数行列式

目录 二阶与三阶行列式 二元线性方程组与二阶行列式 三阶行列式 全排列和对换 排列及其逆序数 对换 n阶行列式的定义 行列式的性质 二阶与三阶行列式 二元线性方程组与二阶行列式 若是采用消元法解x1、x2的话则得到以下式子 有二阶行列式的规律可得&#xff1a;分…

闲谭Scala(3)--使用IDEA开发Scala

1. 背景 广阔天地、大有作为的青年&#xff0c;怎么可能仅仅满足于命令行。 高端大气集成开发环境IDEA必须顶上&#xff0c;提高学习、工作效率。 开整。 2. 步骤 2.1 创建工程 打开IDEA&#xff0c;依次File-New-Project…&#xff0c;不好意思我的是中文版&#xff1a;…

http 请求总结get

关于get请求传递body的问题 错误代码 有400 , 415 等情况 <!doctype html><html lang"zh"><head><title>HTTP Status 400 – 错误的请求</title><style type"text/css">body {font-family:Tahoma,Arial,sans-seri…

CCF-GESP 等级考试 2023年12月认证C++五级真题解析

2023年12月真题 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 正确答案&#xff1a;C 考察知识点&#xff1a;算法 解析&#xff1a;fiboA 是很好理解的&#xff0c;但是执行效率不高&#xff0c;有的计算是重复的&#xff0c;导致效率低。 正确答案&#xf…

Vscode + gdbserver远程调试开发板指南:

本章目录 步骤环境准备网络配置vscode配置步骤 (全图示例)开发板配置开始调试注意: 每次断开之后&#xff0c;开发板都需要重新启动gdbserver才可调试。 参考链接: 步骤 环境准备 将交叉编译链路径加入$PATH变量&#xff1a;确保系统能够找到所需的工具。 export PATH$PATH:/p…

Docker【初识Docker】

目录 为什么会出现Docker这门技术喃&#xff1f; 应用开发和部署的困境 容器技术的先兆 Docker 的出现&#xff1a;简化容器化 Docker 技术的关键创新&#xff1a; Docker 的广泛应用和变革 什么是 Docker&#xff1f; Docker的历史 早期背景&#xff1a;容器化和虚拟化…

金融租赁系统的发展与全球化战略实施探讨

内容概要 金融租赁系统的演变并非一帆风顺&#xff0c;像一场跌宕起伏的电影。首先&#xff0c;咱们得看看它的起源及现状。随着经济的快速发展&#xff0c;金融租赁逐渐作为一种灵活的融资手段崭露头角。在中国市场中&#xff0c;企业对设备和技术更新换代的需求日益迫切&…