定义如下:
① (p+q)阶不变矩定义:
② 对于数字图像,离散化,定义为:
③ 归一化中心矩定义:
④Hu矩定义
-------------------------------------------------------------------------------------------------------------------------------
二 实现(源码)
①自编函数模块
//#################################################################################//
double M[7] = {0}; //HU不变矩
bool HuMoment(IplImage* img)
{
int bmpWidth = img->width;
int bmpHeight = img->height;
int bmpStep = img->widthStep;
int bmpChannels = img->nChannels;
uchar*pBmpBuf = (uchar*)img->imageData;
double m00=0,m11=0,m20=0,m02=0,m30=0,m03=0,m12=0,m21=0; //中心矩
double x0=0,y0=0; //计算中心距时所使用的临时变量(x-x')
double u20=0,u02=0,u11=0,u30=0,u03=0,u12=0,u21=0;//规范化后的中心矩
//double M[7]; //HU不变矩
double t1=0,t2=0,t3=0,t4=0,t5=0;//临时变量,
//double Center_x=0,Center_y=0;//重心
int Center_x=0,Center_y=0;//重心
int i,j; //循环变量
// 获得图像的区域重心(普通矩)
double s10=0,s01=0,s00=0; //0阶矩和1阶矩
for(j=0;j<bmpHeight;j++)//y
{
for(i=0;i<bmpWidth;i++)//x
{
s10+=i*pBmpBuf[j*bmpStep+i];
s01+=j*pBmpBuf[j*bmpStep+i];
s00+=pBmpBuf[j*bmpStep+i];
}
}
Center_x=(int)(s10/s00+0.5);
Center_y=(int)(s01/s00+0.5);
// 计算二阶、三阶矩(中心矩)
m00=s00;
for(j=0;j<bmpHeight;j++)
{
for(i=0;i<bmpWidth;i++)//x
{
x0=(i-Center_x);
y0=(j-Center_y);
m11+=x0*y0*pBmpBuf[j*bmpStep+i];
m20+=x0*x0*pBmpBuf[j*bmpStep+i];
m02+=y0*y0*pBmpBuf[j*bmpStep+i];
m03+=y0*y0*y0*pBmpBuf[j*bmpStep+i];
m30+=x0*x0*x0*pBmpBuf[j*bmpStep+i];
m12+=x0*y0*y0*pBmpBuf[j*bmpStep+i];
m21+=x0*x0*y0*pBmpBuf[j*bmpStep+i];
}
}
// 计算规范化后的中心矩: mij/pow(m00,((i+j+2)/2)
u20=m20/pow(m00,2);
u02=m02/pow(m00,2);
u11=m11/pow(m00,2);
u30=m30/pow(m00,2.5);
u03=m03/pow(m00,2.5);
u12=m12/pow(m00,2.5);
u21=m21/pow(m00,2.5);
// 计算中间变量
t1=(u20-u02);
t2=(u30-3*u12);
t3=(3*u21-u03);
t4=(u30+u12);
t5=(u21+u03);
// 计算不变矩
M[0]=u20+u02;
M[1]=t1*t1+4*u11*u11;
M[2]=t2*t2+t3*t3;
M[3]=t4*t4+t5*t5;
M[4]=t2*t4*(t4*t4-3*t5*t5)+t3*t5*(3*t4*t4-t5*t5);
M[5]=t1*(t4*t4-t5*t5)+4*u11*t4*t5;
M[6]=t3*t4*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);
returntrue;
}
②调用OpenCV方法
// 利用OpenCV函数求7个Hu矩
CvMoments moments;
CvHuMoments hu;
cvMoments(bkImgEdge,&moments,0);
cvGetHuMoments(&moments, &hu);
cout<<hu.hu1<<"/"<<hu.hu2<<"/"<<hu.hu3<<"/"<<hu.hu4<<"/"<<hu.hu5<<"/"<<hu.hu6<<"/"<<hu.hu7<<"/"<<"/"<<endl;
cvMoments(testImgEdge,&moments,0);
cvGetHuMoments(&moments, &hu);
cout<<hu.hu1<<"/"<<hu.hu2<<"/"<<hu.hu3<<"/"<<hu.hu4<<"/"<<hu.hu5<<"/"<<hu.hu6<<"/"<<hu.hu7<<"/"<<"/"<<endl;
-------------------------------------------------------------------------------------------------------------------------------
三 相似性准则
①法一
// 计算相似度1
double dbR =0; //相似度
double dSigmaST =0;
double dSigmaS =0;
double dSigmaT =0;
double temp =0;
{for(int i=0;i<7;i++)
{
temp = fabs(Sa[i]*Ta[i]);
dSigmaST+=temp;
dSigmaS+=pow(Sa[i],2);
dSigmaT+=pow(Ta[i],2);
}}
dbR = dSigmaST/(sqrt(dSigmaS)*sqrt(dSigmaT));
②法二
1 // 计算相似度2
double dbR2 =0; //相似度
double temp2 =0;
double temp3 =0;
{for(int i=0;i<7;i++)
{
temp2 += fabs(Sa[i]-Ta[i]);
temp3 += fabs(Sa[i]+Ta[i]);
}}
dbR2 =1- (temp2*1.0)/(temp3);