欢迎浏览本博客
大家好,我是:我菜就爱学一名刚刚入行OpenCV的小白
从事方向:计算机视觉
我菜就爱学,分享有误,欢迎大佬指出
本篇介绍:CV中的模板匹配算法
模板匹配是一项在一幅图像中寻找与另一幅图像最匹配部分的技术。模板匹配不是基于直方图,而是通过在输入图像上滑动图像块,对实际的图像块和输入图像进行匹配
说明:matchTemplate()用于匹配出和模板重叠的图像区域
void matchTemplate(InputArray image,InputArray temp1,OutputArray result,int method)
说明:这类方法利用平方差来进行匹配,最好匹配为0,而若匹配越差,匹配值则越大。即计算出来值越小,越相关
说明:计算出来的值越接近0,越相关
说明:这类算法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。即计算出来的值越大越相关。
说明:即计算出来的值越接近1,越相关
说明:这类方法将模板对其均值的相对值与图像对其均值的相关值进行匹配,1标识完美匹配,-1表示最坏匹配,0表示没有任何关系
说明:在一个数组中找到全局最小值和全局最大值。
void minMaxLoc(src, minVal, maxVal, minLoc, maxLoc, mask)
minMaxLoc函数找到最小值和最大值元素值以及它们的位置。极值在整个数组中搜索出来的,或者,如果掩膜不是一个空数组,那么将在一个特殊的数组中搜寻。该函数不能用于多通道数组。如果你需要在所有通道中找到最小或者最大值,那么需要先使用Mat::reshape,将它重构成一个单通道数组。
说明:缩放和移位数组元素,以便指定的标准(alpha)或最小(alpha)和最大(beta)数组值获得指定的值。
void normalize(src,dst,alpha=1, beta=0,NORM_MINMAX, dtype=-1, Mat());
void rectangle(img, Point(j,i), Point(j + img4.cols, i + img4.rows), Scalar(255, 255, 0), 2, 8);
#include
#include
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【效果图】"
Mat g_srcImage; Mat g_templateImage; Mat g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;
void on_Matching(int, void *);
int main()
{
g_srcImage = imread("E:\\Pec\\星空.jpg", 1);
g_templateImage = imread("E:\\Pec\\明月.jpg", 1);
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
imshow("明月", g_templateImage);
createTrackbar("Method:", WINDOW_NAME1, &g_nMatchMethod, g_nMaxTrackbarNum, on_Matching);
on_Matching(0, 0);
waitKey(0);
return 0;
}
void on_Matching(int, void *)
{
Mat srcImage;
g_srcImage.copyTo(srcImage);
//初始化输出的矩阵
int resultImage_cols = g_srcImage.cols - g_templateImage.cols + 1;
int resultImage_rows = g_srcImage.rows - g_templateImage.rows + 1;
g_resultImage.create(resultImage_cols, resultImage_rows, CV_32FC1);
//进行匹配
matchTemplate(g_srcImage, g_templateImage, g_resultImage, g_nMatchMethod);
//归一化
normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());
//通过函数minMaxLoc定位最匹配的位置
double minValue, maxValue;//最大值、最小值
Point minLocation, maxLocation;//最大值位置、最小值位置
Point matchLocation;
minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());
//对于方法SQDIFF 和 SQDIFF_NOMED,越小的数值有更高的匹配结果
if (g_nMatchMethod == TM_SQDIFF || g_nMatchMethod == TM_SQDIFF_NORMED)
{
matchLocation = minLocation;
}
else
{
matchLocation = maxLocation;
}
//画出矩形,显示结果
rectangle(srcImage, matchLocation, Point(matchLocation.x + g_templateImage.cols,
matchLocation.y + g_templateImage.rows), Scalar(0, 255, 0), 2, 8, 0);
rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_templateImage.cols,
matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
imshow(WINDOW_NAME1, srcImage);
imshow(WINDOW_NAME2, g_resultImage);
}
1)原图以及寻找的子图
2)找到明月的效果图以及匹配图
相关系数匹配法(TM_COEFF)