OpenCV11-图像的模版匹配

OpenCV11-图像的模版匹配

    • 图像的模版匹配


图像的模版匹配

前面通过图像直方图反向投影的方式在图像中寻找模版图像,由于直方图不能直接反映图像的纹理,因此,如果两幅不同的模版图像具有相同的直方图分布特性,那么在同一幅图中对着两幅模版图像的直方图进行反向投影,最终结果将不具有参考意义。

在图像中寻找模版图像时,可以直接通过比较图像像素的形式来搜索是否存在相同的内容,这种通过比较像素灰度值来寻找相同内容的方法称作图像的模版匹配。

OpenCV中提供了用于图像模版匹配的函数matchTemplate能够实现模版匹配过程中图像与模版相似性的计算:

void matchTemplate(InputArray image,   // 原图 CV_8U或者CV_32FInputArray templ,   // 模板图OutputArray result, // 输出图像 CV_32Fint method, // 模板匹配方法标志InputArray mask = noArray() // 匹配模板的掩码,通常情况下不使用,仅在 TM_SQDIFF和 TM_CCORR_NOrMED两种匹配方法中使用
);

第三个参数为相似性矩阵,滑动窗口与模板的相似性系数存放在滑动窗口左上角第一个像素出,因此输出的相似性矩阵尺寸小于原始图像的尺寸,如果原始图像尺寸为 W × H W \times H W×H ,模板图像尺寸为 w × h w \times h w×h ,那么相似性矩阵尺寸为 ( W − w + 1 ) × ( H − h + 1 ) (W-w+1) \times (H-h+1) (Ww+1)×(Hh+1) 。此外,无论输入的是彩色图像还是灰度图像,函数输出结果都是单通道矩阵。

第4个参数是滑动窗口与模板匹配方法标志也称作相似性系数。

enum TemplateMatchModes {// 平方差匹配法TM_SQDIFF        = 0,// 归一化平方差匹配法TM_SQDIFF_NORMED = 1,// 相关匹配法TM_CCORR         = 2,// 归一化相关匹配法TM_CCORR_NORMED  = 3,// 系数匹配法TM_CCOEFF        = 4,// 归一化相关系数匹配法TM_CCOEFF_NORMED = 5
};

相似性系数公式:method公式计算方法

下面公式中, T T T 表示模版图像, I I I 表示原始图像。

0.TM_SQDIFF:两者匹配程度越低,计算数值越大。

R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) − I ( x + x ′ , y + y ′ ) ) 2 R ( x , y ) = ∑ x ′ , y ′ ( ( T ( x ′ , y ′ ) − I ( x + x ′ , y + y ′ ) ) ⋅ M ( x ′ , y ′ ) ) 2 R(x,y) = \sum_{x',y'}(T(x', y') - I(x+x', y+y'))^2 \\ R(x,y) = \sum_{x',y'}((T(x', y') - I(x+x', y+y')) \cdot M(x',y'))^2 \\ R(x,y)=x,y(T(x,y)I(x+x,y+y))2R(x,y)=x,y((T(x,y)I(x+x,y+y))M(x,y))2

