图像模板匹配

        模板匹配是在一幅图像中寻找到与给定目标模板图像的技术。在匹配过程中有两个主要因素:原图像I,模板图像T。为了在I上检测到与T最匹配的区域,需要在I上滑动模板窗口,每次需要将T在I上滑动一个像素大小(从左至右,从上至下),每次移动后,计算出其相似度来表征匹配结果的好与坏。依次将每个位置的匹配结果存储在R矩阵中,该矩阵的每一个点的亮度表示与模板T的匹配程度(越亮,匹配程度越高)。通过 minMaxLoc 函数可以找到R矩阵中的最大(小)值。

   匹配方法:

   a)method=CV_TM_SQDIFF  

   b)method=CV_TM_SQDIFF_NORMED 

   c)method=CV_TM_CCORR 

   d)method=CV_TM_CCORR_NORMED 

   e)method=CV_TM_CCOEFF  

   f)method=CV_TM_CCOEFF_NOR


以下是实现图像匹配的例程,其中定义了一个函数match实现匹配的具体过程:

// Templatematch.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "opencv2/opencv.hpp" 
using namespace std;
using namespace cv;

void match(Mat img,Mat tem);

int main( int argc, char** argv )
{   
	Mat img;   
	Mat tem;   
	
	 
	img = imread("xiaobei.jpg" );                    //读取原图像"xiaobei.jpg"

	if( img.empty() ) {                                     //判断是否读取成功    
		cerr <<  "Cannot load file " << "xiaobei.jpg" << endl;   
		return -1;    
	}   
  
	tem = imread("mask.jpg");                       //读取模板图像"mask.jpg"
 
	if( tem.empty()) {   
		cerr <<  "Cannot load file " <<"mask.jpg" << endl;   
		return -1;   
	}   

	match( img, tem);                         
	 
	imshow( "result", img );   
	imshow( "template", tem );                      //显示结果

	/* wait until user press a key to exit */   
	cvWaitKey( 0 );    
	return 0;   
}
void match(Mat img,Mat tem)
{
	Mat res;   
	Mat mask;  
	Point        minloc, maxloc;   
	double        minval, maxval;   
   
	int res_cols  = img.cols - tem.cols + 1;   
	int res_rows = img.rows - tem.rows + 1;   	
        res = cvCreateImage( cvSize(res_cols,res_rows), IPL_DEPTH_32F, 1 );
        matchTemplate( img, tem, res,CV_TM_SQDIFF_NORMED ); //归一化平方差匹配法
        minMaxLoc( res, &minval, &maxval, &minloc, &maxloc,mask);
        rectangle( img, cvPoint( minloc.x, minloc.y ), cvPoint( minloc.x + tem.cols, minloc.y + tem.rows ), 
                   cvScalar( 255, 255, 255, 0 ), 1, 0, 0 );  
}






演示效果:

模板:

       

结果:   



这里主要对以下两点进行分析:

1)

        int res_cols  = img.cols - tem.cols + 1;   
	       int res_rows = img.rows - tem.rows + 1; 
结果矩阵R的计算,我是这样理解的:文章开篇提到模板图像每次在原图像上移动一个像素,并将计算出来的相似度存储在R中,那么在整个图像上每行横向移动只需移动img.rows-tem.rows个长度,因此每行共计算出img.rows-tem.rows+1个结果。同理,每列共计算出img.cols-tem.cols+1个结果。

 2)两个函数:




未完待续~~~~~~~~~



















#模板匹配 import cv2 as cv import numpy as np def template_demo(): dog = cv.imread("E:/opencv/picture/dog.jpg") dog_nose = cv.imread("E:/opencv/picture/nose.jpg") cv.imshow("dog",dog) result = cv.matchTemplate(dog,dog_nose,cv.TM_CCORR_NORMED) h,w =dog_nose.shape[:2] min_val,max_val,min_loc,max_loc=cv.minMaxLoc(result) pt1 = max_loc pt2 = (pt1[0]+w,pt1[1]+h) cv.rectangle(dog,pt1,pt2,(0,255,0),2) cv.imshow("match",dog) print(result) #src = cv.imread("E:/opencv/picture/dog.jpg") #cv.imshow("inital_window",src) template_demo() cv.waitKey(0) cv.destroyAllWindows() 分析: 模板匹配通常用于目标检测。本文我们检测狗图片的鼻子。 • 我们需要两个主要组件: 1. 源图像(I):我们期望找到与模板图像匹配的图像 2. 模板图像(T):将与模板图像进行比较的补丁图像 1. result = cv.matchTemplate(dog,dog_nose,cv.TM_CCORR_NORMED) void cv::matchTemplate( cv::InputArray image, // 待匹配图像W*H cv::InputArray templ, // 模板图像,和image类型相同, 大小 w*h cv::OutputArray result, // 匹配结果图像, 类型 32F, 大小 (W-w+1)*(H-h+1) int method // 用于比较的方法 ); 其中method有: TM_SQDIFF_NORMED匹配数值越低表示匹配效果越好 TM_CCORR_NORMED,TM_CCOEFF_NORMED匹配数值越大表示匹配效果越好 result参数:(保存各个点匹配结果的参数) 模板匹配函数cvMatchTemplate依次计算模板与待测图片的重叠区域的相似度,并将结果存入映射图像result当中,也就是说result图像中的每一个点的值代表了一次相似度比较结果 模板在待测图像上每次在横向或是纵向上移动一个像素,并作一次比较计算 我们可以通过cv.minMaxLoc函数来确定结果矩阵的最大值和最小值的位置。 2. cv.minMaxLoc(result) 返回result数值中最小值以及最小值所在的位置和最大值以及最大值所在的位置。 3. 当知道哪个点匹配度最高时这个时候我们需要用矩阵把模板给标出来 C++: void rectangle(Mat& img, Point pt1,Point pt2,const Scalar& color, int thickness=1, int lineType=8, int shift=0) 第一个参数:要在哪个图像上画? 第二个参数:矩阵的左上角点坐标 第三个参数:矩阵的右下角点坐标 第四个参数:颜色
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值