OpenCV学习系列之模板匹配

模板匹配算法介绍

模板匹配算法主要为模板图像在基准图上进行由左往右、由上到下进行相关运算,最后得到一个进行相关运算后的系数矩阵:系数矩阵中的参数值用来度量模板图像在基准图中的子区域相似程度。采用相关系数来进行评判,模板匹配算法主要有基于灰度值的模板匹配、梯度值的模板匹配、相位相关匹配等方法。
模板匹配示意图
灰度值匹配
  模板图像未经过任何预处理,直接取其像素值在原始图像上进行相关运算,灰度匹配算法优点在于速度快,缺点是对光照、亮度变化敏感,匹配鲁棒性不强。
梯度值匹配
针对模板匹配对光照、亮度变化敏感,有学者提出采取先对模板图和原始图分别计算其对应的梯度图。通过梯度图进行相关运算,匹配准确率得以大幅提高。
模板匹配主要缺点

1 基于灰度匹配算法不能够解决匹配景物存在旋转的情况
2 模板匹配算法耗时较大,相对于特征匹配效率低

模板匹配算法示例(图像数字化展示)

采取矩阵演示模式,假设基准图像矩阵G为:
基准图像矩阵
模板图像为T(假设为基准图矩阵G的子区域复制版本):
模板参数图像
计算T在G的匹配位置(相关运算):越界部分补零
[模板T中心点5从矩阵G起点(0,0)由左往右从上往下依次进行运算]

Gs(0, 0) = 01 + 02 + 03 + 04 + 05 + 06 + 07 + 08 + 19 = 9
Gs(0, 1) = 0
1 + 02 + 03 + 04 + 05 + 06 + 07 + 18 + 29 = 26

计算所有的相关系数矩阵Gs :
模板图在基准图上滑动后得出的相关系数矩阵
通过相关系数矩阵Gs可以看出,矩阵中最大参数值为285,最大参数值对应模板匹配的中心位置点(坐标)[绿色线框标定匹配结果]。当然,模板匹配算法改进会添加归一化步骤,梯度图像或者相位图的匹配。

模板匹配算法实验代码
#include "stdafx.h"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace std;
using namespace cv;

/// 全局变量声明
bool use_mask;
Mat img; Mat templ; Mat mask; Mat result;
const char* image_window = "Source Image";
const char* result_window = "Result window";

int match_method;
int max_Trackbar = 5;

void MatchingMethod(int, void*);

int main(int argc, char** argv)
{

	argv[1] = "..\\Histograms_Matching\\image\\lena.jpg";
	argv[2] = "..\\Histograms_Matching\\image\\template.jpg";
	// argv[3] = "..\\Histograms_Matching\\image\\template2.jpg";
	/// 加载模板图与基准图
	img = imread(argv[1], IMREAD_COLOR);
	templ = imread(argv[2], IMREAD_COLOR);

	if (argc > 3) {
		use_mask = true;
		mask = imread(argv[3], IMREAD_COLOR);
	}

	if (img.empty() || templ.empty() || (use_mask && mask.empty()))
	{
		cout << "Can't read one of the images" << endl;
		return -1;
	}

	/// 显示窗口创建
	namedWindow(image_window, WINDOW_AUTOSIZE);
	namedWindow(result_window, WINDOW_AUTOSIZE);

	/// 创建轨迹条
	/// SQDIFF: 差值平方和匹配    SQDIFF NORMED: 标准化差值平方和匹配
	/// TM_CORR: 相关匹配         TM_CORR NORMED: 标准(归一化)相关匹配
	/// TM_COEFF: 相关系数匹配        TM_COEFF NORMED: 标准相关系数匹配
	const char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
	createTrackbar(trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod);
   
	MatchingMethod(0, 0);  /// 匹配参数入口函数

	/// [wait_key]
	waitKey(0);
	system("pause");

	return 0;
}
 匹配函数
