OpenCv--模板匹配

模板匹配

模板匹配是一项在一幅图像中寻找与另外一幅模板图像最匹配(类似)部分的技术.html

实现:ios

  • 咱们须要2幅图像:函数

    1. 原图像 (I): 在这幅图像里,咱们但愿找到一块和模板匹配的区域
    2. 模板 (T): 将和原图像比照的图像块

    咱们的目标是检测最匹配的区域:学习

    ../../../../../_images/Template_Matching_Template_Theory_Summary.jpg
  • 为了肯定匹配区域, 咱们不得不滑动模板图像和原图像进行 比较 :spa

    ../../../../../_images/Template_Matching_Template_Theory_Sliding.jpg
  • 经过 滑动, 咱们的意思是图像块一次移动一个像素 (从左往右,从上往下). 在每个位置, 都进行一次度量计算来代表它是 “好” 或 “坏” 地与那个位置匹配 (或者说块图像和原图像的特定区域有多么类似).code

  • 对于 T 覆盖在 I 上的每一个位置,你把度量值 保存 到 结果图像矩阵 (R) 中. 在 R 中的每一个位置 (x,y) 都包含匹配度量值:orm

    ../../../../../_images/Template_Matching_Template_Theory_Result.jpg

    上图就是 TM_CCORR_NORMED 方法处理后的结果图像 R . 最白的位置表明最高的匹配. 正如您所见, 红色椭圆框住的位置极可能是结果图像矩阵中的最大数值, 因此这个区域 (以这个点为顶点,长宽和模板图像同样大小的矩阵) 被认为是匹配的.htm

  • 实际上, 咱们使用函数 minMaxLoc 来定位在矩阵 R 中的最大值点 (或者最小值, 根据函数输入的匹配参数) .blog

opencv实现方法:

  • 使用OpenCV函数 matchTemplate 在模板块和输入图像之间寻找匹配,得到匹配结果图像
  • 使用OpenCV函数 minMaxLoc 在给定的矩阵中寻找最大和最小值(包括它们的位置).

归一化做用:

定义:标准化是将不一样变化范围的值映射到相同的固定范围中,常见的是 [0,1],此时亦称归一化,也能够是[-1,1]范围。ip

形式:

min_max标准化:

也称为离差标准化,是对原始数据的线性变换,使结果值映射到[0 - 1]之间。转换函数以下:

clip_image002

2.Z-score标准化方法

这种方法给予原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化。通过处理的数据符合标准正态分布,即均值为0,标准差为1,转化函数为:

clip_image004

做用:

1.无量纲化
例如房子数量和收入,从业务层知道这二者的重要性同样,因此把它们所有归一化,这是从业务层面上做的处理。

2.避免数值问题
不一样的数据在不一样列数据的数量级相差过大的话,计算起来大数的变化会掩盖掉小数的变化。

3.一些模型求解的须要
例如梯度降低法,若是不归一化,当学习率较大时,求解过程会呈之字形降低。学习率较小,则会产生直角形路线,无论怎么样,都不会是好路线。

4.时间序列
进行log分析时,会将本来绝对化的时间序列归一化到某个基准时刻,造成相对时间序列,方便排查。

5.收敛速度
加快求解过程当中参数的收敛速度。

例子:

假设有两个变量,都是均匀分布,x1范围是[10000,20000],x2范围是[1,2]。有不少处于同一直线上的点,咱们称这条直线为L。若是如今咱们要作一个分类的话,x2几乎能够被忽略,x2很无辜的被干掉了,仅仅由于所谓量纲的问题。即使x2不被干掉,如今继续求解,来作梯度降低。 很显然,若是某一步咱们求得的降低方向不在直线L上,几乎能够确定确定这步不会降低。这就会致使不收敛,或者收敛很慢。

模板匹配实例:

#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
Mat src1,src2, dst;
int value = 0;
int max_value = 5;
void demo(int, void*);
int main()
{
	src1 = imread("C:\\Users\\马迎伟\\Desktop\\heibao.jpg");
	src2 = imread("C:\\Users\\马迎伟\\Desktop\\heibao1.png");
	if (src1.empty())
	{
		printf("cannot load!!\n");
		system("pause");
		return -1;
	}
	namedWindow("src",CV_WINDOW_AUTOSIZE);
	namedWindow("output",CV_WINDOW_AUTOSIZE);
	createTrackbar("trackbar","output",&value,max_value,demo);
	demo(0, 0);
	//imshow("output", dst);
	waitKey(0);
	return 0;
}
void demo(int, void*)
{
	int dst_col = src1.cols - src2.cols + 1;
	int dst_row = src1.rows - src2.rows + 1;
	//dst必须规定是 这个尺寸和类型
	dst.create(Size(dst_col,dst_row),CV_32FC1);
	//模板匹配
	matchTemplate(src1,src2,dst,value,Mat());
	//归一化
	normalize(dst,dst,0,1,NORM_MINMAX,-1,Mat());
	double minval, maxval;
	Point minloc, maxloc, loc;
	//找到模板匹配的最大值最小值和位置
	minMaxLoc(dst,&minval,&maxval,&minloc,&maxloc,Mat());
	if (value==CV_TM_SQDIFF||value==CV_TM_SQDIFF_NORMED)
	{
		loc = minloc;
	}
	else
	{
		loc = maxloc;
	}
	rectangle(dst,Rect(loc.x,loc.y,src2.cols,src2.rows),Scalar(0,0,255),2,LINE_AA);
	rectangle(src1,Rect(loc.x, loc.y, src2.cols, src2.rows), Scalar(255, 255, 255), 2, LINE_AA);
	imshow("output",dst);
	imshow("src", src1);
}