OpenCV数字图像处理实战二:模板匹配(C++)

article/2025/11/8 23:45:21

OpenCV数字图像处理实战二:模板匹配(C++)

1、模板匹配原理

模板匹配(TemplateMatching)就是在一幅图像中寻找和模板图像(template)最相似的区域,模板匹配不是基于直方图的,而是通过在输入图像上滑动图像块(模板)同时对比相似度,来对模板和输入图像进行匹配的一种方法。该方法原理简单计算速度快,能够应用于目标识别,目标跟踪等多个领域。

2、具体步骤

(1)首先需要一个模板图像 T(子图像)和一个待检测的图像(源图像 S)

image-20221012090549440

image-20221012090705249

(2)在待检测图像从左到右,从上到下计算模板图像与重叠子图像的匹配度,匹配度越高,两者相同的可能性越大。

img

优点: 原理简单计算速度快
缺点:模板图像尺寸和待检测图像尺寸问题。模板尺寸必须小于待检测图片尺寸

3、OpenCV模板匹配实现

3.1 单模板匹配

int main()
{Mat temp = imread("E:\\img\\T2.jpg");Mat src = imread("E:\\img\\S.jpg");Mat dst = src.clone();imshow("temp", temp);//1.构建结果图像resultImg(注意大小和类型)//如果原图(待搜索图像)尺寸为W x H, 而模版尺寸为 w x h, 则结果图像尺寸一定是(W-w+1)x(H-h+1)//结果图像必须为单通道32位浮点型图像int width = src.cols - temp.cols + 1;//result宽度int height = src.rows - temp.rows + 1;//result高度Mat result(height, width, CV_32FC1);//创建结果映射图像//2.模版匹配//这里我们使用的匹配算法是标准平方差匹配 method=TM_SQDIFF_NORMED,数值越小匹配度越好//matchTemplate(src, temp, result, TM_SQDIFF); //平方差匹配法(最好匹配0)matchTemplate(src, temp, result, TM_SQDIFF_NORMED); //归一化平方差匹配法(最好匹配0)//matchTemplate(src, temp, result, TM_CCORR); //相关匹配法(最坏匹配0)//matchTemplate(src, temp, result, TM_CCORR_NORMED); //归一化相关匹配法(最坏匹配0)//matchTemplate(src, temp, result, TM_CCOEFF); //系数匹配法(最好匹配1)//matchTemplate(src, temp, result, TM_CCOEFF_NORMED);//化相关系数匹配,最佳值1imshow("result", result);//3.正则化(归一化到0-1)normalize(result, result, 0, 1, NORM_MINMAX, -1);//归一化到0-1范围//4.找出result中的最大值及其位置double minValue, maxValue;Point minLoc, maxLoc;// 定位极值的函数minMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc);cout << "minValue=" << minValue << endl;cout << "maxValue=" << maxValue << endl;//5.根据result中的最大值位置在源图上画出矩形和中心点rectangle(dst, maxLoc, Point(maxLoc.x + temp.cols, maxLoc.y + temp.rows), Scalar(0, 255, 0), 2, 8);imshow("dst", dst);waitKey(0);return 0;
}

image-20221012093233130

注意:result的长宽正好是(原图-模板图)的长宽,result图中白亮程度表示匹配程度

