您的位置:首页 > 其它

模板匹配——在一幅图像中匹配与模板相似的单个或者多个目标

2016-06-01 09:54 507 查看
(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) );

单目标匹配结果:



代码:

[cpp] view
plain copy

print?





#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)多目标匹配:

结果:



代码:

[cpp] view
plain copy

print?





#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); // 匹配方法计算的结果最小值为float

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.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: