网站开发的测试计划/上海做网站优化
官网链接
从估计的本质矩阵和两幅图像中的对应点恢复相机之间的旋转和平移,使用光束法则进行检验。返回通过检验的内点数目。
#include <opencv2/calib3d.hpp>
int cv::recoverPose ( InputArray E,
InputArray points1,
InputArray points2,
InputArray cameraMatrix,
OutputArray R,
OutputArray t,
InputOutputArray mask = noArray()
)
int recoverPose( InputArray E, InputArray points1, InputArray points2,OutputArray R, OutputArray t, double focal = 1.0,Point2d pp = Point2d(0, 0), InputOutputArray mask = noArray() );
int recoverPose( InputArray E, InputArray points1, InputArray points2,InputArray cameraMatrix, OutputArray R, OutputArray t, double distanceThresh, InputOutputArray mask = noArray(),OutputArray triangulatedPoints = noArray());
E:已经求解出来的本质矩阵,它是3x3的矩阵;
points1:第一张图片中的点;
points2:第二张图片中的点;
cameraMatrix:相机内参矩阵,它是3x3的矩阵;
R:求解出来的两帧图片之间的旋转矩阵;
t:求解出来的两帧图片之间的平移向量;
focal:相机焦距;
pp:像素坐标的原点;
distanceThresh:点的距离阈值,用来滤出距离较远的点;
triangulatedPoints:通过三角化还原点;
官方例子
// Example. Estimation of fundamental matrix using the RANSAC algorithm
int point_count = 100;
vector<Point2f> points1(point_count);
vector<Point2f> points2(point_count);
// initialize the points here ...
for( int i = 0; i < point_count; i++ )
{points1[i] = ...;points2[i] = ...;
}
// cametra matrix with both focal lengths = 1, and principal point = (0, 0)
Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
Mat E, R, t, mask;
E = findEssentialMat(points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, mask);
recoverPose(E, points1, points2, cameraMatrix, R, t, mask);
**说明: **
1. 通过该函数求解出来的 R , t R,t R,t ,它表示的是points1到points2的变换,也就是 R 21 R_{21} R21 , t 21 t_{21} t21
2.该函数求解出来的 R 21 R_{21} R21 , t 21 t_{21} t21,已经是最合适已经通过内部的代码去掉了另外三种错误的解
3. cv::recoverPose()中points1和points2的输入顺序,必须也要和求本质矩阵时对函数cv::findEssentialMat()输入的顺序相同。
4. 使用方法,可以直接包含对应的头文件,也可以直接将函数的内部实现拷贝也可以自己实现(vins),如下:
int recoverPose( InputArray E, InputArray _points1, InputArray _points2, InputArray _cameraMatrix,OutputArray _R, OutputArray _t, InputOutputArray _mask){Mat points1, points2, cameraMatrix;_points1.getMat().convertTo(points1, CV_64F);_points2.getMat().convertTo(points2, CV_64F);_cameraMatrix.getMat().convertTo(cameraMatrix, CV_64F);int npoints = points1.checkVector(2);CV_Assert( npoints >= 0 && points2.checkVector(2) == npoints &&points1.type() == points2.type());CV_Assert(cameraMatrix.rows == 3 && cameraMatrix.cols == 3 && cameraMatrix.channels() == 1);if (points1.channels() > 1){points1 = points1.reshape(1, npoints);points2 = points2.reshape(1, npoints);}double fx = cameraMatrix.at<double>(0,0);double fy = cameraMatrix.at<double>(1,1);double cx = cameraMatrix.at<double>(0,2);double cy = cameraMatrix.at<double>(1,2);points1.col(0) = (points1.col(0) - cx) / fx;points2.col(0) = (points2.col(0) - cx) / fx;points1.col(1) = (points1.col(1) - cy) / fy;points2.col(1) = (points2.col(1) - cy) / fy;points1 = points1.t();points2 = points2.t();Mat R1, R2, t;decomposeEssentialMat(E, R1, R2, t);Mat P0 = Mat::eye(3, 4, R1.type());Mat P1(3, 4, R1.type()), P2(3, 4, R1.type()), P3(3, 4, R1.type()), P4(3, 4, R1.type());P1(Range::all(), Range(0, 3)) = R1 * 1.0; P1.col(3) = t * 1.0;P2(Range::all(), Range(0, 3)) = R2 * 1.0; P2.col(3) = t * 1.0;P3(Range::all(), Range(0, 3)) = R1 * 1.0; P3.col(3) = -t * 1.0;P4(Range::all(), Range(0, 3)) = R2 * 1.0; P4.col(3) = -t * 1.0;// Do the cheirality check.// Notice here a threshold dist is used to filter// out far away points (i.e. infinite points) since// there depth may vary between postive and negtive.double dist = 50.0;Mat Q;triangulatePoints(P0, P1, points1, points2, Q);Mat mask1 = Q.row(2).mul(Q.row(3)) > 0;Q.row(0) /= Q.row(3);Q.row(1) /= Q.row(3);Q.row(2) /= Q.row(3);Q.row(3) /= Q.row(3);mask1 = (Q.row(2) < dist) & mask1;Q = P1 * Q;mask1 = (Q.row(2) > 0) & mask1;mask1 = (Q.row(2) < dist) & mask1;triangulatePoints(P0, P2, points1, points2, Q);Mat mask2 = Q.row(2).mul(Q.row(3)) > 0;Q.row(0) /= Q.row(3);Q.row(1) /= Q.row(3);Q.row(2) /= Q.row(3);Q.row(3) /= Q.row(3);mask2 = (Q.row(2) < dist) & mask2;Q = P2 * Q;mask2 = (Q.row(2) > 0) & mask2;mask2 = (Q.row(2) < dist) & mask2;triangulatePoints(P0, P3, points1, points2, Q);Mat mask3 = Q.row(2).mul(Q.row(3)) > 0;Q.row(0) /= Q.row(3);Q.row(1) /= Q.row(3);Q.row(2) /= Q.row(3);Q.row(3) /= Q.row(3);mask3 = (Q.row(2) < dist) & mask3;Q = P3 * Q;mask3 = (Q.row(2) > 0) & mask3;mask3 = (Q.row(2) < dist) & mask3;triangulatePoints(P0, P4, points1, points2, Q);Mat mask4 = Q.row(2).mul(Q.row(3)) > 0;Q.row(0) /= Q.row(3);Q.row(1) /= Q.row(3);Q.row(2) /= Q.row(3);Q.row(3) /= Q.row(3);mask4 = (Q.row(2) < dist) & mask4;Q = P4 * Q;mask4 = (Q.row(2) > 0) & mask4;mask4 = (Q.row(2) < dist) & mask4;mask1 = mask1.t();mask2 = mask2.t();mask3 = mask3.t();mask4 = mask4.t();// If _mask is given, then use it to filter outliers.if (!_mask.empty()){Mat mask = _mask.getMat();CV_Assert(mask.size() == mask1.size());bitwise_and(mask, mask1, mask1);bitwise_and(mask, mask2, mask2);bitwise_and(mask, mask3, mask3);bitwise_and(mask, mask4, mask4);}if (_mask.empty() && _mask.needed()){_mask.create(mask1.size(), CV_8U);}CV_Assert(_R.needed() && _t.needed());_R.create(3, 3, R1.type());_t.create(3, 1, t.type());int good1 = countNonZero(mask1);int good2 = countNonZero(mask2);int good3 = countNonZero(mask3);int good4 = countNonZero(mask4);if (good1 >= good2 && good1 >= good3 && good1 >= good4){R1.copyTo(_R);t.copyTo(_t);if (_mask.needed()) mask1.copyTo(_mask);return good1;}else if (good2 >= good1 && good2 >= good3 && good2 >= good4){R2.copyTo(_R);t.copyTo(_t);if (_mask.needed()) mask2.copyTo(_mask);return good2;}else if (good3 >= good1 && good3 >= good2 && good3 >= good4){t = -t;R1.copyTo(_R);t.copyTo(_t);if (_mask.needed()) mask3.copyTo(_mask);return good3;}else{t = -t;R2.copyTo(_R);t.copyTo(_t);if (_mask.needed()) mask4.copyTo(_mask);return good4;}}int recoverPose( InputArray E, InputArray _points1, InputArray _points2, OutputArray _R,OutputArray _t, double focal, Point2d pp, InputOutputArray _mask){Mat cameraMatrix = (Mat_<double>(3,3) << focal, 0, pp.x, 0, focal, pp.y, 0, 0, 1);return cv::recoverPose(E, _points1, _points2, cameraMatrix, _R, _t, _mask);}
}
相关文章:

