您的位置:首页 > 其它

【My Project】图像匹配平台一

2011-03-29 10:20 190 查看
图像匹配 平台一

SkySeraph Mar 29th 2011 HQU

Email:zgzhaobo@gmail.com QQ:452728574

Latest Modified Date:Mar 29th 2011 HQU

一 工具:VS2010+OpenCV2.0

语言:CPP

二 原理:采用的是归一化积相关灰度匹配

原理可参考:http://wenku.baidu.com/view/48b0e93467ec102de2bd89eb.html

三 核心源码

执行



//----------------------------------------------
////模板匹配
void CTemplateMatchDlg::OnBnClickedTemplatematch()
{
//  验证
if(pTmpImg == NULL)
{
AfxMessageBox(_T("请先选择模板!"));
return;
}
if(iTmpImgType!=1 && iTmpImgType!=-1 )
{
AfxMessageBox(_T("模板必须是灰度/二值图像,请进行灰度化转换!"));
return;
}
//  验证模板
int h = pTmpImg->height;
int w = pTmpImg->width;
if(w > IMAGE_WIDTH || h > IMAGE_HEIGHT)
{
AfxMessageBox(_T("模板尺寸大于源图像尺寸,请重新选择模板!"));
return;
}

//  更改光标形状
BeginWaitCursor();

//  进行模板匹配
TemplateMatch(pWorkImg,pTmpImg);

//  显示
ShowImage(pWorkImg, IDC_PICSHOW3);

//  恢复光标形状
EndWaitCursor();

}



匹配

//----------------------------------------------
////模板匹配:归一化积相关灰度匹配
/*----------------------------------------------
/----------------------------------------------*/
void CTemplateMatchDlg::TemplateMatch(IplImage* img, IplImage* tmpImg)
{
//循环变量
int i, j, m, n;

double dSumT; //模板元素的平方和
double dSumS; //图像子区域元素的平方和
double dSumST; //图像子区域和模板的点积

//响应值/相似性测度
double R;

//记录当前的最大响应
double MaxR;

//最大响应出现位置
int nMaxX = 0;
int nMaxY = 0;

//源图像的高、宽
int nHeight = img->width;
int nWidth = img->height;
int nStep = img->widthStep;
uchar* cData;
cData = (uchar*)img->imageData;
//模板的高、宽
int nTplHeight = tmpImg->width;
int nTplWidth = tmpImg->height;
int nTplStep = tmpImg->widthStep;
uchar* cTplData;
cTplData = (uchar*)tmpImg->imageData;

//计算 dSumT:模板元素的平方和
dSumT = 0;
for (m = 0;m < nTplHeight ;m++)
{
for(n = 0;n < nTplWidth ;n++)
{
// 模板图像第m行,第n个象素的灰度值
int nGray = cTplData[m*nTplStep+n];
dSumT += (double)nGray*nGray;
}
}

//找到图像中最大响应/最大相似性的出现位置
MaxR = 0;
for (i = 0;i < nHeight - nTplHeight +1 ;i++)
{
for(j = 0;j < nWidth - nTplWidth + 1;j++)
{
dSumST = 0;
dSumS = 0;

for (m = 0;m < nTplHeight ;m++)
{
for(n = 0;n < nTplWidth ;n++)
{
// 原图像第i+m行,第j+n列象素的灰度值
int nGraySrc  = cData[(i+m)*nStep+(j+n)];

// 模板图像第m行,第n个象素的灰度值
int nGrayTpl = cTplData[m*nTplStep+ m];

dSumS += (double)nGraySrc*nGraySrc;
dSumST += (double)nGraySrc*nGrayTpl;
}
}

R = dSumST / ( sqrt(dSumS)*sqrt(dSumT));//计算相关响应/相似性

//与最大相似性比较
if (R > MaxR)
{
MaxR = R;
nMaxX = j;
nMaxY = i;
}
}
}

//清空目标图像/对目标图像的像素进行赋值
if(img)
for (m = 0;m < nHeight ;m++)
{
for(n = 0;n < nWidth ;n++)
{
cData[m*nStep+n] = cData[m*nStep+n]/2;  //像素值减半
}
}
//cvZero(img);

//int nStep2 = img->widthStep;
//uchar* cData2;
//cData2 = (uchar*)img->imageData;

//将找到的最佳匹配区域复制到目标图像
for (m = 0;m < nTplHeight ;m++)
{
for(n = 0;n < nTplWidth ;n++)
{
int nGray = cTplData[m*nTplStep+n];
//cData[m*nStep+n] = 0;
cData[(nMaxY+m)*nStep+(nMaxX+n)] = RGB(nGray, nGray, nGray);
}
}
}


四 效果

界面



处理结果



Author: SKySeraph

Email/GTalk: zgzhaobo@gmail.com QQ:452728574

From: http://www.cnblogs.com/skyseraph/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,请尊重作者的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: