OpenCV模板匹配
- matchTemplate函数
- 具体代码实现
- 匹配结果如下
matchTemplate函数
参考链接:
基本思想是将模板图像在目标图像上滑动逐一对比,通过统计的基本方法进行匹配,比如方差检验,相关性检验等方法来寻找最佳匹配
CV_EXPORTS_W void matchTemplate(
InputArray image,
InputArray templ,
OutputArray result,
int method );
- 参数1:image,待匹配的源图像(搜索图像)
- 参数2:templ,模板图像
- 参数3:result,保存结果的矩阵
我们可以通过minMaxLoc() 确定结果矩阵的最大值和最小值的位置.
minMaxLoc()函数:查找全局最小和最大稀疏数组元素并返回其值及其位置
void minMaxLoc(const SparseMat& a, double* minVal,double* maxVal, int* minIdx=0, int* maxIdx=0);
a: 匹配结果矩阵
&minVal 和 &maxVal: 在矩阵 result 中存储的最小值和最大值
&minLoc 和 &maxLoc: 在结果矩阵中最小值和最大值的坐标. - 参数4:method ,模板匹配的算法
有以下六种:
enum TemplateMatchModes { //模板匹配对应的匹配算法,有三种归一化的,三种不归一化的
TM_SQDIFF = 0, //平方差匹配法,计算平方不同,计算出来的值越小,越相关
TM_SQDIFF_NORMED = 1, //归一化平方差匹配法,计算归一化平方不同,计算出来的值越接近0,越相关
TM_CCORR = 2, //相关匹配法,计算相关性,计算归一化相关性,计算出来的值越大,越相关
TM_CCORR_NORMED = 3, //归一化相关匹配法,计算出来的值越接近1,越相关
TM_CCOEFF = 4, //系数匹配法,计算相关系数,计算出来的值越大,越相关
TM_CCOEFF_NORMED = 5 //归一化相关系数匹配法,计算归一化相关系数,计算出来的值越接近1,越相关
归一化函数
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
具体代码实现
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat src, temp, dst;
int match_method = TM_SQDIFF;
int max_track = 5;
const char* INPUT_T = "input image";
const char* OUTPUT_T = "result image";
const char* match_t = "template match-demo";
void Match_Demo(int, void*);
int main(int argc, char** argv) {
// 待检测图像
src = imread("G:/OpenCV/opencv笔记所用图片/模板匹配/nvTuan.jpg");
// 模板图像
temp = imread("G:/OpenCV/opencv笔记所用图片/模板匹配/DanRen.jpg");
if (src.empty() || temp.empty()) {
printf("could not load image...\n");
return -1;
}
namedWindow(INPUT_T, CV_WINDOW_AUTOSIZE);
namedWindow(OUTPUT_T, CV_WINDOW_NORMAL);
namedWindow(match_t, CV_WINDOW_AUTOSIZE);
imshow(INPUT_T, temp);
const char* trackbar_title = "Match Algo Type:";
createTrackbar(trackbar_title, OUTPUT_T, &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;
Mat result(width, height, CV_32FC1);// 输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh,则结果必须为W - w + 1, H - h + 1的大小。
matchTemplate(src, temp, result, match_method, Mat());//模板匹配
normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());//归一化,变为0-1之间
Point minLoc;
Point maxLoc;
double min, max;
src.copyTo(dst); //将其全部拷贝到dst上
Point temLoc;
minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat()); //得到最小最大值
if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED) { //平方差匹配的方式越小越好
temLoc = minLoc;
}
else { //计算相关性,相关系数的方式值越大越好
temLoc = maxLoc;
}
// 绘制矩形
rectangle(dst, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
rectangle(result, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
imshow(OUTPUT_T, result);
imshow(match_t, dst);
}
匹配结果如下
- 模板图像
- 待匹配的图像(搜索图像)
- 匹配结果如下
- 可进行匹配方法选择
下方六个刻度,每个刻度对应着一个匹配方法method