15.1 引言
模板匹配就是在给定的图像中,通过计算模板与图片对应区域的匹配度,查找与模板最相似的区域。模板匹配的核心其实就是将模板与源图像的每个区域进行比较,逐像素滑动。从本质上讲,是将模板在源图像上进行卷积,创建新的图像或矩阵,其中每个像素值表示模板与源图像中相应区域之间的相似性。分析结果图像,可以通过峰值找到与模板匹配的紧缺位置。
15.2 匹配度量方式
15.2.1 平方差TM_SQDIFF
模板与源图像对应像素值的平方差的和。值越小匹配度越高(0)
15.2.2 归一化平方差TM_SQDIFF_NORMED
值越小匹配度越高(0)
15.2.3 相关性TM_CCORR
模板与源图像对应像素值的乘积和。值越大匹配度越高
15.2.4 归一化相关性TM_CCORR_NORMED
值越大匹配度越高,越接近1,效果越好。
15.2.5 相关性系数TM_CCOEFF
模板与源图像对应像素将去其各自区域的均值后的像素值的乘积和。最佳匹配结果在值等于1处,最差匹配结果在值等于-1处,值等于0直接表示二者不相关。
15.2.6 归一化相关性系数TM_CCOEFF_NORMED
正值表示匹配的结果较好,负值则表示匹配的效果较差。 越接近1,效果越好
15.3 相关API
·void matchTemplate( InputArray image, OutputArray templ, OutputArray result, int method, InputArray mask=noArray())
参数 | 含义 | |
作用 | 根据模板在一幅图像中找到匹配的区域 | |
输入 |
| 源图像,必须是8bit或32bit浮点数图像 |
| 模板图像,类型与源图像一致 | |
| 输出保存结果的矩阵,32F类型。假设源图像W*H,模板w*h,则结果矩阵大小为W-w+1*H-h+1, | |
| 使用的匹配方式,见15.2 | |
| ||
返回值 | void | 无 |
15.4 代码示例
Mat src, temp, dst;
int matchMethod = TM_SQDIFF;
int maxTrack = 5;
const char* INPUTWIN = "srcimg";
const char* OUTPUTWIN = "dstimg";
const char* MATCH = "tempimg";
void matchCallback(int,void*)
{
int width = src.cols - temp.cols + 1;
int height = src.rows - temp.rows + 1;
Mat result(width, height,CV_32FC3);
matchTemplate(src,temp,result,matchMethod);
//遭到匹配上的位置
Point minPos;
Point maxPos;
double min, max;
src.copyTo(dst);
Point tempPos;
minMaxLoc(result,&min,&max,&minPos,&maxPos,Mat());
if (matchMethod == TM_SQDIFF || matchMethod == TM_SQDIFF_NORMED)
{
tempPos = minPos;
}
else
{
tempPos = maxPos;
}
//矩形绘制
rectangle(dst,Rect(tempPos.x, tempPos.y,temp.cols,temp.rows),Scalar(0,0,255),2);
rectangle(result, Rect(tempPos.x, tempPos.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2);
imshow(OUTPUTWIN, dst);
imshow(MATCH, result);
}
int main(int argc, char** argv)
{
//源图像
src = imread("D:\\testimg\\CSet12\\lena.png");
//模板图像
temp = imread("D:\\testimg\\CSet12\\lenaTemp.png");
if (src.empty()|| temp.empty())
{
printf("Could not load the image...\n");
return -1;
}
else;
namedWindow(INPUTWIN, WINDOW_AUTOSIZE);
imshow(INPUTWIN, src);
namedWindow(OUTPUTWIN, WINDOW_AUTOSIZE);
namedWindow(MATCH, WINDOW_AUTOSIZE);
imshow("temp",temp);
const char* trackbarTitle = "Method";
createTrackbar(trackbarTitle, OUTPUTWIN,&matchMethod,maxTrack,matchCallback);
matchCallback(0,0);
waitKey(0);
return 0;
}
15.5 模板匹配的不足
- 不同的图像需要需要按实际测验匹配方式的有效性;
- 目标与模板大小不一致时,小模板无法检测大目标;
- 目标与模板方向不一致,会导致无法识别;
不具有旋转不变性、不具有尺度不变性