OpenCV视觉分析之目标跟踪(11)计算两个图像之间的最佳变换矩阵函数findTransformECC的使用

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

算法描述

根据 ECC 标准 78找到两幅图像之间的几何变换(warp)。

该函数根据 ECC 标准 ([78]) 估计最优变换(warpMatrix),也就是说
warpMatrix = arg ⁡ max ⁡ W ECC ( templateImage ( x , y ) , inputImage ( x ′ , y ′ ) ) \texttt{warpMatrix} = \arg\max_{W} \texttt{ECC}(\texttt{templateImage}(x,y),\texttt{inputImage}(x',y')) warpMatrix=argWmaxECC(templateImage(x,y),inputImage(x,y))
此处
[ x ′ y ′ ] = W ⋅ [ x y 1 ] \begin{bmatrix} x' \\ y' \end{bmatrix} = W \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} [xy]=W xy1

(方程在单应性变换中使用齐次坐标时成立)。它返回最终的增强相关系数,即模板图像和最终变形的输入图像之间的相关系数。当给定一个 3×3 矩阵且 motionType 为 0、1 或 2 时,第三行被忽略。

与 findHomography 和 estimateRigidTransform 不同,findTransformECC 函数实现了一种基于区域的对齐方法,该方法基于强度相似性。本质上,该函数更新初始变换,该变换大致对齐图像。如果缺少这些信息,则使用单位变换(单位矩阵)作为初始化。注意,如果图像经历了强烈的位移/旋转,需要一个初始变换来大致对齐图像(例如,一个简单的欧氏变换/相似变换,允许图像显示大致相同的内容)。在第二幅图像中使用逆向变形,以使图像接近第一幅图像,即在使用 warpAffine 或 warpPerspective 时使用 WARP_INVERSE_MAP 标志。还可以参见 OpenCV 示例 image_alignment.cpp,该示例演示了该函数的使用。注意,如果算法不收敛,该函数会抛出异常。

函数原型

double cv::findTransformECC	
(InputArray 	templateImage,InputArray 	inputImage,InputOutputArray 	warpMatrix,int 	motionType,TermCriteria 	criteria,InputArray 	inputMask,int 	gaussFiltSize 
)		

参数

  • 参数 templateImage:单通道模板图像;CV_8U 或 CV_32F 数组。

  • 参数inputImage:单通道输入图像,该图像应使用最终的 warpMatrix 进行变形,以提供与 templateImage 类似的图像,类型与 templateImage 相同。

  • 参数warpMatrix:浮点型 2×3 或 3×3 映射矩阵(变形矩阵)。

  • 参数motionType:参数,指定运动类型:

    • MOTION_TRANSLATION 设置平移运动模型;warpMatrix 是 2×3 的矩阵,前 2×2 部分为单位矩阵,其余两个参数被估计。
    • MOTION_EUCLIDEAN 设置欧氏(刚性)变换作为运动模型;估计三个参数;warpMatrix 是 2×3 的矩阵。
    • MOTION_AFFINE 设置仿射运动模型(默认);估计六个参数;warpMatrix 是 2×3 的矩阵。
  • MOTION_HOMOGRAPHY 设置单应性作为运动模型;估计八个参数;warpMatrix 是 3×3 的矩阵。
    -参数criteria:参数,指定 ECC 算法的终止条件;criteria.epsilon 定义了两次迭代之间相关系数增量的阈值(负的 criteria.epsilon 使 -criteria.maxcount 成为唯一的终止条件)。默认值如上声明所示。

  • 参数inputMask:一个可选的掩码,用于指示 inputImage 的有效值。

  • 参数gaussFiltSize:一个可选值,指示高斯模糊滤波器的大小;(默认值:- 5)

代码示例


#include <opencv2/opencv.hpp>
#include <iostream>int main() {// 读取图像cv::Mat image1 = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/ecc1.png", cv::IMREAD_GRAYSCALE);cv::Mat image2 = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/ecc2.png", cv::IMREAD_GRAYSCALE);if (image1.empty() || image2.empty()) {std::cout << "Could not open or find the images" << std::endl;return -1;}// 定义变换矩阵cv::Mat warp_matrix = cv::Mat::eye(2, 3, CV_32F);// 设置终止条件const int MAX_ITER = 1000;const double EPSILON = 1e-5;cv::TermCriteria criteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, MAX_ITER, EPSILON);// 计算变换矩阵double ecc = cv::findTransformECC(image1, image2, warp_matrix, cv::MOTION_AFFINE, criteria);// 输出变换矩阵std::cout << "Transformation Matrix:\n" << warp_matrix << std::endl;// 使用计算出的变换矩阵对第二张图像进行变换cv::Mat aligned_image;cv::warpAffine(image2, aligned_image, warp_matrix, image1.size());// 显示原图和对齐后的图像cv::imshow("Original Image", image1);cv::imshow("Aligned Image", aligned_image);cv::imshow("Target Image", image2);cv::waitKey(0);return 0;
}