【Opencv】三维重建之cv::recoverPose()函数(1)
官网链接 从估计的本质矩阵和两幅图像中的对应点恢复相机之间的旋转和平移,使用光束法则进行检验。返回通过检验的内点数目。 #include <opencv2/calib3d.hpp>int cv::recoverPose ( InputArray E, InputArray points1, InputArray points2, InputArray …...

Perl兼容正则表达式函数-PHP8知识详解
在php8中有两类正则表达式函数,一类是perl兼容正则表达式函数,另一类是posix扩展正则表达式函数。二者区别不大,我们推荐使用Perl兼容正则表达式函数。 1、使用正则表达式对字符串进行匹配 用正则表达式对目标字符串进行匹配是正则表达式的主…...

Python处理空值NaN
fork_address_tempread_excel_column_to_list(./eqp_info.xls,Sheet1,车辆地址)for i in fork_address_temp:print(type(i))fork_address[0 if address nan else address for address in fork_address_temp]fork_address结果 <class float><class float><class…...

软件机器人助力交通运输局数据录入,实现高效管理
随着科技的迅速发展,许多传统的行业正在寻求通过科技创新优化工作流程、提升效率。在这样的大背景下,交通运输部门也开始注重引入科技手段改善工作流程。博为小帮软件机器人正逐步改变着交通运输局的工作方式。 软件机器人:交通管理的利器 博…...

