我使用OpenCV中的函数cvGetHumoments()计算7个hu不变矩时始终有错误,为了得到结果我自己用C++编写了一段计算7个hu不变矩的程序。
说明:图片必须是等边长的,即宽和高相等。****或许图片宽不能大于40像素,如果是边缘检测后的线条图像,图像宽高的限制会降低。如果你有什么好的想法,不妨留言交流一下。
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream.h>
float MOMENTS_M(IplImage* MAT,int p,int q) //空间距
{
CvScalar scl;
float M_sum_y;
float M_sum_xy;
int H,W;
H=MAT->height;
W=MAT->width;
for(int i=0;i<H;i++)
{ for(int j=0;j<W;j++)
{
scl=cvGet2D(MAT,i,j);
M_sum_y+=scl.val[0]*pow(j,q);
}
M_sum_xy+=pow(i,p)*M_sum_y;
}
return M_sum_xy;
}
float MOMENTS_U(IplImage* MAT,int p,int q,float X_,float Y_) //中心距
{
CvScalar scl;
float N_sum_y;
float N_sum_xy;
int H,W;
H=MAT->height;
W=MAT->width;
for(int i=0;i<H;i++)
{ for(int j=0;j<W;j++)
{
scl=cvGet2D(MAT,i,j);
N_sum_y+=scl.val[0]*pow(j-Y_,q);
}
N_sum_xy+=pow(i-X_,p)*N_sum_y;
}
return N_sum_xy;
}
//归一化的中心距
void main()
{
int M00,M01,M10,M11,M02,M20,M12,M21,M03,M30;
float X_,Y_;
float U00,U02,U20,U11,U03,U30,U21,U12;
float N02,N20,N11,N03,N30,N12,N21;
float H1,H2,H3,H4,H5,H6,H7;
// IplImage* img;
IplImage* mat;
mat=cvLoadImage("pic5_00.jpg",0);
// mat=cvCreateImage(img->height,img->width,8);
// cvCopy(img,mat);
M00=MOMENTS_M(mat,0,0);
M01=MOMENTS_M(mat,0,1);
M10=MOMENTS_M(mat,1,0);
M11=MOMENTS_M(mat,1,1);
M02=MOMENTS_M(mat,0,2);
M20=MOMENTS_M(mat,2,0);
M12=MOMENTS_M(mat,1,2);
M21=MOMENTS_M(mat,2,1);
M03=MOMENTS_M(mat,0,3);
M30=MOMENTS_M(mat,3,0);
X_=M10/M00;
Y_=M01/M00;
U00=M00;
U02=M02-M01*Y_;
U20=M20-M10*X_;
U11=M11-M10*Y_;
U03=M03-3*M02*X_+2*M10*X_*X_;
U30=M30-3*M02*Y_+2*M01*Y_*Y_;
U12=M12-2*M11*Y_-M02*X_+2*M10*Y_*Y_;
U21=M21-2*M11*X_-M20*Y_+2*M01*X_*X_;
cout<<U00<<"XXX"<<U02<<"XXX"<<U20<<"XXX"<<U11<<"XXX"<<U03<<"XXX"<<U30<<"XXX"<<U12<<"XXX"<<U21<<endl;
N02=U02/U00/U00;
N20=U20/U00/U00;
N11=U11/U00/U00;
N03=U03/U00/U00/sqrt(U00);
N30=U30/U00/U00/sqrt(U00);
N12=U12/U00/U00/sqrt(U00);
N21=U21/U00/U00/sqrt(U00);
cout<<N02<<"XXX"<<N20<<"XXX"<<N11<<"XXX"<<N03<<"XXX"<<N30<<"XXX"<<N12<<"XXX"<<N21<<endl;
//hu7个不变距
H1=N20+N02;
H2=(N20-N02)* (N20-N02)+4*N11*N11;
H3=(N30-3*N12)* (N30-3*N12)+(3*N21-N03)* (3*N21-N03);
H4=(N30+N12)* (N30+N12)+(N21+N03)* (N21+N03);
H5=((N30-3*N12)*(N30+N12)*((N30+N12)*(N30+N12)-3*(N21+N03)*(N21+N03))
+(3*N21-N03)*(N21+N03)*(3*(N30+N12)* (N30+N12)-(N21+N03)* (N21+N03)))*100000;
H6=(N20-N02)*((N30+N12)* (N30+N12)-(N21+N03)* (N21+N03))
+4*N11*(N30+N12)*(N21+N03);
H7=((3*N21-N03)*(N30+N12)*((N30+N12)*(N30+N12)-3*(N21+N03)*(N21+N03))
+(3*N12-N30)*(N21+N03)*(3*(N30+N12)* (N30+N12)- (N21+N03)* (N21+N03)))*100000;
cout<<H1<<"XXX"<<H2<<"XXX"<<H3<<"XXX"<<H4<<"XXX"<<H5<<"XXX"<<H6<<"XXX"<<H7<<endl;
}