当前位置: 首页 > news >正文

[OpenCV] 数字图像处理 C++ 学习——17模板匹配详细讲解+附完整代码

文章目录

  • 前言
  • 1.理论基础
    • 1.1模板匹配介绍
    • 1.2匹配算法介绍
  • 2.代码实现
    • 2.1模块匹配(matchTemplate)
    • 2.2最佳匹配函数(minMaxLoc())
  • 3.完整代码

前言

模板匹配是图像处理和计算机视觉领域中的一种经典技术,它通过在大图像中搜索与小图像(模板)匹配的位置来实现目标检测和定位。OpenCV 提供了简单易用的 cv::matchTemplate 函数来实现模板匹配,本篇博客将详细讲解模板匹配的原理、使用方法,并结合完整的 C++ 代码来演示如何实现模板匹配。

1.理论基础

1.1模板匹配介绍

在这里插入图片描述

  • 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。
  • 所以模板匹配首先需要一个模板图像T(给定的子图像)
  • 另外需要一个待检测的图像-源图像S
  • 工作方法,在带检测图像上,从左到右,从上向下计算模板图像与重叠子图像的匹配度,匹配程度越大,两者相同的可能性越大。

1.2匹配算法介绍

enum TemplateMatchModes {TM_SQDIFF        = 0, // 计算平方不同TM_SQDIFF_NORMED = 1, // 计算归一化平方不同TM_CCORR         = 2, // 计算相关性TM_CCORR_NORMED  = 3, // 计算归一化相关性TM_CCOEFF        = 4, // 计算相关系数TM_CCOEFF_NORMED = 5, // 计算归一化相关系数
};

①计算平方数(TM_SQDIFF)

R ( x , y ) = ∑ 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'))^2 R(x,y)=x,y(T(x,y)I(x+x,y+y))2

②计算归一化平方数(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)= \frac{\sum_{x',y'} (T(x',y') - I(x+x',y+y'))^2}{\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))2

③计算相关性(TM_CCORR)

R ( x , y ) = ∑ x ′ , y ′ ( T ( x ′ , y ′ ) ⋅ I ( x + x ′ , y + y ′ ) ) R(x,y)= \sum_{x',y'} (T(x',y') \cdot I(x+x',y+y')) R(x,y)=x,y(T(x,y)I(x+x,y+y))

④计算归一化相关性(TM_CCORR_NORMED)

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))

⑤计算相关系数(TM_CCOEFF)

R ( x , y ) = ∑ x ′ , y ′ ( T ′ ( x ′ , y ′ ) ⋅ I ′ ( x + x ′ , y + y ′ ) ) R(x,y)= \sum_{x',y'} \left( T'(x',y') \cdot I'(x+x',y+y') \right) 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 ′ ′ ) T'(x',y') = T(x',y') - \frac{1}{w \cdot h} \cdot \sum_{x'',y''} T(x'',y'') T(x,y)=T(x,y)wh1x′′,y′′T(x′′,y′′)

I ′ ( x + x ′ , y + y ′ ) = I ( x + x ′ , y + y ′ ) − 1 w ⋅ h ⋅ ∑ x ′ ′ , y ′ ′ I ( x + x ′ ′ , y + y ′ ′ ) I'(x+x',y+y') = I(x+x',y+y') - \frac{1}{w \cdot h} \cdot \sum_{x'',y''} I(x+x'',y+y'') I(x+x,y+y)=I(x+x,y+y)wh1x′′,y′′I(x+x′′,y+y′′)

⑥计算归一化相关系数(TM_CCOEFF_NORMED)

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'} \left( T'(x',y') \cdot I'(x+x',y+y') \right)}{\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))

2.代码实现

2.1模块匹配(matchTemplate)

