注: 1.关于result的size为什么是(W-w+1,H-h+1),其中W、H是原图像的宽和高,w、h是模板的宽和高,而且要求w≦W,h≦H,这张图应该可以很好的解释; 2.OpenCV提供的method总共有六种,如下: cv::TM_SQDIFF
cv::TM_SQDIFF_NORMED
cv::TM_CCORR
cv::TM_CCORR_NORMED
cv::TM_CCOEFF
cv::TM_CCOEFF_NORMED
3.这六种method处理后的结果对比: 通常使用的都是第2、4、6个,即归一化之后的method;
选择第2种method处理后的值越小说明越相似,即越接近0,越相似; 选择第4、6中method处理后的值越大说明越相似,即越接近1,越相似; 更多关于这六种method的说明请参考OpenCV相关手册;
注: 这里的minVal和maxVal都是double类型的,并且是指针操作,所以在引用的时候要对实参进行&取地址操作;
原图像: 模板: 处理后的图像:
OpenCV提供的这个模板匹配的接口只能检测到其中的一个,为了能够匹配原图像中所有的目标,我简单的处理了一下,封装了一个API,直接输入原图像和模板等参数,就可以输出所有检测到的目标的坐标,源代码如下:
#include <iostream> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; void GetAllMinLoc(Mat image, Mat templ, double sim, Scalar mask, vector<Point> *all_min_loc); int main() { char *str_Input_Window_Title = "Read Image Window"; char *str_Template_Window_Title = "Template Window"; Mat img = imread("E:/chess.jpg");//从指定路径加载图像 Mat img_temp = imread("E:/chess_template.jpg"); if (!img.data || !img_temp.data)//加载图像失败 { printf("Fault to load image!\n\r"); return -1; } imshow(str_Input_Window_Title, img); imshow(str_Template_Window_Title, img_temp); //调用函数检测 vector<Point> P;//存储所有检测目标的坐标 GetAllMinLoc(img, img_temp, 0.05, Scalar(0,0,0), &P); //根据获取的全部坐标数据圈出待检测目标 for (int k = 0; k < P.size(); k++) { Point loc = P[k]; rectangle(img, Rect(loc.x, loc.y, img_temp.cols, img_temp.rows), Scalar(0, 0, 255), 2, 8); } imshow("Match_Result Window", img); waitKey(0); return 0; }运行结果:
个人拙见,仅供参考;