1.TM_SQDIFF_NORMED:两者匹配程度越低,计算数值越大。
R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) − I ( x + x ′ , y + y ′ ) ) 2 ∑ x ′ , y ′ T ( x ′ , y ′ ) 2 ⋅ ∑ x ′ , y ′ I ( x + x ′ , y + y ′ ) 2 R ( x , y ) = ∑ x ′ , y ′ ( ( T ( x ′ , y ′ ) − I ( x + x ′ , y + y ′ ) ) ⋅ M ( x ′ , y ′ ) ) 2 ∑ x ′ , y ′ ( T ( x ′ , y ′ ) ⋅ M ( x ′ , y ′ ) ) 2 ⋅ ∑ x ′ , y ′ ( I ( x + x ′ , y + y ′ ) ⋅ M ( x ′ , y ′ ) ) 2 R(x,y) = \frac{\sum_{x',y'}(T(x', y') - I(x+x', y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 · \sum_{x',y'}I(x+x',y+y')^2}} \\ R(x,y) = \frac{\sum_{x',y'}((T(x', y') - I(x+x', y+y')) \cdot M(x',y'))^2}{\sqrt{\sum_{x',y'}(T(x',y') \cdot M(x',y'))^2 · \sum_{x',y'}(I(x+x',y+y') \cdot M(x',y'))^2}} \\ R(x,y)=x,yT(x,y)2x,yI(x+x,y+y)2 x,y(T(x,y)I(x+x,y+y))2R(x,y)=x,y(T(x,y)M(x,y))2x,y(I(x+x,y+y)M(x,y))2 x,y((T(x,y)I(x+x,y+y))M(x,y))2
2.TM_CCORR:数值越大匹配效果越好,0表示最坏匹配结果。
R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) ⋅ I ( x + x ′ , y + y ′ ) ) R ( x , y ) = ∑ x ′ , y ′ ( ( T ( x ′ , y ′ ) ⋅ I ( x + x ′ , y + y ′ ) ) ⋅ M ( x ′ , y ′ ) 2 ) R(x,y) = \sum_{x',y'}(T(x', y') \cdot I(x+x', y+y')) \\ R(x,y) = \sum_{x',y'}((T(x', y') \cdot I(x+x', y+y')) \cdot M(x',y')^2) \\ R(x,y)=x,y(T(x,y)I(x+x,y+y))R(x,y)=x,y((T(x,y)I(x+x,y+y))M(x,y)2)
3.TM_CCORR_NORMED:完全匹配时结果为1,完全不匹配结果为0
R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) ⋅ I ( x + x ′ , y + y ′ ) ) ∑ x ′ , y ′ T ( x ′ , y ′ ) 2 ⋅ ∑ x ′ , y ′ I ( x + x ′ , y + y ′ ) 2 R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) ⋅ I ( x + x ′ , y + y ′ ) ⋅ M ( x ′ , y ′ ) 2 ) ∑ x ′ , y ′ ( T ( x ′ , y ′ ) ⋅ M ( x ′ , y ′ ) ) 2 ⋅ ∑ x ′ , y ′ ( I ( x + x ′ , y + y ′ ) ⋅ M ( x ′ , y ′ ) ) 2 R(x,y) = \frac{\sum_{x',y'}(T(x', y') \cdot I(x+x', y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'}I(x+x',y+y')^2}} \\ R(x,y) = \frac{\sum_{x',y'}(T(x', y') \cdot I(x+x', y+y') \cdot M(x',y')^2)}{\sqrt{\sum_{x',y'}(T(x',y') \cdot M(x',y'))^2 \cdot \sum_{x',y'}(I(x+x',y+y') \cdot M(x',y'))^2}} \\ R(x,y)=x,yT(x,y)2x,yI(x+x,y+y)2 x,y(T(x,y)I(x+x,y+y))R(x,y)=x,y(T(x,y)M(x,y))2x,y(I(x+x,y+y)M(x,y))2 x,y(T(x,y)I(x+x,y+y)M(x,y)2)
4.TM_CCOEFF:这种方法采用相关匹配法对模版减去均值的结果和原始图像减去均值的结果进行匹配,可以很好地解决模版图像和原始图像之间由于亮度不同而产生的影响。匹配程度越高数值越大,匹配程度越低数值越小,结果可以为负值。
R ( x , y ) = ∑ x ′ , y ′ ( T ′ ( x ′ , y ′ ) ⋅ I ′ ( x + x ′ , y + y ′ ) ) 其中 { T ′ ( x ′ , y ′ ) = T ( x ′ , y ′ ) − 1 w ⋅ h ∑ x ′ ′ , y ′ ′ T ( x ′ ′ , y ′ ′ ) I ′ ( x ′ , y ′ ) = I ( x + x ′ , y + y ′ ) − 1 w ⋅ h ∑ x ′ ′ , y ′ ′ I ( x + x ′ ′ , y + y ′ ′ ) R(x,y) = \sum_{x',y'}(T'(x', y') \cdot I'(x+x', y+y')) \\ 其中\left\{ \begin{array}{ll} T'(x',y') = T(x',y') - \frac{1}{w \cdot h}\sum_{x'',y''}T(x'',y'') \\ I'(x',y') = I(x+x',y+y') - \frac{1}{w \cdot h} \sum_{x'',y''}I(x+x'',y+y'') \\ \end{array} \right. R(x,y)=x,y(T(x,y)I(x+x,y+y))其中{T(x,y)=T(x,y)wh1x′′,y′′T(x′′,y′′)I(x,y)=I(x+x,y+y)wh1x′′,y′′I(x+x′′,y+y′′)
5.TM_CCOEFF_NORMED:归一化到1~-1之间,完全匹配数值为1,完全不匹配数值为-1。
R ( x , y ) = ∑ x ′ , y ′ ( T ′ ( x ′ , y ′ ) ⋅ I ′ ( x + x ′ , y + y ′ ) ) ∑ x ′ , y ′ T ′ ( x ′ , y ′ ) 2 ⋅ ∑ x ′ , y ′ I ′ ( x + x ′ , y + y ′ ) 2 R(x,y) = \frac{\sum_{x',y'}(T'(x', y') \cdot I'(x+x', y+y'))}{\sqrt{ \sum_{x',y'}T'(x', y')^2 \cdot \sum_{x',y'}I'(x+x', y+y')^2 }} \\ R(x,y)=x,yT(x,y)2x,yI(x+x,y+y)2 x,y(T(x,y)I(x+x,y+y))


示例:

#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main()
{cout << "OpenCV Version: " << CV_VERSION << endl;utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);Mat img = imread("lena.png");Mat temp = imread("lena_face.png");if (img.empty() || temp.empty()){cout << "请确认图像文件名称是否正确" << endl;return -1;}cout << "img.size(): " << img.size() << endl; // [512 x 512]cout << "img_template.size(): " << temp.size() << endl; // [164 x 172]Mat result;matchTemplate(img, temp, result, TM_CCOEFF_NORMED);//模板匹配cout << "result.size(): " << result.size() << endl; // [349 x 341]double maxVal, minVal;Point minLoc, maxLoc;//寻找匹配结果中的最大值和最小值以及坐标位置minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);//绘制最佳匹配区域rectangle(img, cv::Rect(maxLoc.x, maxLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2);imshow("原图", img);imshow("模板图像", temp);imshow("result", result);int k = waitKey(0); // Wait for a keystroke in the windowreturn 0;
}

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

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

相关文章

react-redux的connect函数实现

react-redux对store订阅的实现原理&#xff1a; storeContext.js import { createContext } from "react";export const StoreContext createContext() connect.js import React, { PureComponent } from react // import store from ../../store; import {Stor…

ESP RainMaker 客户案例 #2|PitPat

PitPat 是美国领先的健身品牌&#xff0c;致力于通过游戏化的方式改变人们的锻炼习惯&#xff0c;增强健康。该品牌通过智能设备和相关的移动应用程序为从事家庭锻炼的个人提供虚拟跑步体验。目前&#xff0c;PitPat 针对不同受众群体&#xff0c;开发了Superun&#xff0c;Dee…

程序开发中表示密码时使用 password 还是 passcode?

password 和 passcode 是两个经常在计算机和网络安全中使用的术语&#xff0c;两者都是用于身份验证的机制&#xff0c;但它们之间还是存在一些区别的。 password password 通常是指用户自己设置的一串字符&#xff0c;用于保护自己的账户安全。密码通常是静态的&#xff0c;…

druid的简单使用

文章目录 1.数据准备2.pom.xml文件中引用druid3. 在resource目录下创建druid.properties配置文件4. 编写java代码参考文献 1.数据准备 drop table if exists account; create table if not exists account (id int primary key auto_increment,name varchar(10),money dou…

android 13.0 SystemUI导航栏添加虚拟按键功能(三)

1.概述 在13.0的系统产品开发中,对于在SystemUI的原生系统中默认只有三键导航,想添加其他虚拟按键就需要先在构建导航栏的相关布局 中分析结构,然后添加相关的图标xml就可以了,然后添加对应的点击事件,就可以了,接下来先分析第三步关于导航栏的相关布局情况 然后实现虚拟…

从入门到进阶 之 ElasticSearch 文档、分词器 进阶篇

&#x1f339; 以上分享 ElasticSearch 文档、分词器 进阶篇&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f496;收藏&#…

国际站阿里云服务器无法安装程序怎么办?

阿里云服务器是阿里云推出的一种云核算产品&#xff0c;它能够帮助企业和个人快速建立、扩展和管理网络服务。可是&#xff0c;有时候在运用阿里云服务器时&#xff0c;或许会遇到无法装置程序的问题。本文将具体介绍如何处理这个问题。 阿里云服务器无法装置程序或许是由多种原…

【Electron】Not allowed to load local resource

问题描述 使用 audio 标签播放音频文件&#xff0c;控制台报错 Not allowed to load local resource。 原因分析 通常是安全策略所引起的。Electron 默认情况下禁止加载本地资源&#xff0c;以防止潜在的安全风险。 解决方案 在 main.js 中找到创建 BrowserWindow 实例的代码…

latex:使用中文字体

解决方案 我这里使用的是gbsn&#xff08;其他的字体我不知道&#xff0c;如果有补充请评价&#xff09;&#xff0c;详细说明如下&#xff1a;

Python学习基础笔记七十二——IDE集成开发环境

集成开发环境&#xff0c;英文缩写是IDE。 IDE可以帮你更高效地开发项目代码。因为它提供了非常实用的功能&#xff0c;比如项目文件管理、语法高亮、代码导航、自动补齐代码、语法静态检查、调试、版本控制等等。 两款IDE&#xff1a;Pycharm和VSCode。 pycharm中的代码文件都…

万界星空科技/生产制造执行MES系统/开源MES/免费MES

开源系统概述&#xff1a; 万界星空科技免费MES、开源MES、商业开源MES、市面上最好的开源MES、MES源代码、免费MES、免费智能制造系统、免费排产系统、免费排班系统、免费质检系统、免费生产计划系统、免费数字化大屏。 万界星空开源MES制造执行系统的Java开源版本。开源mes…

Qtday2

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {//窗口设置ui->setupUi(this);this->setWindowTitle("原神");this->setWindowIcon(QIcon(":/picture/genshi…

Pandas 快速入门教程

Pandas 概览 Pandas 是 Pythonopen in new window 的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,其长远目标是成为最强大、最灵活、可以支持任何语言的开…

【Python第三方包】控制台进度条——让你控制台变的更漂亮(tqdm)

文章目录 前言一、什么是tqdm?二、如何使用tqdm三、tqdm的基础使用3.1 基本使用3.2 使用total参数指定总步数3.3 在列表上使用3.4 使用desc参数为进度条添加描述信息3.5 动态更新进度条3.6 定制化外观和格式自定义进度条外观讲解3.7 使用tqdm的trange函数(生成器)3.8 在文件…

JavaScript作用域的用法

作用域 外部类无法访问内部类 外部类想要访问内部类需要闭包 两个函数可以有相同的变量名 两个函数包含关系&#xff0c;访问被包含的函数&#xff0c;在其该函数的外边可访问 如果外部函数存在这个同名的函数变量&#xff0c;则内部函数会屏蔽外部函数的 规范&#xff1a…

在数组中合并相同id数据,并且数据中某一字段不一致也统一合并进去

封装的合并的函数 function formateArray(data:any){// ts-ignorelet res data.reduce((ac,a) > {// ts-ignorelet index ac.findIndex(x > x.id a.id);index -1 ? ac.push({...a}) : ac[index] {...ac[index],...a};return ac;},[])return res;}使用 allData 原始…

腾讯云国际站服务器如何打开音频设备?

在使用腾讯云服务器进行音频处理或直播等活动时&#xff0c;或许需求翻开服务器的音频设备。本文将详细介绍如安在腾讯云服务器上翻开音频设备。 在腾讯云服务器上翻开音频设备的过程如下&#xff1a; 登录腾讯云服务器办理控制台 1.首先&#xff0c;需求登录腾讯云服务器的办理…

【jmeter】接口测试流程

1、Jmeter简介 Jmeter是由Apache公司开发的一个纯Java的开源项目&#xff0c;即可以用于做接口测试也可以用于做性能测试。 Jmeter具备高移植性&#xff0c;可以实现跨平台运行。 Jmeter可以实现分布式负载。 Jmeter采用多线程&#xff0c;允许通过多个线程并发取样或通过独…

Cron表达式每隔两小时执行一次

Cron表达式每隔两小时执行一次 0 0 */2 * * ?验证正确性

算法刷题总结(全)

刷题总结 by lds 2023-9-5 文章目录 1.数组/字符串1.1 合并两个有序数组【easy】1.2 移除元素【easy】1.3 删除有序数组中的重复项【easy】1.4 删除有序数组中的重复项II【mid】1.5 多数元素【easy】1.6 大数相加---【美团面试手撕题目】1.7 轮转数组【mid】1.8 买卖股票的最佳…