【图像处理】C++实现模板匹配


//////////////////////////////////////////////////////////////////////////
	//预先判断——3*3十字中心——区域是否相似,如果相似,则再匹配判断。这样可以减少判断次数。
	//前提:模板大于9*9
	BOOL Judgement(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth); //预先判断

/*
//模板匹配:
//复制图像上的一块模板大小的区域,与模板进行匹配,返回目标物的类型的数据;(点,则返回ShapePoint)
//参数:BYTE *pTempDataBuf —— 从图像上复制模板大小的块
		BYTE *pTemplateBuf —— 模板数据
		int nTempHeight    —— 模板高
		int nTempWidth     —— 模板宽

		int LeftDev —— 模板中边界与目标点的左偏量
		int RightDev—— 模板中边界与目标点的右偏量
*/
	//用来判断是否匹配成功
	BOOL TemplateMatch_SSD(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth);//像素差平方和匹配
	BOOL TemplateMatch_CC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth);//互相关匹配
	BOOL TemplateMatch_NCC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth);//归一化互相关匹配


//像素差平方和匹配
BOOL CTemplateMatching::TemplateMatch_SSD(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth)
{
	int m,n;
	double dSSD = 0;//差平方和
	
    unsigned char tempDatapixel;//像素值
    unsigned char templatepixel;
	
	for (m=0; m<nTemplateHeight; m++)
    {
        for(n=0; n<nTemplateWidth; n++)
        {
			tempDatapixel = pTempDataBuf[TPos(m,n)];//模板块像素
            templatepixel = pTemplateBuf[TPos(m,n)];//模板像素
            dSSD += (double)(tempDatapixel - templatepixel)*(tempDatapixel - templatepixel); //模板块与模板里,所有像素值的平方和
        }
    }
	
	if (dSSD < 100)   //SSD测度的临界值
		return 1;
	else
		return 0;
}
	
//互相关匹配
BOOL CTemplateMatching::TemplateMatch_CC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth)
{
	int m,n;
	double dSigmaST = 0;//中间结果——pTempDataBuf与pTemplateBuf乘积和
    double dSigmaS = 0; //中间结果——pTempDataBuf平方和
    double dSigmaT = 0; //中间结果——pTemplateBuf平方和
	double R = 0;//相似性测度

    unsigned char tempDatapixel;//像素值
    unsigned char templatepixel;

	for (m=0; m<nTemplateHeight; m++)
    {
        for(n=0; n<nTemplateWidth; n++)
        {
			tempDatapixel = pTempDataBuf[TPos(m,n)];//模板块像素
            templatepixel = pTemplateBuf[TPos(m,n)];//模板像素
			dSigmaS += (double)tempDatapixel*tempDatapixel; //模板块里,所有像素值的平方和
            dSigmaT += (double)templatepixel*templatepixel; //模板里,所有像素值的平方和
            dSigmaST += (double)tempDatapixel*templatepixel; //模板块与模板里,所有像素值的平方和
        }
    }

	R = dSigmaST/(sqrt(dSigmaT)*sqrt(dSigmaS));//相似性测度公式
	if (R > 0.85)   //相似性测度的临界值
		return 1;
	else
		return 0;
}

//归一化互相关匹配
BOOL CTemplateMatching::TemplateMatch_NCC(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth)
{
	int m,n;
	double dSumST = 0;//中间结果——(Sxy - S')*(Txy - T')之和
    double dSumS = 0; //中间结果——(Sxy - S')平方和
    double dSumT = 0; //中间结果——(Txy - T')平方和

	double dSPixelSum = 0;
	double dTPixelSum = 0;

	double dNCC = 0;//归一化相似测度
	
    unsigned char tempDatapixel;//像素值
    unsigned char templatepixel;

	unsigned char AveraryDatapixel; //pTempDataBuf平均值
	unsigned char AveraryTemplatepixel;//pTemplateBuf平均值

	for (m=0; m<nTemplateHeight; m++)
    {
        for(n=0; n<nTemplateWidth; n++)
        {
			tempDatapixel = pTempDataBuf[TPos(m,n)];//模板块像素
            templatepixel = pTemplateBuf[TPos(m,n)];//模板像素
			dSPixelSum += tempDatapixel;
			dTPixelSum += templatepixel;
			
        }
    }

	AveraryDatapixel = (unsigned char)dSPixelSum/(nTemplateHeight*nTemplateWidth);
	AveraryTemplatepixel = (unsigned char)dTPixelSum/(nTemplateHeight*nTemplateWidth);

	for (m=0; m<nTemplateHeight; m++)
    {
        for(n=0; n<nTemplateWidth; n++)
        {
			tempDatapixel = pTempDataBuf[TPos(m,n)];//模板块像素
            templatepixel = pTemplateBuf[TPos(m,n)];//模板像素
			dSumS  += (double)(tempDatapixel - AveraryDatapixel)*(tempDatapixel - AveraryDatapixel); 
			dSumT  += (double)(templatepixel - AveraryTemplatepixel)*(templatepixel - AveraryTemplatepixel);
			dSumST += (double)(tempDatapixel - AveraryDatapixel)*(templatepixel - AveraryTemplatepixel);
        }
    }
	
	dNCC = dSumST/(sqrt(dSumS)*sqrt(dSumT));	////归一化相似测度公式
	if (dNCC > 0.85)   //相似性测度的临界值
		return 1;
	else
		return 0;
}

//////////////////////////////////////////////////////////////////////////
/*
//预先判断——3*3十字中心——区域是否相似,如果相似,则再匹配判断。这样可以减少判断次数。
//前提:模板大于9*9
*/
BOOL CTemplateMatching::Judgement(BYTE *pTempDataBuf, BYTE *pTemplateBuf, int nTemplateHeight, int nTemplateWidth)
{
	int m,n;
	double dSum = 0;

	int H = 0;//宽高都分成四份,一份的高度
	int W = 0;//一份的宽度
	
	H = nTemplateHeight/4;
	W = nTemplateWidth/4;

	//第一个3*3(上)
	for (m=H-1;m<H+2;m++)
	{
		for (n=2*W-1;n<2*W+2;n++)
		{
			if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)])
				dSum++;
		}
	}

	//第二个3*3(左)
	for (m=2*H-1;m<2*H+2;m++)
	{
		for (n=W-1;n<W+2;n++)
		{
			if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)])
				dSum++;
		}
	}

	//第三个3*3(中)
	for (m=2*H-1;m<2*H+2;m++)
	{
		for (n=2*W-1;n<2*W+2;n++)
		{
			if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)])
				dSum++;
		}
	}

	//第四个3*3(右)
	for (m=2*H-1;m<2*H+2;m++)
	{
		for (n=3*W-1;n<3*W+2;n++)
		{
			if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)])
				dSum++;
		}
	}

	//第五个3*3(下)
	for (m=3*H-1;m<3*H+2;m++)
	{
		for (n=2*W-1;n<2*W+2;n++)
		{
			if (pTempDataBuf[TPos(m,n)] == pTemplateBuf[TPos(m,n)])
				dSum++;
		}
	}

	//判断条件,达到要求,则表示预匹配准确,反之,预匹配失败,进行下个模板匹配
	if (dSum >= (5-1)*9)   //全部个数3*3*5
		return 1;
	else
		return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值