This function is used to compare two Zernike descriptors. All mathematical explanations can be found in the online paper: "Improving Zernike Moments Comparison for Optimal Similarity and Rotation Angle Retrieval", Jerome Revaud et al., 2009. here are some prerequisites: struct Radial // 2D vector in polar coordinates { double mod; double angle; }; #define ANGLEINV(x,y) ((x)==0 && (y)==0? 0 : atan2((y),(x))) typedef double ANGLE2D; typedef std::vector VectorOfRadial; #define ORDERMAX 8 #define MOMENTMAX 25 Now the main function: It returns the distance between the two descriptors for the optimal rotation angle. This last one is also returned as 'angleRes'. // desc1 & desc2 are two vectors of Zernike moments (under radial form : modulus * e^(i*angle) ) // desc1 & desc2 contains desc[0]=Z00, desc[1]=Z11, desc[2]=Z20, desc[3]=Z22, and so on static double Compare(const VectorOfRadial & desc1, const VectorOfRadial & desc2, ANGLE2D& angleRes) { WORD n; double sum=0,tmp; WORD nbMoments = min(desc1.size(),desc2.size()); // NON INVARIANT V2 // search for optimal angle // minimization of S(phi) = sum( Wp * module( Zpq*e^(i*q*phi) - Z'pq)^2 ) // <=>sum( Wp * (|Zpq|^2+|Z'pq|^2)) + sum( 2* Wp * |Zpq|*|Z'pq|*cos( [Zpq]-[Z'pq]+ q*phi ) ) // test int p,q; double modZ1,modZ2; BYTE orderMax = 0; static BYTE orders[MOMENTMAX]; static double radials[MOMENTMAX][2]; orders[0] = 0; radials[0][0] = 0; radials[0][1] = 0; // Fill the tabs for(n=p=1; norderMax) orderMax=q; } // Fast approximate the solution sum += findMimimumCosinesG(orders,radials,orderMax,nbMoments,angleRes); return sum; } Then this one is used to find global minimum static double findMimimumCosinesG( const BYTE orders[], const double radials[][2], BYTE orderMax, WORD sizeMax, ANGLE2D & res ) { WORD q; double min; // Create and reset the coefficients matrix static double C[ORDERMAX][2]; memset(C,0,sizeof(C)); // First thing : unite same phases for(q=0; q=0)) // et ca remonte { // recherche du minimum double pos = x - thisDer*inter/(nextDer-thisDer); double y=ComputeExact(C,orderMax,pos,false); if(y