OpenCV实现之模板匹配(Template Matching)

 

1. 什么是模板匹配?

模板匹配是一种用于在源图像S中寻找定位给定目标图像T(即模板图像)的技术。其原理很简单,就是通过一些相似度准则来衡量两个图像块之间的相似度Similarity(S,T)。

 

. 模板匹配方法的优缺点:

                 优点:简单、直接

                 缺点:不具有旋转不变性、不具有尺度不变性


 首先,参看上图。假设褐色的大图为待测图片,红色小图为模板图片。


模板匹配的工作方式

   模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。

   假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:

 (1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;

 (2)用临时图像和模板图像进行对比,对比结果记为c;

 (3)对比结果c,就是结果图像(0,0)处的像素值;

 (4)切割输入图像从(0,1)至(10,11)的临时图像,对比,并记录到结果图像;

 (5)重复(1)~(4)步直到输入图像的右下角。

   大家可以看到,直方图反向投影对比的是直方图,而模板匹配对比的是图像的像素值;模板匹配比直方图反向投影速度要快一些,但是我个人认为直方图反向投影的鲁棒性会更好。

 备注: 滑动的意思是图像块一次移动一个像素(从左往右,从上往下). 在每一个位置, 都进行一次度量计算来表明它是 “好” 或 “坏” 地与那个位置匹配 (或者说块图像和原图像的特定区域有多么相似).

 

C++: void matchTemplate(InputArray image,InputArray templ, OutputArray result, int method)

image:  搜索对象图像 It must be 8-bit or 32-bit floating-point.

templ:模板图像,小于image,并且和image有相同的数据类型

result:比较结果必须是单通单32位浮点数

method:比较算法总共有六种如下所示

method=CV_TM_SQDIFF_NORMED

method=CV_TM_CCORR_NORMED

1)Square difference matching method (method = CV_TM_SQDIFF) 平方差

R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2

2)Correlation matching methods (method = CV_TM_CCORR) 互相关

R(x,y)= \sum _{x',y'} (T(x',y')  \cdot I(x+x',y+y'))

3)Correlation coefficient matching methods (method = CV_TM_CCOEFF)  相关系数

R(x,y)= \sum _{x',y'} (T'(x',y')  \cdot I(x+x',y+y'))

\begin{array}{l} T'(x',y')=T(x',y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}

4)上述三种方法的归一化形式(目的是为了减少光照的影响)

 

 1.result中数据的含义。

       模板匹配函数cvMatchTemplate依次计算模板与待测图片的重叠区域的相似度,并将结果存入映射图像result当中,也就是说result图像中的每一个点的值代表了一次相似度比较结果。

      2.result的尺寸大小。

       如图可知,模板在待测图像上每次在横向或是纵向上移动一个像素,并作一次比较计算,由此,横向比较W-w+1次,纵向比较H-h+1次,从而得到一个 (W-w+1)×(H-h+1)维的结果矩阵,result即是用图像来表示这样的矩阵,因而图像result的大小为(W-w+1)×(H-h+1)。

       3.如何result中获得最佳匹配区域

       使用函数cvMinMaxLoc(result,&min_val,&max_val,&min_loc,&max_loc,NULL); 从result中提取最大值(相似度最高)以及最大值的位置(即在result中该最大值max_val的坐标位置max_loc,即模板滑行时左上角的 坐标,类似于图中的坐标(x,y)。)

         由此得到:rect=cvRect(max_loc.x,max_loc.y,tmp->width,tmp->height);rect表示的矩形区域即是最佳的匹配区域。

 

确定矩形位置是使用的是max_loc,原来这个跟匹配时采用的方法参数有关,具体如下:

关于参数method:

CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。

CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。

CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。

CV_TM_SQDIFF_NORMED 归一化平方差匹配法

CV_TM_CCORR_NORMED 归一化相关匹配法

CV_TM_CCOEFF_NORMED 归一化相关系数匹配法

代码实现:

 

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;
/**********************************************************
 *
 * input:
 * argc-----current mass center point
 * argv-----previous mass center point
 *
 **********************************************************/
int main(int argc,char **argv)
{
    Mat pFrame;//read frame from video
    Mat pFrameGray;
    VideoCapture pCapture;
    pCapture.open("./plane.mov");
    if(!pCapture.isOpened())
    {
        cout<<"open video error"<<endl;
        return -1;
    }

    Mat temp;
    temp = imread("./plane.png",0);//read a gray template
    if(!temp.data)
    {
        cout<<"read template pic error"<<endl;
        return -1;
    }

    namedWindow("template tracking");
    moveWindow("template tracking",100,100);

    Mat result;//save template match result
    while(1)
    {
        pCapture.read(pFrame);//read a frame from video
        cvtColor(pFrame,pFrameGray,CV_BGR2GRAY);
     
       matchTemplate(pFrameGray,temp,result,TM_SQDIFF);

        //location
        double minValue;
        double maxValue;
        //location point
        Point minLocP;
        Point maxLocP;
        //match locat
        minMaxLoc(result,&minValue,&maxValue,&minLocP,&maxLocP,Mat());

        rectangle(pFrame,Rect(minLocP.x,minLocP.y,temp.cols,temp.rows),Scalar(0,0,255),2,8,0);
        
        imshow("template tracking",pFrame);
        waitKey(33);

    }
    return 0;
}

其中template为:

                           

实验最后效果如下图所示

可以看出效果还是很不错的

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

血_影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值