void MatchingMethod(int, void*)
{
	/// 原始图像拷贝
	Mat img_display;
	img.copyTo(img_display);

	/// 创建匹配输出图像结果矩阵
	int result_cols = img.cols - templ.cols + 1;
	int result_rows = img.rows - templ.rows + 1;

	result.create(result_rows, result_cols, CV_32FC1);

	/// 模板匹配
	bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);
	if (use_mask && method_accepts_mask)
	{
		matchTemplate(img, templ, result, match_method, mask);
	}
	else
	{
		matchTemplate(img, templ, result, match_method);
	}

	//! 归一化
	normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	/// 通过minMaxLoc来定位最佳匹配位置
	double minVal; double maxVal; Point minLoc; Point maxLoc;
	Point matchLoc;
    /// 寻找图像矩阵中最大最小像素点
	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

	/// 对于SQDIFF与SQDIFF_NORMED方式, 最佳匹配在最小点. 相反其它模式,最佳匹配在最大点位置
	if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED)
	{
		matchLoc = minLoc;
	}
	else
	{
		matchLoc = maxLoc;
	}

	/// 绘制匹配区
	rectangle(img_display, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(0), 2, 8, 0);
	rectangle(result, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(0), 2, 8, 0);

	imshow(image_window, img_display);
	imshow(result_window, result);

	return;
}

匹配实验结果:

总结

模板匹配算法经过多年发展已近趋于成熟,基于图像灰度信息的模板匹配算法最先被提出与使用,通过计算模板图像与基准图像滑动的子区域的相关系数进行判决匹配位置。随后由于基于灰度的匹配方法鲁棒性较差:光照、亮度等影响;因此出现基于梯度图像的模板匹配算法,梯度图抗光照、噪声、亮度等较好。模板匹配进行相关运算时耗时较高,由于卷积与相关实际运算中较为接近(可以近似理解卷积运算就是相关运算过程中核函数(模板图像)旋转180°),可以通过FFT进行加速运算;由于模板匹配对于景象有旋转变化时失效,后期逐渐发展为局部特征模式下的匹配算法,如SIFT、SURF等代表的算法火热了前二十年。随着12年Alexnet网络分类性能在ImageNet上脱颖而出,经典的手工设计方式告一段落,基于深度学习模式下的图像识别已经成为当下最流行的技术。但是,经典手工设计核函数思想在卷积神经网络设计中启发:Ps 低层次语义特征到高层次的语义特征是否类似于尺度空间的思想,不同大小的卷积核函数代表着不同的感受野等等。

代码下载

环境:windows10 x64 + vs2015 + opencv3.3.1

百度网盘链接:https://pan.baidu.com/s/1c3CFoIk 密码:xnce

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV中实现Halcon的模板匹配是有一定的挑战性的。OpenCV中自带的模板匹配算法是像素基本的模板匹配,容易受到光照影响,光照稍微有所不同,该方法就会失效。因此,如果想要实现类似Halcon的模板匹配算法,可以考虑基于图像边缘梯度的方法。 引用中提到的基于图像边缘梯度的模板匹配算法对图像光照与像素迁移都有很强的抗干扰能力,并且在工业应用场景中已经得到广泛使用。这种算法主要是通过提取图像的边缘信息和梯度信息来进行模板匹配,能够更好地适应光照变化和像素变化。 然而,需要注意的是,OpenCV中并没有直接提供基于图像边缘梯度的模板匹配算法。如果想要实现类似的功能,可能需要根据具体的需求和场景自己编写代码或者借助第三方库。 总而言之,要在OpenCV中实现Halcon的模板匹配,可以考虑基于图像边缘梯度的方法,但需要自己编写相应的代码或者借助第三方库来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [使用OpenCV实现Halcon算法(3)基于轮廓的模板匹配](https://blog.csdn.net/libaineu2004/article/details/117021634)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [使用OpenCV实现Halcon算法(4)OpenCV实现边缘模板匹配算法](https://blog.csdn.net/libaineu2004/article/details/117063718)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [opencv获取模板模板匹配](https://blog.csdn.net/the_future_way/article/details/110448796)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值