时序分解 | MATLAB实现基于SGMD辛几何模态分解的信号分解分量可视化
时序分解 | MATLAB实现基于SGMD辛几何模态分解的信号分解分量可视化 目录 时序分解 | MATLAB实现基于SGMD辛几何模态分解的信号分解分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 SGMD分解算法(辛几何模态分解),分解结果可视…...

FinalShell报错:Swap file “.docker-compose.yml.swp“ already exists
FinalShell中编辑docker-compose.yml文件,保存时报错:Swap file ".docker-compose.yml.swp" already exists;报错信息截图如下: 问题原因:有人正在编辑docker-compose.yml文件或者上次编辑没有保存ÿ…...

卷积过程详细讲解
1:单通道卷积 以单通道卷积为例,输入为(1,5,5),分别表示1个通道,宽为5,高为5。假设卷积核大小为3x3,padding0,stride1。 卷积过程如下: 相应的卷积核不断…...

代码随想录第五十六天
代码随想录第五十六天 Leetcode 583. 两个字符串的删除操作Leetcode 72. 编辑距离 Leetcode 583. 两个字符串的删除操作 题目链接: 两个字符串的删除操作 自己的思路:想到了,但是初始化初始错了!!!! 思路1:直接动规五…...

.NET 最便捷的Log4Net日志记录器
最便捷的Log4Net使用方法 LOG4NET 配置日志记录器开始引用nuget LOG4NET 配置日志记录器 Apache log4net 库是一个帮助程序员将日志语句输出到各种的工具 的输出目标。log4net是优秀的Apachelog4j™框架的移植 Microsoft.NET 运行时。我们保持了与原始log4j相似的框架 同时利…...

深入探讨软件逆向工程:解密黑盒的奥秘
引言 逆向工程作为计算机科学领域中的一项关键技术,扮演着解密、漏洞分析、反病毒等诸多领域的重要角色。本文将深入探讨逆向工程的概念、应用领域以及一些常用的逆向工程技术。 什么是逆向工程? 逆向工程是指通过分析已有的程序或设备,推…...

利用tidevice+mysql+grafana实现ios性能测试
利用tidevicemysqlgrafana实现ios性能测试 1.什么是tidevice? tidevice是一个可以和ios设备进行通信的工具,提供以下功能: 截图获取手机信息ipa包的安装和卸载根据bundleID 启动和停止应用列出安装应用信息模拟Xcode运行XCTest,…...

内网安全:WMI协议与SMB协议横向移动
目录 网络拓扑图 网络环境说明 WMI协议 SMB协议 域内信息收集 WMI协议 - 横向移动 利用方式一:wmic命令 利用方式一:cscript 利用方式一:impacket SMB协议 - 横向移动 利用方式一:psexec 利用方式二:psexe…...

05-Numpy基础-用于数组的文件输入输出
np.save和np.load是读写磁盘数组数据的两个主要函数。默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为.npy的文件中的: 如果文件路径末尾没有扩展名.npy,则该扩展名会被自动加上。然后就可以通过np.load读取磁盘上的数组࿱…...

Docker微服务实战
文章目录 业务需求IDEA编写代码编写Dockerfile构建镜像运行容器网页端访问测试 业务需求 利用Docker部署应用服务,实现在网页端通过输入地址 ip:端口/hello/docker,页面显示hello docker ! IDEA编写代码 创建springboot项目 网上很多教程,此步骤省略……...

NLNet论文总结和代码实现
Non-local Neural Networks(非局部神经网络):使用自注意力机制捕获远程依赖。 论文: https://arxiv.org/pdf/1711.07971.pdf 源码: 长距离依赖关系,顾名思义,是要和远程建立关系,在l…...

数字 IC 设计职位经典笔/面试题(三)
共100道经典笔试、面试题目(文末可全领) 1. IC 设计中同步复位与异步复位的区别? 同步复位在时钟沿变化时,完成复位动作。异步复位不管时钟,只要复位信号满足条件,就完成复位动作。异步复位对复位信号要求…...

