模板匹配: 模板匹配实际上就是模板图在源图中的平移,因此只能匹配到如出一辙(形态和方向都一致)的局部图像
demo1:ios
#include <opencv2/opencv.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> using namespace cv; int main() { //加载源图像和模板图像 cv::Mat image_source = cv::imread("1.bmp", cv::IMREAD_GRAYSCALE); cv::Mat image_template = cv::imread("7.png", cv::IMREAD_GRAYSCALE); //cv::Mat image_source = cv::imread("lena.jpg", cv::IMREAD_GRAYSCALE); //cv::Mat image_template = cv::imread("template.jpg", cv::IMREAD_GRAYSCALE); cv::Mat image_matched; //模板匹配方法 cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCOEFF_NORMED);//归一化的平方差 //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_SQDIFF);//平方差 //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCORR); //相关性匹配 //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCORR_NORMED);//归一化的相关性匹配 //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCOEFF);//相关性系数匹配 //cv::matchTemplate(image_source, image_template, image_matched, cv::TM_CCOEFF_NORMED);//归一化的相关性系数匹配 double minVal, maxVal; cv::Point minLoc, maxLoc; //寻找最佳匹配位置 //参数:单通道阵列、最小值的指针、最大值的指针、最小位置的指针、最大位置的指针 cv::minMaxLoc(image_matched, &minVal, &maxVal, &minLoc, &maxLoc); cv::Mat image_color; cv::cvtColor(image_source, image_color, CV_GRAY2BGR); //circle()参数:图像(单通道或多通道) cv::circle(image_color, //将匹配到的用圆圈绘制出 cv::Point(maxLoc.x + image_template.cols/2, maxLoc.y + image_template.rows/2), //圆心坐标 100, //圆半径 cv::Scalar(0, 0, 255), //圆的颜色 2, //线条粗细 8, 0); namedWindow("source image",CV_WINDOW_NORMAL); //可调节窗口大小 namedWindow("match result",CV_WINDOW_NORMAL); //可调节窗口大小 namedWindow("target",CV_WINDOW_NORMAL); //可调节窗口大小 cv::imshow("source image", image_source); cv::imshow("match result", image_matched); cv::imshow("target", image_color); cv::waitKey(0); return 0; }
demo2:函数
#include<opencv2/opencv.hpp> #include<iostream> #include<string> using namespace cv; using namespace std; int max_track = 5; int match_method = CV_TM_SQDIFF; String Source_path = "1.bmp"; String Temp_path = "3.png"; String src_window = "Source Window"; String temp_window = "Temp Window"; String Output_window = "Output Window"; Mat src, temp; void Match_Demo(int, void*); int main() { src = imread(Source_path, IMREAD_COLOR); temp = imread(Temp_path, IMREAD_COLOR); if (!src.data || !temp.data) { printf("Could not load the src image or temp image..."); return false; } //namedWindow(src_window, CV_WINDOW_AUTOSIZE); //imshow(src_window, src); namedWindow(temp_window, CV_WINDOW_NORMAL); imshow(temp_window, temp); const char* trackbar_title = "Match Algo Type"; namedWindow(Output_window, CV_WINDOW_NORMAL); createTrackbar(trackbar_title, Output_window, &match_method, max_track, Match_Demo);//建立滑动条并进行初始化 Match_Demo(0, 0); //参数为0,表示进行一次初始化 waitKey(0); return 0; } void Match_Demo(int, void*) //响应滑动条的回调函数 { int height = src.rows - temp.rows + 1; int width = src.cols - temp.cols + 1; Mat result(width, height, CV_32FC1); matchTemplate(src, temp, result, match_method, Mat());//匹配 normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());//标准化 Point minLoc; Point maxLoc; double min, max; Mat dst; src.copyTo(dst); Point tempLoc; minMaxLoc(result, &min, &max, &minLoc, &maxLoc,Mat()); //经过函数minMaxLoc定位最匹配的位置 if (match_method== CV_TM_SQDIFF||match_method==CV_TM_SQDIFF_NORMED) //越小的数值有着更高的匹配结果 { tempLoc = minLoc; } else //其他方法,数值越大匹配效果越好 { tempLoc = maxLoc; } rectangle(dst, Rect(tempLoc.x, tempLoc.y, temp.cols, temp.rows),Scalar(0,0,255),2,8,0);//绘制出矩形,并显示最终结果 rectangle(result, Rect(tempLoc.x, tempLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8, 0); namedWindow("Output window2", CV_WINDOW_NORMAL); imshow("Output window2", dst); namedWindow(Output_window, CV_WINDOW_NORMAL); imshow(Output_window, result); return; }