模板匹配——在一幅图像中匹配与模板相似的单个或者多个目标
(1)目标匹配函数:
cvMatchTemplate( const CvArr* image, constCvArr* templ,
CvArr* result,int method );
Image 待搜索图像
Templ 模板图像
Result 匹配结果 用来存放通过以下方法计算出滑动窗口与模板的相似值
Method 计算匹配程度的方法
关于匹配方法,使用不同的方法产生的结果的意义可能不太一样,有些返回的值越大表示匹配程度越好,而有些方法返回的值越小表示匹配程度越好
关于参数 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归一化相关系数匹配法
(2):接着就是要找最值以及最值对应的坐标
cvMinMaxLoc()寻找一个矩阵中最大最小值以及相应的坐标
cvMinMaxLoc( constCvArr* arr, double* min_val, double* max_val,
CvPoint* min_locCV_DEFAULT(NULL),
CvPoint* max_locCV_DEFAULT(NULL),
const CvArr* mask CV_DEFAULT(NULL) );
单目标匹配结果:

代码:
- #include <iostream>
- #include "cv.h"
- #include "cxcore.h"
- #include "highgui.h"
- using namespace std;
- int main()
- {
- IplImage *src = cvLoadImage("E:\\study_opencv_video\\lesson16_1\\images\\src.jpg", 0);
- IplImage *srcResult = cvLoadImage("E:\\study_opencv_video\\lesson16_1\\images\\src.jpg", 3);
- IplImage *templat = cvLoadImage("E:\\study_opencv_video\\lesson16_1\\images\\template.png", 0);
- IplImage *result;
- if(!src || !templat)
- {
- cout << "打开图像失败"<< endl;
- return 0;
- }
- int srcW, srcH, templatW, templatH, resultH, resultW;
- srcW = src->width;
- srcH = src->height;
- templatW = templat->width;
- templatH = templat->height;
- if(srcW < templatW || srcH < templatH)
- {
- cout <<"模板不能比原图像小" << endl;
- return 0;
- }
- resultW = srcW - templatW + 1;
- resultH = srcH - templatH + 1;
- result = cvCreateImage(cvSize(resultW, resultH), 32, 1);
- cvMatchTemplate(src, templat, result, CV_TM_SQDIFF);
- double minValue, maxValue;
- CvPoint minLoc, maxLoc;
- cvMinMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc);
- cvRectangle(srcResult, minLoc, cvPoint(minLoc.x + templatW, minLoc.y+ templatH), cvScalar(0,0,255));
- cvNamedWindow("srcResult", 0);
- cvNamedWindow("templat", 0);
- cvShowImage("srcResult", srcResult);
- cvShowImage("templat", templat);
- cvWaitKey(0);
- cvReleaseImage(&result);
- cvReleaseImage(&templat);
- cvReleaseImage(&srcResult);
- cvReleaseImage(&src);
- return 0;
- }
(3)多目标匹配:
结果:

代码:
- #include <iostream>
- #include "cv.h"
- #include "cxcore.h"
- #include "highgui.h"
- using namespace std;
-
- CvPoint getNextMinLoc(IplImage *result, CvPoint minLoc, int maxVaule, int templatW, int templatH)
- {
-
-
- int startX = minLoc.x - templatW;
- int startY = minLoc.y - templatH;
- int endX = minLoc.x + templatW;
- int endY = minLoc.y + templatH;
- if(startX < 0 || startY < 0)
- {
- startX = 0;
- startY = 0;
- }
- if(endX > result->width - 1 || endY > result->height - 1)
- {
- endX = result->width - 1;
- endY = result->height - 1;
- }
- int y, x;
- for(y = startY; y < endY; y++)
- {
- for(x = startX; x < endX; x++)
- {
- cvSetReal2D(result, y, x, maxVaule);
- }
- }
-
- double new_minVaule, new_maxValue;
- CvPoint new_minLoc, new_maxLoc;
- cvMinMaxLoc(result, &new_minVaule, &new_maxValue, &new_minLoc, &new_maxLoc);
- return new_minLoc;
-
- }
- int main()
- {
- IplImage *src = cvLoadImage("E:\\study_opencv_video\\lesson16_1\\images\\src.jpg", 0);
- IplImage *srcResult = cvLoadImage("E:\\study_opencv_video\\lesson16_1\\images\\src.jpg", 3);
- IplImage *templat = cvLoadImage("E:\\study_opencv_video\\lesson16_1\\images\\template.png", 0);
- IplImage *result;
- if(!src || !templat)
- {
- cout << "打开图片失败" << endl;
- return 0;
- }
- int srcW, srcH, templatW, templatH, resultH, resultW;
- srcW = src->width;
- srcH = src->height;
- templatW = templat->width;
- templatH = templat->height;
- if(srcW < templatW || srcH < templatH)
- {
- cout << "模板不能比原图小" << endl;
- return 0;
- }
- resultW = srcW - templatW + 1;
- resultH = srcH - templatH + 1;
- result = cvCreateImage(cvSize(resultW, resultH), 32, 1);
- cvMatchTemplate(src, templat, result, CV_TM_SQDIFF);
- double minValue, maxValue;
- CvPoint minLoc, maxLoc;
- cvMinMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc);
- cvRectangle(srcResult, minLoc, cvPoint(minLoc.x + templatW, minLoc.y+ templatH), cvScalar(0,0,255));
- CvPoint new_minLoc;
-
-
- new_minLoc = getNextMinLoc(result, minLoc, maxValue, templatW, templatH);
- cvRectangle(srcResult, new_minLoc, cvPoint(new_minLoc.x + templatW, new_minLoc.y+ templatH), cvScalar(0,0,255));
-
- new_minLoc = getNextMinLoc(result, new_minLoc, maxValue, templatW, templatH);
- cvRectangle(srcResult, new_minLoc, cvPoint(new_minLoc.x + templatW, new_minLoc.y+ templatH), cvScalar(0,0,255));
- cvNamedWindow("srcResult", 0);
- cvNamedWindow("templat", 0);
- cvShowImage("srcResult", srcResult);
- cvShowImage("templat", templat);
- cvWaitKey(0);
- cvReleaseImage(&result);
- cvReleaseImage(&templat);
- cvReleaseImage(&srcResult);
- cvReleaseImage(&src);
- return 0;
- }
作者:小村长 出处:http://blog.youkuaiyun.com/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流