说明:
图像要是一个灰度图像
pBmpBuf指向图像数据。
我看到网上没有一个真正的纯VC++的HU矩提取代码,希望这个能给大家有所帮助,我相信大家能看懂。(目前和OpenCv提取的还有一点偏差,我会尽快修改过来)
bool HuMoment()
{
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 i,j,k;//循环变量
double tmp[3];//临时变量数组。
int lineByte=(bmpWidth*biBitCount/8+3)/4*4;
//获得图像的区域重心
double s10=0,s01=0,s00=0;
for(i=0;i<bmpHeight;i++)//y
{
for(j=0;j<bmpWidth;j++)//x
{
s10=s10+j*pBmpBuf[i*bmpWidth+j];
s01=s01+i*pBmpBuf[i*bmpWidth+j];
s00=s00+pBmpBuf[i*bmpWidth+j];
}
}
Center_x=s10/s00;
Center_y=s01/s00;
m00=s00;
for(i=0;i<bmpHeight;i++)
{
for(j=0;j<bmpWidth;j++)//x
{
x0=j-Center_x;
y0=i-Center_y;
m11=m11+x0*y0*pBmpBuf[i*bmpWidth+j];
m20=m20+x0*x0*pBmpBuf[i*bmpWidth+j];
m02+=y0*y0*pBmpBuf[i*bmpWidth+j];
m03+=y0*y0*y0*pBmpBuf[i*bmpWidth+j];
m30+=x0*x0*x0*pBmpBuf[i*bmpWidth+j];
m12+=x0*y0*y0*pBmpBuf[i*bmpWidth+j];
m21=x0*x0*y0*pBmpBuf[i*bmpWidth+j];
}
}
//计算规范化后的中心矩
u20=m20/(m00*m00);
u02=m02/(m00*m00);
u11=m11/(m00*m00);
u30=m30/(m00*m00*sqrt(m00));
u03=m03/(m00*m00*sqrt(m00));
u12=m12/(m00*m00*sqrt(m00));
u21=m21/(m00*m00*sqrt(m00));
//计算中间变量。
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*t3*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);
cout<<M[0]<<endl;//<<二"<<M[0]<<"三"<<M[0]<<"四"<<M[0]<<"五"<<M[0]<<"六"<<M[0]<<"七"<<M[0]<<endl;
cout<<M[1]<<endl;
cout<<M[2]<<endl;
cout<<M[3]<<endl;
cout<<M[4]<<endl;
cout<<M[5]<<endl;
cout<<M[6]<<endl;
return true;
}