ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

opencv-C++_模板匹配_matchTemplate

2019-02-23 16:48:21  阅读:315  来源: 互联网

标签:matchTemplate srcImage 匹配 resultImage C++ opencv matchLocation tempalteImage met


模板匹配不是基于直方图的,而是通过在输入图像上滑动图像块,对实际图像块和输入图像进行匹配的一种匹配方法。

实现模板匹配:matchTemplate()函数
用于匹配出和模板重叠的图像区域;
函数原型C++

void matchTemplate( InputArray image, InputArray temp1, OutputArray result, int method )

【1】InputArray类型的image,待搜索的图像,且需为8位或32位浮点型图像;
【2】InputArray类型的temp1,搜索模板,需和源图片有一样的数据类型,且尺寸不能大于源图像;
【3】OutputArray类型的result,比较结果的映射图像,其必须为单通道、32位浮点型图像,如果图像尺寸是W x H而temp1尺寸是wxh,则此参数result一定是(W-w + 1)x(H-h+1);
【4】int类型的method,指定的匹配方法,提供一下6种方法:

  1. 平方差匹配法 method = TM_SQDIFF,使用平方差来进行匹配,最好匹配为0。
    而若匹配越差,匹配值则越大。(说明最黑的地方是匹配最好的地方)
  2. 归一化平方差匹配法:method = TM_SQDIFF_NORMED,最好匹配为0。
  3. 相关匹配法:method = TM_CCORR,这类方法才用模板和图像间的乘法操作,所以较大
    的数表示匹配程序较高,0标识最坏的匹配效果。
  4. 归一化相关匹配法 method = TM_CCORR_NORMED;最坏匹配为0。
  5. 系数匹配法method = TM_CCOEFF;最好匹配为1;
  6. 化相关系数匹配法method = TM_CCOEFF_NORMED;最好匹配为1。

通常,随着从简单的测量(平方差)到更复杂的测量(相关系数),我们可获得越来越准确的匹配。然而,这同时也会以越来越大的计算量为代价。比较科学的办法是对所有这些方法多次测试实验,以便为自己的应用选择同时兼顾速度和精度的最佳方案。

程序实例:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Mat g_srcImage, g_tempalteImage, g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;


void on_matching(int, void*)
{
	Mat srcImage;
	g_srcImage.copyTo(srcImage);
	int resultImage_cols = g_srcImage.cols - g_tempalteImage.cols + 1;
	int resultImage_rows = g_srcImage.rows - g_tempalteImage.rows + 1;
	g_resultImage.create(resultImage_cols, resultImage_rows, CV_32FC1);

	matchTemplate(g_srcImage, g_tempalteImage, g_resultImage, g_nMatchMethod);
	normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());
	double minValue, maxValue;
	Point minLocation, maxLocation, matchLocation;
	minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation);

	if (g_nMatchMethod == TM_SQDIFF || g_nMatchMethod == CV_TM_SQDIFF_NORMED)
	{
		matchLocation = minLocation;
	}
	else
	{
		matchLocation = maxLocation;
	}

	rectangle(srcImage, matchLocation, Point(matchLocation.x + g_tempalteImage.cols, matchLocation.y + g_tempalteImage.rows), Scalar(0, 0, 255), 2, 8, 0);
	rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_tempalteImage.cols, matchLocation.y + g_tempalteImage.rows), Scalar(0, 0, 255), 2, 8, 0);

	imshow("原始图", srcImage);
	imshow("效果图", g_resultImage);

}

int main()
{
	g_srcImage = imread("curry.jpg");
	if (!g_srcImage.data)
	{
		cout << "原始图读取失败" << endl;
		return -1;
	}
	g_tempalteImage = imread("curry2.jpg");
	if (!g_tempalteImage.data)
	{
		cout << "模板图读取失败" << endl;
		return -1;
	}

	imshow("g_srcImage", g_srcImage);
	imshow("g_tempalteImage", g_tempalteImage);

	namedWindow("原始图", CV_WINDOW_AUTOSIZE);
	namedWindow("效果图", CV_WINDOW_AUTOSIZE);
	createTrackbar("方法", "原始图", &g_nMatchMethod, g_nMaxTrackbarNum, on_matching);

	on_matching(0, NULL);


	waitKey(0);

	return 0;
}

可以看到有些方法也是匹配不上的;

原始图片:
在这里插入图片描述

模板图片:
在这里插入图片描述

运行结果

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

标签:matchTemplate,srcImage,匹配,resultImage,C++,opencv,matchLocation,tempalteImage,met
来源: https://blog.csdn.net/qq_27396861/article/details/87894153

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有