运行结果

原始图:
在这里插入图片描述
目标图

在这里插入图片描述
对齐的图
在这里插入图片描述

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

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

相关文章

【2024最新版Kotlin教程】Kotlin第一行代码系列第五课-类继承,抽象类,接口

【2024最新版Kotlin教程】Kotlin第一行代码系列第五课-类继承&#xff0c;抽象类&#xff0c;接口 为什么要有继承呢&#xff0c;现实中也是有继承的&#xff0c;对吧&#xff0c;你继承你爸的遗产&#xff0c;比如你爸建好了一个房子&#xff0c;儿子继承爸&#xff0c;就得了…

iOS用rime且导入自制输入方案

iPhone 16 的 cantonese 只能打传统汉字&#xff0c;没有繁简转换&#xff0c;m d sh d。考虑用「仓」输入法 [1] 使用 Rime 打字&#xff0c;且希望导入自制方案 [2]。 仓输入法有几种导入方案的方法&#xff0c;见 [3]&#xff0c;此处记录 wifi 上传法。准备工作&#xff1…

基于Zynq FPGA的雷龙SD NAND存储芯片性能测试

文章目录 前言一、SD NAND特征1.1 SD卡简介1.2 SD卡Block图 二、SD卡样片三、Zynq测试平台搭建3.1 测试流程3.2 SOC搭建 四、软件搭建五、测试结果六、总结 前言 随着嵌入式系统和物联网设备的快速发展&#xff0c;高效可靠的存储解决方案变得越来越重要。雷龙发展推出的SD NA…

【动态规划 数学】2745. 构造最长的新字符串|1607

本文涉及知识点 C动态规划 数学 LeetCode2745. 构造最长的新字符串 给你三个整数 x &#xff0c;y 和 z 。 这三个整数表示你有 x 个 “AA” 字符串&#xff0c;y 个 “BB” 字符串&#xff0c;和 z 个 “AB” 字符串。你需要选择这些字符串中的部分字符串&#xff08;可以全…

【Linux驱动开发】timer库下的jiffies时间戳和延时驱动编写

【Linux驱动开发】timer库下的jiffies时间戳和延时驱动编写 gitee地址&#xff1a; https://gitee.com/Mike_Zhou_Admin/Linux_Driver_Timestamp_Driver/更新以gitee为准 文章目录 timer库时间戳函数延时函数驱动代码应用测试附录&#xff1a;嵌入式Linux驱动开发基本步骤开发…

了解云计算工作负载保护的重要性及必要性

云计算de小白 云计算技术的快速发展使数据和应用程序安全成为一种关键需求&#xff0c;而不仅仅是一种偏好。随着越来越多的客户公司将业务迁移到云端&#xff0c;保护他们的云工作负载&#xff08;指所有部署的应用程序和服务&#xff09;变得越来越重要。云工作负载保护&…

C语言 循环高级

时间&#xff1a;2024.11.6 一、学习内容 1、无限循环 无限循环&#xff1a;循环永远停不下来 注意点&#xff1a;无限循环因为永远停不下来&#xff0c;所以下面不能再写其他的代码了 2、break 跳转控制语句&#xff1a; 在循环的过程中&#xff0c;跳到其他语句上执行 #…

易语言模拟真人动态生成鼠标滑动路径

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

CSS学习之Grid网格布局基本概念、容器属性

网格布局 网格布局&#xff08;Grid&#xff09;是将网页划分成一个个网格单元&#xff0c;可任意组合不同的网格&#xff0c;轻松实现各种布局效果&#xff0c;也是目前CSS中最强大布局方案&#xff0c;比Flex更强大。 基本概念 容器和项目 当一个 HTML 元素将 display 属性…

聊一聊Elasticsearch的索引的分片分配机制

