代码如下:
#include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace std; using namespace cv; Mat src, temp, dst; //Trackbar的参数: int match_method = TM_SQDIFF; //match_method指针指向第一种匹配方法 int max_track = 5; // 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("L:/10.jpg"); // 模板图像 temp = imread("L:/11.jpg"); if (src.empty() || temp.empty()) { printf("could not load image... "); 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_method, max_track Match_Demo(0, 0); waitKey(0); return 0; } void Match_Demo(int, void*) { //定义一个result矩阵,必须是单通道32位浮点数, //假设源图像WxH,模板图像wxh,则结果必须为W - w + 1, H - h + 1的大小。 int width = src.cols - temp.cols + 1; int height = src.rows - temp.rows + 1; Mat result(width, height, CV_32FC1); matchTemplate(src, temp, result, match_method, Mat()); //match_method指针指的是5种方法 //matchTemplate魔板匹配函数:1.源图像 2.模板图像 3.输出结果result 4.匹配方法 5.Mat() normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat()); //归一化函数 Point minLoc; //匹配计算结果中最小值的位置点 Point maxLoc; //匹配计算结果最大值的位置点 double min, max; // double型 src.copyTo(dst); Point temLoc; //定义找到位置的坐标点 minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat()); //找出result矩阵中值最小和最大的点 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函数参数:1.目标图像 2.矩形Rect的起点坐标和矩形长宽 3.线条颜色 4.粗细 5.默认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); }
原图:
模板:
五种匹配结果:(注:这里的result image是归一化后的计算图像,找到与模板匹配的矩形坐标点后分别标画出来的)
由上面结果可以看出,除了第三种方法不能在图像上找到与模板匹配的位置以外,
其他四种方法都能精确的找到车标的准确位置。