imgproc模块--模板匹配

1.目的
(1)使用openCV函数matchTemplate()在输入图像中搜索图像块
(2)使用openCV函数minMaxLoc()寻找数组中的最大或者最小值

2.原理
[1]模板匹配
给定一个图像块,搜索配对的图像块,当模板是矩形时候,并不一定所有的矩形块内容都是相关的,在这种情况下,可以利用掩码分离有用信息。

[2]工作原理
输入:原图像,模板
目标:寻找最高的匹配块
这里写图片描述

搜索:比较模板和原图像,通过滑动形式配对模板。
这里写图片描述

搜索过程是从左到右,从上到下,逐个像素像素遍历的过程,通过计算每一次滑动过程的配对效果的好坏确定最佳匹配模块,并将度量结果存储在结果矩阵R中。矩阵R中的每一个位置(x,y)包含了配对度量。
匹配结果

如上图所示,红色圆圈中的亮点区域表示匹配高的区域,黑色的矩形框框表示匹配区域,实际过程中,我们通过minMaxLoc函数在结果矩阵R中寻找最佳匹配。

PS:如果使用掩码,则需要输入原图像,模板,掩码。掩码的维度必须和模板一致,并且拥有CV_8U和CV_32F的深度以及和模板具有相同通道数。CV_8U的掩码必须是二进制值,CV_32F则是在[0,1]之间的小数,掩码和模板对应相乘,获得经过掩码操作的模板。现在只有CV_TM_SQDIFF和CV_TM_CCORR_NORMED支持掩码操作。

[3]配对方法
<1>method=CV_TM_SQDIFF:平方差匹配法
平方差匹配法

<2>method=CV_TM_SQDIFF_NORMED:归一化平方差匹配法
归一化平方差匹配法

<3>method=CV_TM_CCORR:相关匹配法
相关匹配法

<4>method=CV_TM_CCORR_NORMED:归一化相关匹配法
归一化相关匹配法

<5>method=CV_TM_CCOEFF:相关系数匹配法
相关系数匹配法

<6>method=CV_TM_CCOEFF_NORMED:归一化相关系数匹配法
归一化相关系数匹配法

3.部分代码解释
(1)minMaxLoc

    /*
    minMaxLoc参数解释
    result:输入数组
    minVal:数组最小值
    maxVal:数组最大值
    minLoc:数组最小值所在位置
    maxLoc:数组最大值所在位置
    Mat():掩码,没定义则为无掩码操作
    */
    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

(2)matchTemplate

    matchTemplate参数解释
    img:输入图像
    templ:模板
    result:匹配结果,存储匹配过程中的度量值metric value
    type:匹配方法
    */
    matchTemplate(img, templ, result, type);

4.完整代码
(1)CommonInclude.h

#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
#endif

(2)Matching.cpp

#include"CommonInclude.h"

/*
配对方法0,1,2,3,4,5
*/
int type = 0;
int num_type = 5;
Mat img, templ, mask, result;
char windowResultName[] = "Matched";
char windowOriginName[] = "Origin";

void Matching(int, void*){
    Mat display_img = img.clone();
    /*
    matchTemplate参数解释
    img:输入图像
    templ:模板
    result:匹配结果,存储匹配过程中的度量值metric value
    type:匹配方法
    */
    matchTemplate(img, templ, result, type);
    //归一化
    normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

    double minVal, maxVal;
    Point minLoc, maxLoc;
    Point matchLoc;
    //使用minMaxLoc函数确定数组的最值以及位置
    /*
    minMaxLoc参数解释
    result:输入数组
    minVal:数组最小值
    maxVal:数组最大值
    minLoc:数组最小值所在位置
    maxLoc:数组最大值所在位置
    Mat():掩码,没定义则为无掩码操作
    */
    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
    if( type == CV_TM_SQDIFF || type == CV_TM_SQDIFF_NORMED )
    {
        matchLoc = minLoc;
    }else{
        matchLoc = maxLoc;
    }
    //绘制匹配的区域
    rectangle(display_img, matchLoc, Point(matchLoc.x+templ.cols, matchLoc.y+templ.rows), Scalar(0,0,0), 2, 8);
    rectangle(result, matchLoc, Point(matchLoc.x+templ.cols, matchLoc.y+templ.rows), Scalar(0,0,0), 2, 8);
    imshow(windowOriginName, img);
    imshow(windowResultName,display_img);
    imshow("result", result);
}

int main(int argc, char**argv){
    if(argc<3){
        cout << "more parameters are required!!!" << endl;
        return(-1);
    }
    img = imread(argv[1]);
    templ = imread(argv[2]);
    //mask = imread(argv[3]);
    if(!img.data || !templ.data){
        cout << "error to read images!!!" << endl;
        return(-1);
    }
    namedWindow(windowResultName, CV_WINDOW_AUTOSIZE);
    const char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
    createTrackbar(trackbar_label, windowResultName,&type, num_type, Matching);
    Matching(0,0);
    waitKey(0);
    return(0);
}

参考文献
1.http://docs.opencv.org/master/de/da9/tutorial_template_matching.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值