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

【OpenCV】- 模板匹配(浩瀚星空只为寻找那一抹明月)

🤖🤖🤖🤖 欢迎浏览本博客 🤖🤖🤖🤖
😆😆😆😆😆😆😆大家好,我是:我菜就爱学😆😆😆😆😆😆😆一名刚刚入行OpenCV的小白👻👻
👻👻从事方向:计算机视觉
🔔🔔我菜就爱学,分享有误,欢迎大佬指出🔔🔔
🌏🌏🌏本篇介绍:CV中的模板匹配算法


文章目录

      • 1 模板匹配的概念与原理
      • 2 模板匹配:matchTemplate()函数
        • 1)平方差匹配法 method=TM_SQDIF
        • 2)归一化平方差匹配法 method=TM_SQDIFF_NORMED
        • 3)相关匹配法:method = TM_CCORR
        • 4)归一化相关匹配法:method = TM_CCORR_NORMED
        • 5)系数匹配算法:method = TM_CCOEFF
        • 6)归一化相关系数匹配法 method= TM_CCOEFF_NORMED
      • 3 模板匹配综合示例
        • 1)minMaxLoc()函数相关API
        • 2)normalize()函数相关API
        • 3)rectangle()函数相关API
        • 示例代码(在星空中寻找月亮)

1 模板匹配的概念与原理

模板匹配是一项在一幅图像中寻找与另一幅图像最匹配部分的技术。模板匹配不是基于直方图,而是通过在输入图像上滑动图像块,对实际的图像块和输入图像进行匹配

2 模板匹配:matchTemplate()函数

说明:matchTemplate()用于匹配出和模板重叠的图像区域

void matchTemplate(InputArray image,InputArray temp1,OutputArray result,int method)
  • 第一个参数:待搜索的图像
  • 第二个参数:搜索模板,要和源图像有一样的数据类型
  • 第三个参数:比较结果的映射图像。如果图像尺寸是W * H,而temp的尺寸是 w * h,则输出参数result是:(W-w+1) x(H-h+1)
  • 第四个参数:匹配方法。提供六种方法如下

1)平方差匹配法 method=TM_SQDIF

说明:这类方法利用平方差来进行匹配,最好匹配为0,而若匹配越差,匹配值则越大。即计算出来值越小,越相关

在这里插入图片描述

2)归一化平方差匹配法 method=TM_SQDIFF_NORMED

说明:计算出来的值越接近0,越相关

在这里插入图片描述

3)相关匹配法:method = TM_CCORR

说明:这类算法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。即计算出来的值越大越相关。

在这里插入图片描述

4)归一化相关匹配法:method = TM_CCORR_NORMED

说明:即计算出来的值越接近1,越相关

在这里插入图片描述

5)系数匹配算法:method = TM_CCOEFF

说明:这类方法将模板对其均值的相对值与图像对其均值的相关值进行匹配,1标识完美匹配,-1表示最坏匹配,0表示没有任何关系

在这里插入图片描述

6)归一化相关系数匹配法 method= TM_CCOEFF_NORMED

在这里插入图片描述

3 模板匹配综合示例

1)minMaxLoc()函数相关API

说明:在一个数组中找到全局最小值和全局最大值。

void minMaxLoc(src, minVal, maxVal, minLoc, maxLoc, mask)

minMaxLoc函数找到最小值和最大值元素值以及它们的位置。极值在整个数组中搜索出来的,或者,如果掩膜不是一个空数组,那么将在一个特殊的数组中搜寻。该函数不能用于多通道数组。如果你需要在所有通道中找到最小或者最大值,那么需要先使用Mat::reshape,将它重构成一个单通道数组。

2)normalize()函数相关API

说明:缩放和移位数组元素,以便指定的标准(alpha)或最小(alpha)和最大(beta)数组值获得指定的值。

void normalize(src,dst,alpha=1, beta=0,NORM_MINMAX, dtype=-1, Mat());
  • 参数1:InputArray类型的src,输入数组(图像)。
  • 参数2:OutputArray类似的dst,输出数组(图像),与输入图像类型尺寸一样。
  • 参数3:alpha,表示range normalization模式的最小值。有默认值为1。
  • 参数4:beta,表示range normalization模式的最大值,不用于norm normalization(范数归一化)模式。有默认值为0。
  • 参数5:normType,表示归一化的类型,可以有以下的取值:
    • NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用。
    • NORM_INF:此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)。
    • NORM_L1:归一化数组的L1-范数(绝对值的和)。
    • NORM_L2:归一化数组的(欧几里德)L2-范数。
  • 参数6:有默认值为-1。dtype为负数时,输出数组的type与输入数组的type相同;否则,出数组与输入数组只是通道数相同,而tpye=CV_MAT_DEPTH(dtype)。
  • 参数7:操作掩膜,用于指示函数是否仅仅对指定的元素进行操作。

