Fork me on GitHub

【My Project】图像匹配平台一

图像匹配 平台一

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/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,请尊重作者的

posted @ 2011-03-29 10:20  SkySeraph  阅读(4026)  评论(0编辑  收藏  举报