OpenCV相机标定与3D重建(37)计算两幅图像之间单应性矩阵(Homography Matrix)的函数findHomography()的使用
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
找到两个平面之间的透视变换。
cv::findHomography 是 OpenCV 库中用于计算两幅图像之间单应性矩阵(Homography Matrix)的函数。单应性矩阵描述了两个平面之间的投影变换关系,它在计算机视觉中用于图像校正、拼接和增强现实等任务。
函数原型
Mat cv::findHomography
(InputArray srcPoints,InputArray dstPoints,int method = 0,double ransacReprojThreshold = 3,OutputArray mask = noArray(),const int maxIters = 2000,const double confidence = 0.995
)
参数
- 参数srcPoints:原平面中点的坐标,可以是类型为 CV_32FC2 的矩阵或 vector。
- 参数dstPoints:目标平面中点的坐标,可以是类型为 CV_32FC2 的矩阵或 vector。
- 参数method:用于计算单应性矩阵的方法。可能的方法包括:
- 0:常规方法,使用所有点,即最小二乘法。
- RANSAC:基于RANSAC的稳健方法。
- LMEDS:最小中值(Least-Median)稳健方法。
- RHO:基于PROSAC的稳健方法。
- ransacReprojThreshold:仅用于 RANSAC 和 RHO 方法。这是允许的最大重投影误差,用于将一对点视为内点。也就是说,如果
∥ dstPoints i − convertPointsHomogeneous ( H ⋅ srcPoints i ) ∥ 2 > ransacReprojThreshold \| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} \cdot \texttt{srcPoints} _i) \|_2 > \texttt{ransacReprojThreshold} ∥dstPointsi−convertPointsHomogeneous(H⋅srcPointsi)∥2>ransacReprojThreshold
则认为点 i 是离群点。如果 srcPoints 和 dstPoints 以像素为单位测量,则通常将此参数设置在1到10之间是有意义的。 - 参数mask:由稳健方法(如 RANSAC 或 LMEDS)设置的可选输出掩码。注意输入掩码值被忽略。
- 参数maxIters:RANSAC的最大迭代次数。
- 参数confidence:置信水平,介于0和1之间。
该函数找到并返回源平面和目标平面之间的透视变换矩阵 H H H
s i [ x i ′ y i ′ 1 ] ∼ H [ x i y i 1 ] s_i \begin{bmatrix} x'_i \\ y'_i \\ 1 \end{bmatrix} \sim H \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} si xi′yi′1 ∼H xiyi1
从而最小化反投影误差:
∑ i ( x i ′ − ( h 11 x i + h 12 y i + h 13 ) h 31 x i + h 32 y i + h 33 ) 2 + ( y i ′ − ( h 21 x i + h 22 y i + h 23 ) h 31 x i + h 32 y i + h 33 ) 2 \sum_i \left( \frac{x'_i - (h_{11}x_i + h_{12}y_i + h_{13})}{h_{31}x_i + h_{32}y_i + h_{33}} \right)^2 + \left( \frac{y'_i - (h_{21}x_i + h_{22}y_i + h_{23})}{h_{31}x_i + h_{32}y_i + h_{33}} \right)^2 i∑(h31xi+h32yi+h33xi′−(h11xi+h12yi+h13))2+(h31xi+h32yi+h33yi′−(h21xi+h22yi+h23))2
如果 method 参数设置为默认值 0,则函数使用所有点对通过简单的最小二乘方案计算初始单应性估计。
然而,如果并非所有的点对(srcPoints_i, dstPoints_i)都符合刚性的透视变换(即存在一些离群点),这个初始估计将会较差。在这种情况下,你可以使用三种稳健方法之一。RANSAC、LMEDS 和 RHO 方法尝试许多不同的随机子集(每次四个点对,共线点对被丢弃),使用这个子集和简单的最小二乘算法估计单应性矩阵,然后计算所估计单应性的质量/优度(对于RANSAC来说是内点的数量,对于LMEDS来说是最小中值重投影误差)。最佳子集随后用于生成单应性矩阵的初始估计和内点/离群点的掩码。
无论是否使用稳健方法,计算出的单应性矩阵都会进一步优化(在稳健方法的情况下仅使用内点),以Levenberg-Marquardt方法减少重投影误差。
RANSAC 和 RHO 方法可以处理几乎任何比例的离群点,但需要一个阈值来区分内点和离群点。LMEDS 方法不需要任何阈值,但只有当内点超过50%时才能正确工作。最后,如果没有离群点且噪声较小,使用默认方法(method=0)。
该函数用于找到初始的内部和外部矩阵。单应性矩阵确定至一个尺度。因此,它被标准化以使 h 33 = 1 h_{33}=1 h33=1。需要注意的是,每当无法估计 H 矩阵时,将返回一个空矩阵。
代码示例
#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main( int argc, char** argv )
{// 创建虚拟的匹配点数据(假设我们有4对匹配点)vector< Point2f > srcPoints = { Point2f( 56.0f, 65.0f ), Point2f( 368.0f, 52.0f ), Point2f( 28.0f, 387.0f ), Point2f( 389.0f, 390.0f ) };vector< Point2f > dstPoints = { Point2f( 0.0f, 0.0f ), Point2f( 300.0f, 0.0f ), Point2f( 0.0f, 300.0f ), Point2f( 300.0f, 300.0f ) };// 定义输出的单应性矩阵和掩码Mat homographyMatrix, mask;// 使用 RANSAC 方法计算单应性矩阵homographyMatrix = findHomography( srcPoints, dstPoints,RANSAC, // 使用RANSAC方法3.0, // 点到投影模型的最大重投影误差mask, // 输出掩码2000, // 最大迭代次数0.995 ); // 置信水平// 打印结果cout << "Homography Matrix:\n" << homographyMatrix << 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;}}return 0;
}
运行结果
Homography Matrix:
[1.055873761296419, 0.09181510967794945, -65.09691276166618;0.04690100493754324, 1.125624118501043, -75.79202397907012;0.0001832514481695185, 0.0005133370013304123, 0.9999999999999999]
Inliers mask:
Point 1 is an inlier.
Point 2 is an inlier.
Point 3 is an inlier.
Point 4 is an inlier.
相关文章:
OpenCV相机标定与3D重建(37)计算两幅图像之间单应性矩阵(Homography Matrix)的函数findHomography()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 找到两个平面之间的透视变换。 cv::findHomography 是 OpenCV 库中用于计算两幅图像之间单应性矩阵(Homography Matrix)的…...
Nacos配置管理+共享配置、配置热更新
1. 什么是配置管理? Nacos 配置管理是一个集中管理配置的工具。 它把微服务的配置集中存放,方便管理。可以动态更新配置,配置变了,微服务能马上知道并更新,不用重启。还能进行版本控制,记录配置的历史版本方便回滚。…...
asp.net core系统记录当前在线人数
实时记录当前在线人数,登录后保持120秒在线状态,在线状态保存在缓存中,采用滑动过期,在120秒内请求了系统,自动续活120秒;超过时间则移除用户在线状态; 需要在登录过滤器标记用户在线状态需要排…...
秒杀场景的设计思考
秒杀场景的设计思考 在学习Redis的之后,一个绕不开的话题就是秒杀系统的设计。本文将从下面👇🏻几个方面展开一下个人简单的理解: 秒杀场景的介绍设计的核心思路怎么限流、削峰、异步planB总结 秒杀场景的介绍 秒杀场景是…...
快速掌握Haproxy原理架构
文章目录 一、原理架构二、无负载均衡三、四层负载均衡的工作流程四、七层负载均衡工作流程五、基础属性mode 属性retries 属性maxconn 属性clitimeout 属性servtimeout 属性states uri 属性 一、原理架构 四层tcp代理:Haproxy仅在客户端和服务器之间双向转发流量&…...
基于Centos7.X系统端口占用处理
1、查看当前端口占用情况 使用 netstat 查看系统中占用的端口和相关的进程。 netstat -tuln 或者 ss -tnl 选项解释: -t 显示 TCP 连接-u 显示 UDP 连接-l 显示监听的端口-n 以数字形式显示端口号和 IP 2、具体进程的pid netstat -anp | grep <port_numb…...
MySQL的索引失效的原因有那些
1. 数据类型不匹配 详细说明:MySQL在比较不同数据类型的值时,可能会尝试进行隐式转换。如果这种转换导致了复杂度增加或无法直接利用索引,则会导致索引失效。 实例与解决方案: -- 错误示例:数据类型不匹配 select *…...
Java重要面试名词整理(十):Kafka
文章目录 Kafka简介相关概念Kraft集群 Kafka收发消息梳理客户端工作机制消费者分组消费机制生产者拦截器机制消息序列化机制消息分区路由机制生产者消息缓存机制发送应答机制生产者消息幂等性生产者消息事务 Kafka集群架构设计-Kafka的Zookeeper元数据梳理Leader Partition选举…...
内置ALC的前置放大器D2538A/D3308
一、概述 D2538A/D3308是芯谷科技推出的带有ALC(自动电平控制)的前置音频放大器芯片,最初产品为单声道/立体声收录机及盒式录音机而开发,作为录音/回放的磁头放大器使用;由于产品的高增益、低噪声及ALC外部可调的特性&…...
04-微服务02
我们将黑马商城拆分为5个微服务: 用户服务 商品服务 购物车服务 交易服务 支付服务 由于每个微服务都有不同的地址或端口,相信大家在与前端联调的时候发现了一些问题: 请求不同数据时要访问不同的入口,需要维护多个入口地址…...
Java中的this关键字详解:深入理解与应用
目录 一、this关键字的基本概念 二、this指代当前对象 示例: 三、this区分成员变量与方法参数 示例: 四、使用this()调用构造方法 示例: 五、使用this传递当前对象 示例: 六、this的其他注意事项输出结果: …...
2、C#基于.net framework的应用开发实战编程 - 设计(二、四) - 编程手把手系列文章...
二、设计; 二.四、制定设计规范; 编码规范在软件编程里起到了非常重要的作用,主要是让代码更加的规范化,更加的简洁,更加的漂亮,更加的能够面向对象显示。 以前那个系列就有发布C#的编码规范的文…...
设置首选网络类型以及调用Android框架层的隐藏API
在Android SDK中提供的framework.jar是阉割版本的,比如有些类标记为hide,这些类不会被打包到这个jar中,而有些只是类中的某个方法或或属性被标记为hide,则这些类或属性会被打包到framework.jar,但是我们无法调用&#…...
“Gold-YOLO:基于聚合与分发机制的高效目标检测新范式”
🏡作者主页:点击! 🤖编程探索专栏:点击! ⏰️创作时间:2024年12月26日8点00分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文源地址(有视频…...
神经网络-AlexNet
AlexNet是在2012年的ImageNet竞赛后,整理发表的文章,也是对CNN网络的衍生。 网络结构 AlexNet网络结构如下图所示,网络分为了上下两部分,对应两个不同的GPU训练,可以更好的利用GPU算力。只有在特殊的网络层后&#x…...
Hutool 发送 HTTP 请求的几种常见写法
最简单的 GET 请求: String result HttpUtil.get("https://www.baidu.com");带参数的 GET 请求: // 方法1: 直接拼接URL参数 String result HttpUtil.get("https://www.baidu.com?name张三&age18");// 方法2: 使用 HashMap…...
【Linux】进度条
本文中,我们来写一个进度条。 本文大纲: 写一个命令行版的进度条。 1.回车换行 2.缓冲区问题(本文不深究) 2.1测试代码 3.写一个什么样的进度条? version1 version2 回车换行 这俩不是一个概念&…...
【zookeeper核心源码解析】第四课:客户端与服务端读写的io核心流程
系列文章目录 【zookeeper核心源码解析】第一课:zk启动类核心流程序列图 【zookeeper核心源码解析】第二课:俯瞰QuorumPeer启动核心流程,实现选举关键流程 【zookeeper核心源码解析】第三课:leader与follower何时开始同步&#…...
强化学习蘑菇书笔记
绪论 强化学习就是一个智能体在一个不确定的环境中最大化它的奖励。智能体在一个环境中获取某个状态后,做一个动作,也称为决策,在环境中执行这个决策以后,会有一个奖励。尽可能多地获得更多的奖励。 强化学习概述 强化学习与监…...
《机器学习》——线性回归模型
文章目录 线性回归模型简介一元线性回归模型多元线性回归模型误差项分析一元线性模型实例完整代码 多元线性模型实例完整代码 线性回归模型简介 线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。 相关关系&…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!
多连接 BLE 怎么设计服务不会乱?分层思维来救场! 作者按: 你是不是也遇到过 BLE 多连接时,调试现场像网吧“掉线风暴”? 温度传感器连上了,心率带丢了;一边 OTA 更新,一边通知卡壳。…...
el-amap-bezier-curve运用及线弧度设置
文章目录 简介示例线弧度属性主要弧度相关属性其他相关样式属性完整示例链接简介 el-amap-bezier-curve 是 Vue-Amap 组件库中的一个组件,用于在 高德地图 上绘制贝塞尔曲线。 基本用法属性path定义曲线的路径,可以是多个弧线段的组合。stroke-weight线条的宽度。stroke…...
Oracle实用参考(13)——Oracle for Linux物理DG环境搭建(2)
13.2. Oracle for Linux物理DG环境搭建 Oracle 数据库的DataGuard技术方案,业界也称为DG,其在数据库高可用、容灾及负载分离等方面,都有着非常广泛的应用,对此,前面相关章节已做过较为详尽的讲解,此处不再赘述。 需要说明的是, DG方案又分为物理DG和逻辑DG,两者的搭建…...
