模板匹配的概念和原理
模板匹配就是在一幅图像中寻找与模板图像最匹配(相似)部分。
具体步骤为从左到右,从上向下计算模板图像与图像覆盖区域的匹配度,匹配程度越大,两者相同的可能性越大。
实现模板匹配:matchTemplate 函数
void matchTemplate(InputArray image, InputArray temp1, OutputArray result, int method);
- image,待搜索的图像,且需为 8 位或 32 位浮点型图像。
- temp1,搜索模板,需要和原图片有一样的数据类型,且尺寸不能大于源图像。
- result,比较结果的映射图像,其必须为单通道、32 位浮点型图像,大小为 (image.cols - temp1.cols +1)×(image.rows - temp1.rows +1)
- method,匹配方法,有 6 种选项:
匹配方法 | 计算公式 |
平方差匹配法 TM_SQDIFF |
|
归一化平方差匹配法 TM_SQDIFF_NORMED |
|
相关匹配法 TM_CCORR |
|
归一化相关匹配法 TM_CCORR_NORMED |
|
系数匹配法 TM_CCOEFF |
其中
|
化相关系数匹配法 TM_CCOEFF_NORMED |
|
代码示例:
#include<opencv.hpp>
#include<iostream>
#include<string>
using namespace std;
using namespace cv;
Mat src, temp;
int method = 0;
void ChangeMethod(int, void*) {
switch (method){
case 0:
method = TM_SQDIFF;
break;
case 1:
method = TM_SQDIFF_NORMED;
break;
case 2:
method = TM_CCORR;
break;
case 3:
method = TM_CCORR_NORMED;
break;
case 4:
method = TM_CCOEFF;
break;
case 5:
method = TM_CCOEFF_NORMED;
break;
}
Mat result;
matchTemplate(src, temp, result, method);
imshow("result", result);
Mat dst = src.clone();
double mxValue, mnValue;
Point mxPoint, mnPoint;
minMaxLoc(result, &mnValue, &mxValue, &mnPoint, &mxPoint);
//https://www.cnblogs.com/bjxqmy/p/12386274.html
if (method == TM_SQDIFF || method == TM_SQDIFF_NORMED) {
rectangle(dst, mnPoint, Point(mnPoint.x + temp.cols, mnPoint.y + temp.rows), Scalar(0, 0, 255));
}
else{
rectangle(dst, mxPoint, Point(mxPoint.x + temp.cols, mxPoint.y + temp.rows), Scalar(0, 0, 255));
}
imshow("dst", dst);
}
int main() {
src = imread("C:/Users/齐明洋/Desktop/1.jpg");
temp = imread("C:/Users/齐明洋/Desktop/a.jpg");
imshow("src", src);
imshow("temp", temp);
namedWindow("dst");
createTrackbar("method", "dst", &method, 5, ChangeMethod);
ChangeMethod(0, 0);
waitKey(0);
}
效果演示:
原图和模板:
TM_SQDIFF 方法
TM_SQDIFF_NORMED 方法
TM_CCORR 方法
TM_CCORR_NORMED 方法
TM_CCOEFF 方法
TM_CCOEFF_NORMED 方法