本文章由公号【开发小鸽】发布!欢迎关注!!!
老规矩–妹妹镇楼:
一. 模板匹配
- 模板匹配就是在整个图像区域匹配到与给定子图像的小块区域
- 模板匹配首先需要一个模板图像(子图像)
- 待检测图像
- 工作方法:在待检测图像上,从左到右,从上到下计算模板图像与待检测图像的匹配度。
二. 匹配算法
- 计算平方不同(cv::TM_SQDIFF)
- 归一化计算平方不同(cv::TM_SQDIFF_NORMED)
- 计算相关性(cv::TM_CCORR)
- 归一化计算相关性(cv::TM_CCORR_NORMED)
- 计算相关系数(cv::CCOEFF)
- 归一化计算相关系数(cv:::CCOEFF_NORMED)
三. API分析
cv::matchTemplate(
InputArray image; //原图像, 8-bit或32-bit浮点数图像
InputArray temp, //模板图像
OutputArray result, //输出结果,必须单通道32位浮点数,假设原图像 W X H,模板图像 w x h, 则结果的大小为 W-w+1, H-h+1
int method, //匹配方法
InputArray mask = noArray()
)
四. 代码实现:
/*****模板匹配*****/
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
cv::Mat src, dst, temp;
int match_method = cv::TM_SQDIFF; //比较方法
int match_track = 5; //比较方法数字
void Match_Demo(int, void*);
int main(int argc, char** argv) {
src = cv::imread("1.jpg");
temp = cv::imread("2.jpg"); //模板图像
cv::namedWindow("in", cv::WINDOW_NORMAL);
cv::namedWindow("temp", cv::WINDOW_NORMAL);
cv::namedWindow("match", cv::WINDOW_NORMAL);
cv::imshow("in", src);
cv::imshow("temp", temp);
//用拖条改变比较方式
cv::createTrackbar("Method: ", "match", &match_method, match_track,
Match_Demo);
Match_Demo(0, 0);
cv::waitKey(0);
return 0;
}
void Match_Demo(int, void*) {
//改变比较方法
//准备模板比较参数
//result 结果尺寸, 32FC1
int width = src.cols - temp.cols + 1;
int height = src.rows - temp.rows + 1;
cv::Mat result(width, height, CV_32FC1);
//模板匹配
cv::matchTemplate(src, temp, result, match_method, cv::Mat());
//归一化 0-1之间
cv::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
//在result中找出模板的位置,result中都是数值,根据比较方法分别找出最大值和最小值
cv::Point minLoc;
cv::Point maxLoc;
double min, max;
cv::Point tempLoc;
cv::minMaxLoc(result, &min, &max, &minLoc, &maxLoc, cv::Mat());
//根据比较方法选择最大值,最小值
if (match_method == cv::TM_SQDIFF || match_method == cv::TM_SQDIFF_NORMED)
tempLoc = minLoc;
else
tempLoc = maxLoc;
//找到模板所匹配的位置了,绘制矩形显示,矩形大小为模板图像大小
src.copyTo(dst);
cv::rectangle(dst, cv::Rect(tempLoc.x, tempLoc.y, temp.cols, temp.rows),
cv::Scalar(0, 0, 255), 2, 8);
cv::rectangle(result, cv::Rect(tempLoc.x, tempLoc.y, temp.cols, temp.rows),
cv::Scalar(0, 0, 255), 2, 8);
cv::namedWindow("result", cv::WINDOW_NORMAL);
cv::imshow("result", result);
cv::imshow("match", dst);
}