图像匹配之不变矩匹配法

 不变矩匹配法     TM算法 具有平移、旋转、尺寸不变性
 
 
                                                                                                                                                                                p+q>=2
 
 
 
归一化公式:
 
算法过程:计算 分别计算模板和原图的7个不变矩 ,根据归一化公式得出相似度。

代码如下:
   (取b通道作为检测的通道)
//源文件.cpp
<pre name="code" class="cpp">void Ctry::OnTryTyr1()
{
	 //TODO:  在此添加命令处理程序代码
	IplImage* TemplateSrc = cvLoadImage("D:\\13.jpg");            //模板图像
	IplImage* Src = cvLoadImage("D:\\24.jpg");                            //原图
	int        i, j;                      //循环变量
	double  dbr;                   //原图,模板的相似度
	double temp;           // 临时变量
	double Su00, Su02, Su20, Su11, Su30, Su12, Su21, Su03;  
	double Tu00, Tu02, Tu20, Tu11, Tu30, Tu12, Tu21, Tu03;
	double  dbR;                            //原图,模板的相似度
	double  Sa[8], Ta[8];                //原图,模板7个不变矩,二阶,三阶重心矩
	double  dSigmaST = 0;            //中间结果
	double  dSigmaT = 0;
	double  dSigmaS = 0;
	//计算重心x,y坐标
	CalBarycenter(Src, &nBarycenterX, &nBarycenterY);
	CalBarycenter(TemplateSrc, &nTBarycenterX, &nTBarycenterY);

	//计算二阶,三阶矩(规格化)
	Su00 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 0, 0);
	Su02 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 0, 2) / pow(Su00,2);
	Su20 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 2, 0) / pow(Su00, 2);
	Su11 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 1, 1) / pow(Su00, 2);
	Su30 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 3, 0) / pow(Su00, 2.5);
	Su12 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 1, 2) / pow(Su00, 2.5);
	Su21 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 2, 1) / pow(Su00, 2.5);
	Su03 = BarycenterMoment(Src, &nBarycenterX, &nBarycenterY, 0, 3) / pow(Su00, 2.5);

	Tu00 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 0, 0);
	Tu02 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 0, 2) / pow(Tu00, 2);
	Tu20 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 2, 0) / pow(Tu00, 2);
	Tu11 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 1, 1) / pow(Tu00, 2);
	Tu30 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 3, 0) / pow(Tu00, 2.5);
	Tu12 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 1, 2) / pow(Tu00, 2.5);
	Tu21 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 2, 1) / pow(Tu00, 2.5);
	Tu03 = BarycenterMoment(TemplateSrc, &nTBarycenterX, &nTBarycenterY, 0, 3) / pow(Tu00, 2.5);

	Sa[1] = Su02 + Su20;
	Sa[2] = (Su20 - Su02)*(Su20 - Su02) + 4 * Su11*Su11;
	Sa[3] = pow((Su30 - 3 * Su12), 2) + pow((3 * Su21 - Su03), 2);
	Sa[4] = pow((Su30 + Su12), 2) + pow((Su21 + Su03), 2);
	Sa[5] = (Su30 - 3 * Su12)*(Su30 + Su12)*(pow((Su30 + Su12), 2) - 3 * pow((Su21 + Su03), 2)) + (3 * Su21 - Su03)*(Su21 + Su03)*(3 * pow((Su30 + Su12), 2) - pow((Su21 + Su03), 2));
	Sa[6] = (Su20 - Su02)*(pow((Su30 + Su12), 2) - pow((Su21 + Su03), 2)) + 4 * Su11*(Su30 + Su12)*(Su21 + Su03);
	Sa[7] = (3 * Su21 - Su03)*(Su30 + Su12)*(pow((Su30 + Su12), 2) - 3 * pow((Su21 + Su03), 2)) + (Su30 - 3 * Su12)*(Su21 + Su03)*(3 * pow((Su30 + Su12), 2) - pow((Su21 + Su03), 2));

	Ta[1] = Tu02 + Tu20;
	Ta[2] = (Tu20 - Tu02)*(Tu20 - Tu02) + 4 * Tu11*Tu11;
	Ta[3] = pow((Tu30 - 3 * Tu12), 2) + pow((3 * Tu21 - Tu03), 2);
	Ta[4] = pow((Tu30 + Tu12), 2) + pow((Tu21 + Tu03), 2);
	Ta[5] = (Tu30 - 3 * Tu12)*(Tu30 + Tu12)*(pow((Tu30 + Tu12), 2) - 3 * pow((Tu21 + Tu03), 2)) + (3 * Tu21 - Tu03)*(Tu21 + Tu03)*(3 * pow((Tu30 + Tu12), 2) - pow((Tu21 + Tu03), 2));
	Ta[6] = (Tu20 - Tu02)*(pow((Tu30 + Tu12), 2) - pow((Tu21 + Tu03), 2)) + 4 * Tu11*(Tu30 + Tu12)*(Tu21 + Tu03);
	Ta[7] = (3 * Tu21 - Tu03)*(Tu30 + Tu12)*(pow((Tu30 + Tu12), 2) - 3 * pow((Tu21 + Tu03), 2)) + (Tu30 - 3 * Tu12)*(Tu21 + Tu03)*(3 * pow((Tu30 + Tu12), 2) - pow((Tu21 + Tu03), 2));

	for (int i = 1; i < 8; i++)
	{
		temp = Sa[i] * Ta[i];
		dSigmaST += temp;
		dSigmaT += pow(Ta[i], 2);
		dSigmaS += pow(Sa[i], 2);
	}
	dbr = dSigmaST / (sqrt(dSigmaS)*sqrt(dSigmaT));
          
        //显示匹配的相似度
	CString str;
	str.Format(_T("%lf"), dbr);
	AfxMessageBox(str);
}
void Ctry::CalBarycenter(IplImage* src, int *nBarycenterX0, int *nBarycenterY0)
{
	CvScalar  pixel0;
	double m00=0, m10=0, m01=0;           //0次矩m00, x方向一次矩m01,  y方向一次矩m10
	double   temp;        //临时变量
	//求0次矩m00, x方向一次矩m01,  y方向一次矩m10
	for (int j = 0; j < src->height; j++)
	{
		for (int i = 0; i <src->width; i++)
		{
			pixel0 = cvGet2D(src, j, i);
			m00 += pixel0.val[0];
			m10 += i*pixel0.val[0];
			m01 += j*pixel0.val[0];
		}
	}
	//重心x,y坐标
	*nBarycenterX0 = (int)(m10 / m00 + 0.5);
	*nBarycenterY0 = (int)(m01 / m00 + 0.5);
}


double Ctry::BarycenterMoment(IplImage* src, int *nBarycenterX0, int *nBarycenterY0, int ip, int jp)
{
	double temp;      //临时变量
	double dbImageMoment = 0;       //图像的矩
	CvScalar  pixel1;
	//力矩的计算
	for (int j = 0; j < src->height; j++)
	{
		for (int i = 0; i < src->width; i++)
		{
			pixel1 = cvGet2D(src, j, i);
			temp = pow((double)(i - *nBarycenterX0), ip)*pow((double)(j - *nBarycenterY0), jp);
			temp = temp*pixel1.val[0];
			dbImageMoment = dbImageMoment + temp;
		}
	}
	return dbImageMoment;
}

//头文件.h
public:
	void CalBarycenter(IplImage* src, int *nBarycenterX0, int *nBarycenterY0);   
	double BarycenterMoment(IplImage* src, int *nBarycenterX0, int *nBarycenterY0, int ip, int jp);

public:
	//原图模板重心x,y坐标值
	int        nBarycenterX, nBarycenterY;
	int        nTBarycenterX, nTBarycenterY;


 
 
匹配结果:







  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值