3)rectangle()函数相关API

void rectangle(img, Point(j,i), Point(j + img4.cols, i + img4.rows), Scalar(255, 255, 0), 2, 8);
  • iamge:被处理的图片
  • Point(j,i):代表矩形左上点的坐标
  • Point(j + cols, i + rows):代表矩形右下点的坐标
  • Scalar:颜色
  • 2:代表线条宽度
  • 8:是线型,默认取8

示例代码(在星空中寻找月亮)

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【效果图】"
Mat g_srcImage; Mat g_templateImage; Mat g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;
void on_Matching(int, void *);
int main()
{
	g_srcImage = imread("E:\\Pec\\星空.jpg", 1);
	g_templateImage = imread("E:\\Pec\\明月.jpg", 1);
	namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
	namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
	imshow("明月", g_templateImage);
	createTrackbar("Method:", WINDOW_NAME1, &g_nMatchMethod, g_nMaxTrackbarNum, on_Matching);
	on_Matching(0, 0);
	waitKey(0);
	return 0;
}
void on_Matching(int, void *)
{
	Mat srcImage;
	g_srcImage.copyTo(srcImage);
	//初始化输出的矩阵
	int resultImage_cols = g_srcImage.cols - g_templateImage.cols + 1;
	int resultImage_rows = g_srcImage.rows - g_templateImage.rows + 1;
	g_resultImage.create(resultImage_cols, resultImage_rows, CV_32FC1);
	//进行匹配
	matchTemplate(g_srcImage, g_templateImage, g_resultImage, g_nMatchMethod);
	//归一化
	normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());
	//通过函数minMaxLoc定位最匹配的位置
	double minValue, maxValue;//最大值、最小值
	Point minLocation, maxLocation;//最大值位置、最小值位置
	Point matchLocation;
	minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());

	//对于方法SQDIFF 和 SQDIFF_NOMED,越小的数值有更高的匹配结果
	if (g_nMatchMethod == TM_SQDIFF || g_nMatchMethod == TM_SQDIFF_NORMED)
	{
		matchLocation = minLocation;
	}
	else
	{
		matchLocation = maxLocation;
	}

	//画出矩形,显示结果
	rectangle(srcImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, 
	matchLocation.y + g_templateImage.rows), Scalar(0, 255, 0), 2, 8, 0);
	rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_templateImage.cols,
	 matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
	imshow(WINDOW_NAME1, srcImage);
	imshow(WINDOW_NAME2, g_resultImage);
}

1)原图以及寻找的子图

在这里插入图片描述
在这里插入图片描述

2)找到明月的效果图以及匹配图

平方差匹配算法(SQDIFF)
在这里插入图片描述在这里插入图片描述

相关系数匹配法(TM_COEFF)

在这里插入图片描述

相关文章:

  • Python Apex Legends 武器自动识别与压枪 全过程记录
  • 程序里对象很深很大,可以用这个设计模式缓解一下
  • Seata 分布式事务 详解+使用
  • 前端马农:抢不到消费券,我还不会自己做一张吗
  • React基础-JSX事件绑定-事件传参
  • python爬虫面试题集锦及答案
  • 语言学概论
  • 2022国赛C题解析
  • 我的创作纪念日,3周年总结
  • 构建自己的Docker镜像(Dockerfile)
  • SQL Server 2012学习笔记- - - 初识篇
  • QT UI设计笔记
  • 【全栈】vue3.0 + golang 尝试前后端分离【博客系统1.1】有进展了
  • Chapter9:Simulink建模与仿真
  • 【Python Web】Flask框架(八)前端基础整合
  • 【node学习】协程
  • 0基础学习移动端适配
  • Apache Spark Streaming 使用实例
  • django开发-定时任务的使用
  • JavaWeb(学习笔记二)
  • JS字符串转数字方法总结
  • Webpack入门之遇到的那些坑,系列示例Demo
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 前端路由实现-history
  • 前端性能优化--懒加载和预加载
  • 通过git安装npm私有模块
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • AI算硅基生命吗,为什么?
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • #pragma data_seg 共享数据区(转)
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • $.ajax()参数及用法
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (1)无线电失控保护(二)
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (done) 两个矩阵 “相似” 是什么意思?
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (八)c52学习之旅-中断实验
  • (八)Flask之app.route装饰器函数的参数
  • (层次遍历)104. 二叉树的最大深度
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .net core + vue 搭建前后端分离的框架
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .net Stream篇(六)
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .NET学习全景图
  • //TODO 注释的作用
  • [.net] 如何在mail的加入正文显示图片
  • [20170713] 无法访问SQL Server
  • [android] 切换界面的通用处理