void matchTemplate( InputArray image, // 源图像,必须是8-bit或者32-bit浮点数图像InputArray templ, // 模板图像,类型与输入图像一致OutputArray result, // 输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh,则结果必须为W-w+1, H-h+1的大小。int method, //使用的匹配方法InputArray mask = noArray()  //(optional) 可选的掩码图像,用于指定要处理的区域。);

使用示例:

matchTemplate(src, temp, result, TM_SQDIFF, Mat());

2.2最佳匹配函数(minMaxLoc())

minMaxLoc() 是 OpenCV 中用于查找数组或图像中最大值和最小值及其位置的函数。在图像处理任务(如模板匹配、特征检测)中经常使用,用来确定某个区域内的极值点。

// OpenCV 函数 minMaxLoc 函数介绍
void minMaxLoc( InputArray src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, InputArray mask = noArray() )
  • src: 输入数组,可以是单通道的 cv::Mat 或其他支持的 OpenCV 数据类型。
  • minVal: 指向一个双精度浮点型变量的指针,用于存储找到的最小值。
  • maxVal: 指向一个双精度浮点型变量的指针,用于存储找到的最大值。
  • minLoc: 指向 Point 结构体的指针,用于存储找到的最小值位置。
  • maxLoc: 指向 Point 结构体的指针,用于存储找到的最大值位置。
  • mask (可选): 用于掩模操作的输入数组,标识出需要考虑的像素。

结果:

在这里插入图片描述

3.完整代码

#include<opencv2/opencv.hpp>
#include<highgui.hpp>
#include<iostream>
#include<math.h>using namespace cv;
using namespace std;Mat src, temp, dst;
int max_track = 5;
int match_method = TM_SQDIFF;
const char* INPUT_T = "input image";
const char* OUTPUT_T = "result image";
const char* match_t = "template match-demo";void Match_Demo(int, void*)
{int width = src.cols - temp.cols + 1;int height = src.rows - temp.rows + 1;Mat result(width, height, CV_32FC1); //32位浮点数,单通道matchTemplate(src, temp, result, match_method, Mat());normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());Point minLoc;Point maxLoc;double min, max;src.copyTo(dst);Point temLoc;// 用于在给定矩阵中找到最小值、最大值及其对应的位置minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat());if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED)temLoc = minLoc;elsetemLoc = maxLoc;//绘制矩形rectangle(dst, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);rectangle(result, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);imshow(OUTPUT_T, result);imshow(match_t, dst);}void Template_matching()
{src = imread("cat.jpg");//模板图像temp = imread("cat_nose.jpg");if (src.empty() || temp.empty()){cout << "ERROR: Could not load image." << endl;return;}namedWindow(INPUT_T, WINDOW_AUTOSIZE);namedWindow(OUTPUT_T, WINDOW_NORMAL);namedWindow(match_t, WINDOW_AUTOSIZE);imshow(INPUT_T, temp);const char* trackbar_title = "Match Algo Type:";createTrackbar(trackbar_title, OUTPUT_T, &match_method, max_track, Match_Demo);Match_Demo(0, 0);waitKey(0);}int main() 
{Template_matching();return 0;
}

http://www.mrgr.cn/news/55030.html

相关文章:

  • Plug-and-Play Diffusion Features for Text-Driven Image-to-Image Translation
  • QT开发--QT SQL模块
  • Axure复选框全选反选取消高级交互
  • R语言中的stat_compare_means():如何解决anova目标对象的方法问题
  • vue3 解决背景图与窗口留有间隙的问题
  • 美学心得(第二百六十八集) 罗国正
  • 3.订阅者Subscriber的编程实现以及话题消息定义与使用后续课程
  • pgAdmin不显示template1数据库,该如何设置才可以显示?
  • ACM与蓝桥杯竞赛指南 基本输入输出格式二
  • 波浪理论(Elliott Wave Theory)
  • autosar-port/interface学习总结
  • Docker compose 安装Jenkins
  • c++迷宫游戏
  • 揭秘CSS浮动盒:掌握高度塌陷修复、文字环绕特效示艺的秘籍!!(重点秘籍!!)
  • 高清无水印推文视频素材下载网站推荐
  • vite脚手架中安装和按需引入vuetify
  • 了解这些U盘数据恢复工具,不再担忧数据丢失
  • STM32应用详解(4)读写FLASH
  • 配置管理之Nacos
  • 025_Position_Layout_in_Matlab界面布局之设定位置
  • 【C++】C++语言知识总结浅析
  • 优质原创短视频素材下载网站推荐
  • Spring Boot 3.0 集成 knife4j 居然这么简单?你只需知道这几步!
  • 引爆品牌增长:数字营销的新策略与旧智慧
  • python+ffmpeg 屏幕录制程序
  • 集创赛比赛细则了解