Matlab分割彩色图像
彩色图像 彩色图像除有亮度信息外,还包含有颜色信息。以最常见的RGB(红绿蓝)彩色空间为例来简要说明彩色图像: 彩色图像可按照颜色的数目来划分。例如,256色图像和真彩色图像(2的16次方=21677…...

[数据集][目标检测]垃圾目标检测数据集VOC格式14963张44类别
数据集格式:Pascal VOC格式(不包含分割的txt文件,仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数):14963 标注数量(xml文件个数):14963 标注类别数:44 标注类别名称:["toiletries","plastic utensi…...

MATLAB算法实战应用案例精讲-【深度学习】推荐系统模型DSSMDeepFM
目录 前言 DSSM 输入层 英文 中文 表示层 匹配层 优缺点 DeepFM模...

基于springboot的社区生活缴费系统/基于javaweb的水电缴费系统
摘 要 网络的广泛应用给生活带来了十分的便利。所以把社区生活缴费管理与现在网络相结合,利用java语言建设社区生活缴费系统,实现社区生活缴费管理的信息化。则对于进一步提高社区生活缴费管理发展,丰富社区生活缴费管理经验能起到不少的促进…...

Linux —— keepalived
简介 Keepalived 是一个用 C 语言编写的路由软件。这个项目的主要目标是为 Linux 系统和基于 Linux 的基础设施提供简单而强大的负载均衡和高可用性功能。 Keepalived 开源并且免费的软件。 Keepalived 的2大核心功能 1. loadbalance 负载均衡 LB:ipvs--》lvs软件…...

ubuntu安装pyenv
Pyenv是一种轻量级的Python版本管理工具,它可以让你在同一台机器上同时管理多个Python版本。这个工具对于开发者来说非常有用,因为在不同的项目中可能需要使用不同版本的Python。下面是在Ubuntu系统上安装pyenv,并配置环境变量的步骤…...

【Kubernetes】对外服务之 Ingress
目录 简介 Ingress 组成 ●ingress ●ingress-controller Ingress-Nginx 工作原理 部署 nginx-ingress-controller 1、部署ingress-controller Pod及相关资源 ingress 暴露服务的方式 ●方式一:DaemonSetHostNetworknodeSelector ●方式二:Dep…...

大数据项目实战(安装准备)
一,搭建大数据集群环境 1.1安装准备 1.1.1虚拟机安装与克隆 1.虚拟机的安装和设置以及启动虚拟机并安装操作系统(以下仅供参考) 安装一台虚拟机主机名为:hadoop01的虚拟机备用 VMware虚拟机安装Linux教程(超详细)_vmware安装…...

SAP ABAP基础语法-内表篇(二)
十一、使用 SPLIT 直接拆分到内表: DATA: BEGIN OF auth_data OCCURS 0,text(1024),END OF auth_data.STR SE39/SE39/SE01/SE10.SPLIT STR AT / INTO TABLE auth_data. 二十、CONDENSE 的用法: 把工作区的内的所有字段的值 赋给 字符串 DATA: BEGIN O…...

读SQL学习指南(第3版)笔记05_过滤
1. 不需要考虑排除任何列 1.1. 清除数据表中所有的内容 1.2. 暂存新数据仓库的数据 1.3. 向数据表中新添一列后 1.4. 修改数据表中的所有行 1.5. 检索消息队列表中的所有行 2. where子句 2.1. 可以在其中指定一个或多个过滤条件,用于限制SQL语句处理的行数 …...

防火墙组建双击热备后老是主备自动切换怎么处理?
环境: 2台主备防火墙 8.0.75 AF-2000-FH2130B-SC 核心交换机 H3C S6520-26Q-SI version 7.1.070, Release 6326 问题描述: 防火墙组建双击热备后老是主备自动切换怎么处理? 查看切换日志,本地故障值小于对端,经常自动切换导致eth3接口业务老是自动断开,切换频率,…...

SQL地址门牌排序,字典序转为数字序
页面有一批地址数据查询,结果字符排序默认是字典序的,所以造成了门牌3号在30号之前,影响用户体验; id, road_code, road_name, address_fullname, address_name 102 10086 人民一路 北江省南海市西湖区人民一路3号 3号 103 10086…...

DevExpress WinForms数据编辑器组件,提供丰富的数据输入样式!(二)
DevExpress WinForms超过80个高影响力的WinForms编辑器和多用途控件,从屏蔽数据输入和内置数据验证到HTML格式化,DevExpress数据编辑库提供了无与伦比的数据编辑选项,包括用于独立数据编辑或用于容器控件(如Grid, TreeList和Ribbon)的单元格。…...

HTML番外篇(五)-移动端适配
一、媒体查询 1.认识媒体查询 媒体查询是一种提供给开发者针对不同设备需求进行定制化开发的一个接口。 你可以根据设备的类型(比如屏幕设备、打印机设备)或者特定的特性(比如屏幕的宽度)来修改你的页面。 媒体查询的使用方式主要有三种:…...