第10章 模板匹配_opencv

OpenCV 模板匹配

模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术。通常被用于目标检测、相似度分析中, 在目标图像中快速找到待匹配对象的位置。

模板匹配API 函数——cv::matchTemplate()

函数声明如下,

CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
                                 OutputArray result, int method );

image:待匹配的源图像

templ:模板图像

result:保存结果的矩阵,我们可以通过minMaxLoc() 确定结果矩阵的最大值和最小值的位置

minMaxLoc()函数:查找全局最小和最大稀疏数组元素并返回其值及其位置,函数声明如下,

method :模板匹配的算法

在OpenCV中提供了如下6种匹配度量方法,

enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };

1)平方差匹配法CV_TM_SQDIFF

2)归一化平方差匹配法CV_TM_SQDIFF_NORMED

3)相关匹配法CV_TM_CCORR

4)归一化相关匹配法CV_TM_CCORR_NORMED

5)系数匹配法CV_TM_CCOEFF

6)化相关系数匹配法CV_TMCCOEFF_NORMED

通常来讲,随着从简单测量方法(平方差)到更复杂的测量方法(相关系数法),我们可以获得越来越准确的匹配。然而这同时也会以越来越大的计算量为代价。对于选取何种方法,针对不同的匹配情况进行对此分析比较,选取更适合自己应用场景同时兼顾速度和精度的最佳方案。

注意:TM_SQDIFF,TM_SQDIFF_NORMED匹配数值越低表示匹配效果越好,其它四种反之。TM_SQDIFF_NORMED,TM_CCORR_NORMED,TM_CCOEFF_NORMED是标准化的匹配,得到的最大值,最小值范围在0~1之间,其它则需要自己对结果矩阵归一化。

不同的方法会得到差异很大的结果,可以通过测试选择最合适的方法。

模板匹配需要结合minMaxLoc函数一起使用,说明如下,

void minMaxLoc(const SparseMat& a, double* minVal,double* maxVal, int* minIdx=0, int* maxIdx=0);

a: 匹配结果矩阵

&minVal 和 &maxVal: 该矩阵 result 中存储的最小值和最大值

&minLoc 和 &maxLoc: 在结果矩阵中最小值和最大值的坐标

模板匹配功能实现可参考如下代码,

void templateMatching(const Mat& srcImage, const Mat& templateImage)
{
Mat result;
//enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };
matchTemplate(srcImage, templateImage, result, TM_CCOEFF_NORMED);   //最好匹配为1,值越小匹配越差
double minVal = -1;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
//取大值(视匹配方法而定)
//matchLoc = minLoc;
matchLoc = maxLoc;

cv::Mat image_color;
cv::cvtColor(srcImage, image_color, IMREAD_COLOR);
 
Mat mask = image_color.clone(); //绘制最匹配的区域
rectangle(mask, matchLoc, Point(matchLoc.x + templateImage.cols, matchLoc.y + templateImage.rows), Scalar(0, , 0), 2, 8, 0);
imshow(&#;匹配后的图像&#;, mask);
waitKey(0);
  }

模板匹配函数调用示例如下,

//模板匹配处理的是灰度图
cv::Mat templateImage = imread(&#;E:/Image/broad tm plate.jpg&#;, cv::IMREAD_GRAYSCALE /*cv::IMREAD_COLOR*/);
cv::Mat  image = imread(&#;E:/Image/broad.jpg&#;, cv::IMREAD_GRAYSCALE/*cv::IMREAD_COLOR*/);
imshow(&#;templateImage&#;, templateImage);
imshow(&#;image&#;, image);
waitKey(0);
 
templateMatching(image, templateImage);

注意:

1)图像尺寸比例要一致,模板图像是从测试图像大小的图像中截取得到的

2)处理灰度图

3)模板的样式 需要与图像中待匹配的对象 样式一致

OpenCV官方图片,data/broad.jpg测试,测试图像,

模板图像,

模板匹配效果图,


原文链接:,转发请注明来源!