模板匹配函数cv::MatchTemplate一次计算模板与待测图像的相似度,并将结果存入映
图像result中,也就是result图像中的每一个点的值代表一次相似度比较结果;其中,模通过在待检测的图像上从左到右,从上到下滑动,每到达一个像素点,就会以这个像素点左上角顶点从原图像中截取一个与模板大小一样的图像进行像素比较的运算,模板在滑动过程中,将模板和当前截取的图像的比较计算结果储存在result矩阵中,result的大小为(W-w+1,H-h+1),在result中的每个位置(x,y)的值都表示以这个点为左上角顶点截取的图像模板像素计算后的计算结果;模板在待测图像上每次在横向或者纵向上每次移动一个像素点然后进行一次比较,所以横向比较W-w+1次,纵向比较H-h+1次,最终得到一个(W-w+1)x(H-h+1)的result矩阵。
ROI区域的获取
从result中提取最大值(相似度最高)以及最大值的位置(即在result中该最大值max_val的坐标位置max_loc,即模板滑行时左上角的坐标,类似于图中的坐标(x,y);由此得到rect=cvRect(max_loc.x,max_loc.y,tmp->width,tmp->height); 其中rect表示最佳的匹配的矩形区域。

3.2 多目标模板匹配一

 //  1.读入图片Mat srcImg = imread("E://img//S1.png");Mat templateImg = imread("E://img//T3.jpg");Mat resultImg;Mat showImg = srcImg.clone();//  设置result图片的大小int resultImg_cols = srcImg.cols - templateImg.cols + 1;int resultImg_rows = srcImg.rows - templateImg.rows + 1;resultImg.create(resultImg_cols, resultImg_rows, CV_32FC1);//  2.模板匹配matchTemplate(srcImg, templateImg, resultImg, TM_CCOEFF_NORMED); //化相关系数匹配法(最好匹配1)//  3.归一化normalize(resultImg, resultImg, 0, 1, NORM_MINMAX);Mat midImg = resultImg.clone();//多目标模板匹配---方法一double matchValue;int count0=0;int tempW=0, tempH=0;char matchRate[10];for(int i=0; i<resultImg_rows; i++){for(int j=0; j<resultImg_cols; j++){matchValue = resultImg.at<float>(i, j);sprintf_s(matchRate, "%0.2f", matchValue);if(matchValue>=0.85 && (abs(j - tempW)>5) && (abs(i - tempH)>5) ){count0++;//将文字显示在图片上putText(showImg, matchRate, Point(j-5, i-5), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1);rectangle(showImg, Point(j, i), Point(j + templateImg.cols, i + templateImg.rows), Scalar(0, 255, 0), 2);tempW = j;tempH = i;}}}cout<<"count="<<count0<<endl;imshow("resultImg", resultImg);imshow("dst", showImg);

image-20221012124853119

3.3 多目标模板匹配二

//多目标模板匹配---方法二double minValue, maxValue;Point minLoc, maxLoc;Point matchLoc;char matchRate[10];for (int i = 0; i < 100; i++){int startX = maxLoc.x - 4;int startY = maxLoc.y - 4;int endX = maxLoc.x + 4;int endY = maxLoc.y + 4;if (startX < 0 || startY < 0){startX = 0;startY = 0;}if (endX > resultImg.cols - 1 || endY > resultImg.rows - 1){endX = resultImg.cols - 1;endY = resultImg.rows - 1;}Mat temp = Mat::zeros(endX - startX, endY - startY, CV_32FC1);//Mat ROI = resultImg(Rect(Point(startX, startY), temp.cols, temp.rows));temp.copyTo(resultImg(Rect(startX, startY, temp.cols, temp.rows)));minMaxLoc(resultImg, &minValue, &maxValue, &minLoc, &maxLoc);if (maxValue < 0.89)    break;cout << "max_value= " << maxValue << endl;sprintf_s(matchRate, "%0.2f", maxValue);putText(showImg, matchRate, Point(maxLoc.x - 5, maxLoc.y - 5), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1);rectangle(showImg, maxLoc, Point(maxLoc.x + templateImg.cols, maxLoc.y + templateImg.rows), Scalar(0, 255, 0), 2);}imshow("midImg", midImg);imshow("resultImg", resultImg);imshow("dst", showImg);

image-20221012125238806

模板匹配 --- matchTemplate()
CV_EXPORTS_W void matchTemplate(
InputArray image, 
InputArray temp1, 
OutputArray result, 
int method);
image:待搜索图像(大图)
temp1:搜索模板,需和原图一样数据类型且尺寸大小不能大于源图像
reuslt:比较结果的映射图像,其必须为单通道的,32位浮点型图像,如果原图(待搜索图像)尺寸为W*H,二temp1的尺寸为w*h,则result的尺寸一定是(W-w+1)*(H-h+1)
method:指定的匹配方法,有如下六种:

(1)平方差匹配 method=TM_SQDIFF

这类方法利用平方差来进行匹配,最好匹配为0。匹配越差,匹配值越大。

image-20221012092134147

(2)标准平方差匹配 method=TM_SQDIFF_NORMED

img

(3)相关匹配 method=TM_CCORR

这类方法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。

img

(4)标准相关匹配 method=TM_CCORR_NORMED

img

(5)相关匹配 method=TM_CCOEFF

这类方法将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示匹配很差,0表示没有任何相关性(随机序列)。

img

img

(6)标准相关匹配 method=TM_CCOEFF_NORMED

img

矩阵归一化 --- normalize()	函数的作用是进行矩阵归一化。
void normalize(InputArray src,OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() )
src:输入源图像,Mat类型
dst:输出结果图像,需要和原图一样的尺寸和类型
alpha:归一化后的最小值,默认为1
beta:归一化后的最大值,默认为0
norm_type:归一化类型,可选:NORM_INF, NORM_L1, NORM_L2(默认)等
dtype:默认值为-1,此参数为负值时,输出矩阵和src有同样的类型
mask:可选的掩码操作
寻找最值 --- minMaxLoc()	函数的作用是在数组中找到全局最小值和最大值
CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal, CV_OUT double* maxVal = 0, CV_OUT Point* minLoc=0, CV_OUT Point* maxLoc=0, InputArray mask=noArray());
src:输入源图像,单通道图像
minVal:返回最小值的指针,若无需返回,则置为0
maxVal:返回最大值的指针,若无需返回,则置为0
minLoc:返回最小位置的指针,若无需返回,则置为0
maxLoc:返回最大位置的指针,若无需返回,则置为0
mask:可选的掩码操作

