OpenCV学习2 模板匹配
模板匹配就是图像搜索的的一个过程,只不过是找到模板在原图像中最为相似的一块
OpenCV提供了模板匹配的函数
void matchTemplate(InputArray image, InputArray templ, OutputArray result, int method)
image参数:代表原图像; templ参数:模板;
result参数:输出的结果,可以说这是一幅相似度图像;
method参数:相似度的度量方式。
差值平方和匹配 0 CV_TM_SQDIFF
标准化差值平方和匹配 1 CV_TM_SQDIFF_NORMED
相关匹配 2 CV_TM_CCORR
标准相关匹配 3 CV_TM_CCORR_NORMED
相关匹配 4 CV_TM_CCOEFF
标准相关匹配 5 CV_TM_CCOEFF_NORMED
具体该函数详解参考官方文档
下面贴出一段改编自官方文档的代码
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdlib.h>
using namespace cv;
using namespace std;
//全局变量
Mat img; Mat templ; Mat result;
char *image_window ="Source Image";
char *result_window = "Result Image";
char *template_window = "Template Image";
int match_method;//滑动条的值对应不同的相似度度量方法
int max_trackBar = 5;//滑动条最大值
void MatchMethod(int,void *);//滑动条的回调函数
int main()
{
img = imread("number.png", 0);
templ = imread("num_templ.png", 0);
namedWindow(image_window, CV_WINDOW_AUTOSIZE);
namedWindow(result_window, CV_WINDOW_AUTOSIZE);
namedWindow(template_window, CV_WINDOW_AUTOSIZE);
char *trackBar_label = "Method:";
createTrackbar(trackBar_label, image_window, &match_method, max_trackBar, MatchMethod);//创建滑动条
MatchMethod(0, 0);
waitKey(0);
cvDestroyAllWindows();
return 0;
}
void MatchMethod(int, void *)
{
Mat display_img;
Mat result_copy;
img.copyTo(display_img);
int result_rows = img.rows - templ.rows + 1;
int result_cols = img.cols - templ.cols + 1;
result.create(result_rows, result_cols, CV_32FC1);
matchTemplate(img, templ,result_copy, match_method);//调用模板匹配函数
normalize(result_copy, result, 1, 0, NORM_MINMAX,-1,Mat());//归一化操作
double minVal, maxVal;
Point minLoc, maxLoc, matchLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc,Mat());//寻找result图像中最大值,最小值的坐标
if (match_method==CV_TM_SQDIFF||match_method==CV_TM_SQDIFF_NORMED)//这两种方式是取最小值
{
matchLoc = minLoc;
}
else
{
matchLoc = maxLoc;
}
//标出模板在原图的位置
rectangle(display_img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(255), 2, 8);
rectangle(result, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(0), 2, 8);
imshow(image_window, display_img);
imshow(result_window, result);
imshow(template_window, templ);
return;
}
选用的模板就是一个6的数字
可以从结果看出还是很好的框选出模板的位置,毕竟图像简单,下图是选用标准化差值平方和匹配的方式
d
我们看一下归一化的Result图
相似度图像效果非常好,标出了模板定位点,其余的都为白色。
再看一下其他相似度度量方式的结果,下图是相关匹配度量方式的结果
相似度图,可以看出最亮的一个点就是模板定位点