|
模板匹配介绍
模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。
所以模板匹配首先需要一个模板图像T(给定的子图像)
另外需要一个待检测的图像-源图像S
工作方法,在带检测图像上,从左到右,从上向下计算模板图像与重叠子图像的匹配度,匹配程度越大,两者相同的可能性越大。

模板匹配介绍 – 匹配算法介绍
OpenCV中提供了六种常见的匹配算法如下:

计算归一化平方不同
计算归一化相关性
计算归一化相关系数

这类方法利用图像与模板各个像素差值的平方和来进行匹配,最好匹配为 0。 匹配越差,匹配值越大。
- 标准化差值平方和匹配 CV_TM_SQDIFF_NORMED
这个方法其实和差值平方和算法是类似的。只不过对图像和模板进行了标准化操作。
这种标准化操作可以保证当模板和图像各个像素的亮度都乘上了同一个系数时,相关度不发生变化。
也就是说当 I(x,y)和T(x,y) 变为k×I(x,y)和k×T(x,y) 时,R(x,y)不发生变化。
这类方法采用模板和图像的互相关计算作为相似度的度量方法,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。
- 标准化相关匹配 CV_TM_CCORR_NORMED
这个方法和 标准化差值平方和匹配 类似,都是去除了亮度线性变化对相似度计算的影响。可以保证图像和模板同时变亮或变暗k倍时结果不变。
这种方法也叫做相关匹配,但是和上面的 CV_TM_CCORR 匹配方法还是有不通过的。简单的说,这里是把图像和模板都减去了各自的平均值,使得这两幅图像都没有直流分量。
- 标准相关匹配 CV_TM_CCOEFF_NORMED
这是 OpenCV 支持的最复杂的一种相似度算法。这里的相关运算就是数理统计学科的相关系数计算方法。具体的说,就是在减去了各自的平均值之外,还要各自除以各自的方差。经过减去平均值和除以方差这么两步操作之后,无论是我们的待检图像还是模板都被标准化了,这样可以保证图像和模板分别改变光照亮不影响计算结果。计算出的相关系数被限制在了 -1 到 1 之间,1 表示完全相同,-1 表示两幅图像的亮度正好相反,0 表示两幅图像之间没有线性关系。

相关API介绍cv::matchTemplate
[C++] 纯文本查看 复制代码 matchTemplate(
InputArray image,// 源图像,必须是8-bit或者32-bit浮点数图像
InputArray templ,// 模板图像,类型与输入图像一致
OutputArray result,// 输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh,
则结果必须为W-w+1, H-h+1的大小。
int method,//使用的匹配方法
InputArray mask=noArray()//(optional)
)

[C++] 纯文本查看 复制代码 /*
注意:
差值平方和匹配 CV_TM_SQDIFF
这类方法利用图像与模板各个像素差值的平方和来进行匹配,最好匹配为 0。 匹配越差,匹配值越大。
标准化差值平方和匹配 CV_TM_SQDIFF_NORMED
这个方法其实和差值平方和算法是类似的。只不过对图像和模板进行了标准化操作。
这种标准化操作可以保证当模板和图像各个像素的亮度都乘上了同一个系数时,相关度不发生变化。
也就是说当 I(x,y)和T(x,y) 变为k×I(x,y)和k×T(x,y) 时,R(x,y)不发生变化。
相关匹配 CV_TM_CCORR
这类方法采用模板和图像的互相关计算作为相似度的度量方法,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。
标准化相关匹配 CV_TM_CCORR_NORMED
这个方法和 标准化差值平方和匹配 类似,都是去除了亮度线性变化对相似度计算的影响。可以保证图像和模板同时变亮或变暗k倍时结果不变。
相关匹配 CV_TM_CCOEFF
这种方法也叫做相关匹配,但是和上面的 CV_TM_CCORR 匹配方法还是有不通过的。简单的说,这里是把图像和模板都减去了各自的平均值,使得这两幅图像都没有直流分量。
标准相关匹配 CV_TM_CCOEFF_NORMED
这是 OpenCV 支持的最复杂的一种相似度算法。这里的相关运算就是数理统计学科的相关系数计算方法。具体的说,就是在减去了各自的平均值之外,还要各自除以各自的方差。经过减去平均值和除以方差这么两步操作之后,无论是我们的待检图像还是模板都被标准化了,这样可以保证图像和模板分别改变光照亮不影响计算结果。计算出的相关系数被限制在了 -1 到 1 之间,1 表示完全相同,-1 表示两幅图像的亮度正好相反,0 表示两幅图像之间没有线性关系。
*/
#include <opencv2/opencv.hpp>
#include <iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src, dst, gray,temp;
//匹配方法
int match_method = CV_TM_SQDIFF;
//模式匹配最大范围
int max_track = 5;
//声明匹配回调函数
void Match_Demo(int, void*);
int main(int argc, char** argv) {
//待检测图像
src = imread("D:/IDE/opencv-3.1.0/demo.jpg");
//模板图像
temp = imread("D:/IDE/opencv-3.1.0/temp.jpg");
if (!src.data||!temp.data) {
printf("加载图片异常\n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
imshow("temp", temp);
//创建标题为匹配模式的拖动条到input窗口上
createTrackbar("匹配模式", "input",&match_method,max_track, Match_Demo);
Match_Demo(0, 0 );
waitKey(0);
return 0;
}
void Match_Demo(int, void*) {
int width = src.cols - temp.cols+1;
int height = src.rows - temp.rows + 1;
//定义32位浮点型单通道图像 ,并且指定宽高
Mat result(width,height,CV_32FC1);
//匹配
matchTemplate(src, temp, result, match_method,Mat());
//归一化0-1之间
normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
//最小值
Point minloc;
//最大值
Point maxloc;
//临时判断值
Point temploc;
double min, max;
//找出最大最小值
minMaxLoc(result,&min,&max, &minloc, &maxloc, Mat());
if (match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED) {
temploc = minloc;
}
else {
temploc = maxloc;
}
src.copyTo(dst);
//绘制矩形
rectangle(dst, Rect(temploc.x, temploc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, LINE_AA);
rectangle(result, Rect(temploc.x, temploc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, LINE_AA);
imshow("output", dst);
imshow("模式效果", result);
}
|
|