部分参考来自22、【opencv入门】模板匹配 - 阿牧路泽 - 博客园 (cnblogs.com)


http://chatgpt.dhexx.cn/article/RcQYlK3w.shtml

相关文章

opencv 模板匹配形状匹配

文章目录 1. 找圆垫子1.1 得到模板1.2 形状匹配 2. 找瓜子 这是第四次作业要求 所以今天就趁机会讲讲模板匹配&#xff0c;正好之前的项目有一部分重要工作就是和模板匹配紧密相关&#xff0c;对于今天作业来说&#xff0c;之前的项目难度更大&#xff0c;因为涉及到许多要考虑…

Opencv——图像模板匹配

引言 什么是模板匹配呢&#xff1f; 看到这里大家是否会觉得很熟悉的感觉涌上心头&#xff01;在人脸识别是不是也会看见 等等。 模板匹配可以看作是对象检测的一种非常基本的形式。使用模板匹配&#xff0c;我们可以使用包含要检测对象的“模板”来检测输入图像中的对象。 …

OpenCV-模板匹配cv::matchTemplate

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 函数原型 void matchTemplate( InputArray image, InputArray templ,OutputArray result, int method, InputArray mask noArr…

OPENCV多种模板匹配使用对比

前文简单提到模板匹配中的一种&#xff1a;NCC多角度模板匹配&#xff0c;博主结合实际的检测项目&#xff08;已落地&#xff09;发现其准确率和稳定性有待提升&#xff0c;特别是一些复杂背景的图形&#xff0c;又或是模板选取不当都会造成不理想的效果&#xff1b;同时也借鉴…

基于opencv的模板匹配详解

1.什么是模板匹配 在OpenCV教程中这样解释模板匹配&#xff1a; 模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术。这里说的模板是我们已知的小图像&#xff0c;模板匹配就是在一副大图像中搜寻目标。模板就是我们已知的在图中要找的目标&#xff0c;…

OpenCV模板匹配(cv2.matchTemplate)

目录 摘要正文OpenCV模板匹配&#xff08;cv2.matchTemplate&#xff09;什么是模板匹配&#xff1f;OpenCV的 “cv2.matchTemplate” 函数配置开发环境项目结构使用OpenCV实施模板匹配OpenCV模板匹配结果总结 摘要 在本教程中&#xff0c;您将学习如何使用OpenCV和cv2.matchTe…

Opencv (C++)系列学习---模板匹配

目录 1.模板匹配的定义 2.API介绍 3.寻找最优匹配位置&#xff08;匹配后的配套操作&#xff09; 4.具体代码 1.模板匹配的定义 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域&#xff0c;该匹配方法并不是基于直方图&#xff0c;而是使用一个图像块在输入图像…

【OpenCV--模板匹配】

目录 一、模板匹配 1.定义&#xff1a; 2.实现&#xff1a; 二、霍夫线检测 1.原理&#xff1a; 2.实现&#xff1a; 三、霍夫圆检测 1.描述&#xff1a; 2.用法&#xff1a; 一、模板匹配 1.定义&#xff1a; 模板匹配就是在给定的图片中&#xff0c;查找和模板最相似的区域…

OpenCV学习笔记(十一)——模板匹配

模板匹配是指在当前图像A内寻找与图像B最相似的部分&#xff0c;一般将图像A称为输入图像&#xff0c;将图像B称为模板图像。模板匹配的操作方法是将模板图像B在图像A上滑动&#xff0c;遍历所有像素以完成匹配。 OpenCV学习笔记(十一&#xff09; 1. 模板匹配基础2. 多模板匹配…

opencv中的模板匹配

1 匹配函数 opencv 提供了一个专门用于模板匹配的函数 cv::matchTemplate();其调用方式如下&#xff1a; void cv::matchTemplate(cv::InputArray image, // 用于搜索的输入图像, 8U 或 32F, 大小 W-Hcv::InputArray templ, // 用于匹配的模板&#xff0c;和image类型相同&am…

【论文译文】BigGAN

译文仅供参考&#xff01; 原文是pdf&#xff0c;想下载的话可以戳&#xff1a;http://www.gwylab.com/pdf/biggan_chs.pdf

WGAN、WGAN-GP、BigGAN

一、WGAN概述 WGAN论文地址&#xff1a;https://arxiv.org/abs/1701.07875 在这篇论文中&#xff0c;作者研究了不同的测量方法&#xff0c;来描述模型生成样本和证实样本之间分布差距&#xff0c;或者说&#xff0c;不同的散度定义&#xff0c;在对比之后&#xff0c;认为EM…

tf hub bigGan 猫变狗

原文链接: tf hub bigGan 猫变狗 上一篇: tf hub mobile_net 使用 下一篇: tf hub 使用缓存 数据 根据输入的标签和噪声生成指定类别的图片&#xff0c;类似infogan 每次向着目标前进一小步&#xff0c;将其中的过程变化记录下来 import tensorflow as tf import n…

(2018, BigGAN)用于高保真自然图像合成的大规模 GAN 训练

Large scale gan training for high fidelity natural image synthesis 公众号&#xff1a;EDPJ 目录 0. 摘要 1. 简介 2. 背景 3. 扩展 GAN 3.1 使用截断技巧权衡多样性和保真度 3.2 总结 4. 分析 4.1 表征不稳定性&#xff1a;生成器 4.2 表征不稳定性&#xff1…

深度解读DeepMind新作:史上最强GAN图像生成器—BigGAN

在碎片化阅读充斥眼球的时代&#xff0c;越来越少的人会去关注每篇论文背后的探索和思考。 在这个栏目里&#xff0c;你会快速 get 每篇精选论文的亮点和痛点&#xff0c;时刻紧跟 AI 前沿成果。 点击本文底部的「阅读原文」即刻加入社区&#xff0c;查看更多最新论文推荐。 这…

基于飞桨实现BigGAN生成动漫图像——为艺术创作赋能

点击左上方蓝字关注我们 【飞桨开发者说】艾梦&#xff0c;深度学习业余选手&#xff0c;热衷于用AI创造新的可能性&#xff0c;努力探索发现未知的神奇世界。玩AI&#xff0c;我是认真的。 作为学力不足、码力有余的深度学习业余玩家&#xff0c;笔者在工作中忙里偷闲&#xf…

GAN变种介绍 - DCGAN、InfoGAN、CycleGAN、WGAN、Self-Attention GAN、BigGAN

GAN变种介绍 - DCGAN、InfoGAN、CycleGAN、WGAN、Self-Attention GAN、BigGAN 一、DCGAN二、InfoGAN三、CycleGAN四、WGAN五、Self-Attention GAN六、BigGAN 在原始的 GAN 论文中&#xff0c;Ian Goodfellow 从理论层面分析了 GAN 网络的收敛性&#xff0c;并且在多个经典图片数…

基于飞桨PaddlePaddle实现BigGAN生成动漫图像——为艺术创作赋能

作为学力不足、码力有余的深度学习业余玩家&#xff0c;笔者在工作中忙里偷闲&#xff0c;借助AI Studio的免费GPU继续自己对于生成对抗网络落地应用的相关研究。尽管深度学习已在工业生成中广泛应用&#xff0c;但作为研究重头的视觉效果极佳的GAN的图像生成&#xff0c;却在应…

深度学习(四十六)——StarGAN, InfoGAN, ProGAN, StyleGAN, BigGAN, FUNIT, CVAE

StarGAN 论文&#xff1a; 《StarGAN: Unified Generative Adversarial Networksfor Multi-Domain Image-to-Image Translation》 CycleGAN的局限在于&#xff1a;对于两个Domain之间的变换&#xff0c;需要两个G网络。可以想象&#xff0c;当Domain的数量上升时&#xff0c;…

biggan:large scale gan training for high fidelity natural image synthesis

深度解读DeepMind新作&#xff1a;史上最强GAN图像生成器—BigGAN - 知乎本期推荐的论文笔记来自 PaperWeekly 社区用户 TwistedW。由 DeepMind 带来的 BigGAN 可谓是笔者见过最好的 GAN 模型了&#xff0c;这里的 Big 不单单是指模型参数和 Batch 的大&#xff0c;似乎还在暗示…