1、什么是分片分配 分片分配是由ES主节点将索引分片移动到ES集群中各个节点上的过程。 该过程尽量保证&#xff0c;同一个索引的分片尽量分配到更多的节点上&#xff0c;以此来达到读写索引的时候可以利用更多硬件资源的效果。 在分配过程当中&#xff0c;也不能将某个主分片…

springboot的增删改查商城小实践(b to c)

首先准备一张表&#xff0c;根据业务去设计表 订单编号是参与业务的&#xff0c;他那订单编号里面是有特殊意义的&#xff0c;比如说像什么一些年月日什么的&#xff0c;一些用户的ID都在那编号里面呢&#xff1f;不能拿这种东西当主件啊 根据数据量去决定数据类型 价格需要注意…

Ubuntu 安装 RTL8811cu 网卡驱动

一、支持的网卡 RTL8811AU、RTL8811CU、RTL8821AU、RTL8821CU 二、下载驱动 github&#xff1a;https://github.com/brektrou/rtl8821CU 直接下载zip源码即可 三、安装驱动 sudo su -i #切换到root用户 apt-get update #更新安装源 apt-get install -y dkms …

解锁炎症和肿瘤免疫治疗新靶点:TREM1&TREM2

前 言 TREM家族属于细胞表面受体&#xff0c;介导调控炎症反应&#xff0c;现已成为癌症、神经退行性疾病以及炎症性疾病等多种疾病最有潜力的药物靶点。截至2023年6月&#xff0c;有5项FDA注册的临床前或临床试验正在进行中&#xff0c;有3项是TREM2在阿尔茨海默症&#xff…

【Unity】Unity拖拽在Android设备有延迟和卡顿问题的解决

一、介绍 在制作Block类游戏时&#xff0c;其核心的逻辑就是拖拽方块放入到地图中&#xff0c;这里最先想到的就是Unity的拖拽接口IDragHandler,然后通过 IPointerDownHandler, IPointerUpHandler 这两个接口判断按下和松手&#xff0c;具体的实现逻辑就是下面 public void On…

Postman断言与依赖接口测试详解!

在接口测试中&#xff0c;断言是不可或缺的一环。它不仅能够自动判断业务逻辑的正确性&#xff0c;还能确保接口的实际功能实现符合预期。Postman作为一款强大的接口测试工具&#xff0c;不仅支持发送HTTP请求和接收响应&#xff0c;还提供了丰富的断言功能&#xff0c;帮助测试…

NewStar CTF 2024 misc WP

decompress 压缩包套娃&#xff0c;一直解到最后一层&#xff0c;将文件提取出来 提示给出了一个正则&#xff0c;按照正则爆破密码&#xff0c;一共五位&#xff0c;第四位是数字 ^([a-z]){3}\d[a-z]$ 一共就五位数&#xff0c;直接ARCHPR爆破&#xff0c;得到密码 xtr4m&…

鸿蒙开发案例:七巧板

【1】引言&#xff08;完整代码在最后面&#xff09; 本文介绍的拖动七巧板游戏是一个简单的益智游戏&#xff0c;用户可以通过拖动和旋转不同形状的七巧板块来完成拼图任务。整个游戏使用鸿蒙Next框架开发&#xff0c;利用其强大的UI构建能力和数据响应机制&#xff0c;实现了…

C++_STL_xx_番外01_关于STL的总结(常见容器的总结;关联式容器分类及特点;二叉树、二叉搜索树、AVL树(平衡二叉搜索树)、B树、红黑树)

文章目录 1. 常用容器总结2. 关联式容器分类3. 二叉树、二叉搜索树、AVL树、B树、红黑树 1. 常用容器总结 针对常用容器的一些总结&#xff1a; 2. 关联式容器分类 关联式容器分为两大类&#xff1a; 基于红黑树的set和map&#xff1b;基于hash表的unorder_set和unorder_ma…

Django目录结构最佳实践

Django项目目录结构 项目目录结构配置文件引用修改创建自定义子应用方法修改自定义注册目录从apps目录开始 项目目录结构 └── backend # 后端项目目录&#xff08;项目名称&#xff09;├── __init__.py├── logs # 项目日志目录├── manage.py #…

AnytimeCL:难度加大,支持任意持续学习场景的新方案 | ECCV‘24

来源&#xff1a;晓飞的算法工程笔记 公众号&#xff0c;转载请注明出处 论文: Anytime Continual Learning for Open Vocabulary Classification 论文地址&#xff1a;https://arxiv.org/abs/2409.08518论文代码&#xff1a;https://github.com/jessemelpolio/AnytimeCL 创新…