视觉图像:模板匹配一
绪:
模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术,模板匹配不是基于直方图的,而是通过在输入图像上滑动图像块,对实际的图像块和输入图像进行匹配的一种匹配方法。
操作方法
- 01
定义: 模板匹配是在一副图像中寻找到与给定目标模板图像的技术。 在匹配过程中有两个主要因素:原始图像I,模板图像T。 为了在原始图像I上检测到与模板图像T最匹配的区域,需要在原始图像I上滑动模板窗口,每次需要将模板图像T在原始图像I上滑动一个像素大小(从左至右,从上至下),每次移动后计算出其相似度来表征匹配结果的好与坏。 将每个位置的匹配结果存储在R矩阵中,该矩阵的每一个点的亮度表示与模板图像T的匹配程度。 通过minMaxLoc函数找到R矩阵中的最大值、最小值。
- 02
匹配方法: 常见的相似度匹配方法: 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,归一化相关系数匹配法
- 03
相似性匹配结果矩阵R的大小: 模板图像在原始图像上移动一个像素,并将计算出来的相似度数据存储在R矩阵中,那么在整个原始图像上每行横向移动只需移动raw_img.cols-mask_img_cols+1次;每列纵向移动只需移动raw_img.cols-mask_img.cols+1次;
- 04
OpenCV模板匹配函数:matchTemplate() 格式:void matchTemplate(inputArray image,inputArray templ,outputArray result,int method) 功能:用于匹配出和模板重叠的图像区域 参数: inputArray image,待搜索的图像,且需为8位或32位浮点型图像; inputArray templ,搜索模板,需和源图像有一样的数据类型,且尺寸不能大于源图像。 outputArray result,比较结果的映射图像,其必须为单通道、32位浮点型图像,如果图像尺寸是W*H,而templ的尺寸是w*h,则此参数result一定是(W-w+1)x(H-h+1) ; int method,指定的匹配方法; 常见的匹配方法: (1)平方差匹配法 method=TM_SQDIFF (2)归一化平方差匹配法 method=TM_SQDIFF_NORMED (3)相关匹配法 method=TM_CCORR (4)归一化相关匹配法 method=TM_CCORR_NORMED (5)系数匹配法 method=TM_CCOEFF (6)归一化相关系数匹配法 method=TM_CCOEFF_NORMED 【注】:模板匹配的方法适用于模板很小,而原图像很大的情况下,不然得到的图像会很小,而且只是原图像左上的一部分,如果要检测的物体在右下角,可能在目标图中框不完全要检测的物体。
- 05
OpenCV函数:minMaxLoc() 功能:找到矩阵中全局最大值和最小值;
- 06
OpenCV模板匹配例程: #include <opencv2\opencv.hpp> using namespace std; using namespace cv; void match(Mat _raw_img,Mat _mask_img); int main( int argc, char** argv ) { Mat raw_img; Mat mask_img; raw_img = imread("raw.jpg" ); if( raw_img.empty() ) { cerr << "Cannot load file " << "raw.jpg" << endl; return -1; } mask_img = imread("mask.jpg"); //读取模板图像"mask.jpg" if( mask_img.empty()) { cerr << "Cannot load file " <<"mask.jpg" << endl; return -1; } match( raw_img, mask_img); imshow( "result", raw_img ); imshow( "template", mask_img ); //显示结果 /* wait until user press a key to exit */ waitKey( 0 ); return 0; } void match(Mat _raw_img,Mat _mask_img) { Mat res_img; Mat mask; Point min_loc_p, max_loc_p; double min_val, max_val; int res_cols = _raw_img.cols - _mask_img.cols + 1; int res_rows = _raw_img.rows - _mask_img.rows + 1; res_img = cvCreateImage( cvSize(res_cols,res_rows), IPL_DEPTH_32F, 3 ); matchTemplate( _raw_img, _mask_img, res_img,CV_TM_SQDIFF_NORMED ); //归一化平方差匹配法 minMaxLoc( res_img, &min_val, &max_val, &min_loc_p, &max_loc_p,mask); rectangle( _raw_img, cvPoint( min_loc_p.x, min_loc_p.y ), cvPoint( min_loc_p.x + _mask_img.cols, min_loc_p.y + _mask_img.rows ), cvScalar( 255, 255, 255, 0 ), 1, 0, 0 ); }