void mvContours::get_hu_moments (CvSeq* contour1, HU_MOMENTS &hu_moments) { CvMoments moments; double hus[7]; cvContourMoments(contour1, &moments); cvGetHuMoments(&moments, (CvHuMoments*)hus); hu_moments = std::vector<double>(hus, hus+sizeof(hus)/sizeof(double)); }
/* * call-seq: * CvHuMoments.new(<i>src_moments</i>) * * Calculates the seven Hu invariants. * <i>src_moments</i> The input moments * * seven Hu invariants that are defined as: * h1=η20+η02 * h2=(η20-η02)²+4η11² * h3=(η30-3η12)²+ (3η21-η03)² * h4=(η30+η12)²+ (η21+η03)² * h5=(η30-3η12)(η30+η12)[(η30+η12)²-3(η21+η03)²]+(3η21-η03)(η21+η03)[3(η30+η12)²-(η21+η03)²] * h6=(η20-η02)[(η30+η12)²- (η21+η03)²]+4η11(η30+η12)(η21+η03) * h7=(3η21-η03)(η21+η03)[3(η30+η12)²-(η21+η03)²]-(η30-3η12)(η21+η03)[3(η30+η12)²-(η21+η03)²] * where ηi,j are normalized central moments of 2-nd and 3-rd orders. The computed values are proved to be invariant to the image scaling, rotation, and reflection except the seventh one, whose sign is changed by reflection. */ VALUE rb_initialize(VALUE self, VALUE src_moments) { try { cvGetHuMoments(CVMOMENTS(src_moments), CVHUMOMENTS(self)); } catch (cv::Exception& e) { raise_cverror(e); } return self; }
static int hu_moments_test( void ) { const double success_error_level = 1e-7; CvSize size = { 512, 512 }; int i; IplImage* img = atsCreateImage( size.width, size.height, 8, 1, 0 ); CvMoments moments; CvHuMoments a, b; AtsRandState rng_state; int seed = atsGetSeed(); double nu20, nu02, nu11, nu30, nu21, nu12, nu03; double err = 0; char buffer[100]; atsRandInit( &rng_state, 0, 255, seed ); atsbRand8u( &rng_state, (uchar*)(img->imageData), size.width * size.height ); cvMoments( img, &moments, 0 ); atsReleaseImage( img ); nu20 = cvGetNormalizedCentralMoment( &moments, 2, 0 ); nu11 = cvGetNormalizedCentralMoment( &moments, 1, 1 ); nu02 = cvGetNormalizedCentralMoment( &moments, 0, 2 ); nu30 = cvGetNormalizedCentralMoment( &moments, 3, 0 ); nu21 = cvGetNormalizedCentralMoment( &moments, 2, 1 ); nu12 = cvGetNormalizedCentralMoment( &moments, 1, 2 ); nu03 = cvGetNormalizedCentralMoment( &moments, 0, 3 ); cvGetHuMoments( &moments, &a ); b.hu1 = nu20 + nu02; b.hu2 = sqr(nu20 - nu02) + 4*sqr(nu11); b.hu3 = sqr(nu30 - 3*nu12) + sqr(3*nu21 - nu03); b.hu4 = sqr(nu30 + nu12) + sqr(nu21 + nu03); b.hu5 = (nu30 - 3*nu12)*(nu30 + nu12)*(sqr(nu30 + nu12) - 3*sqr(nu21 + nu03)) + (3*nu21 - nu03)*(nu21 + nu03)*(3*sqr(nu30 + nu12) - sqr(nu21 + nu03)); b.hu6 = (nu20 - nu02)*(sqr(nu30 + nu12) - sqr(nu21 + nu03)) + 4*nu11*(nu30 + nu12)*(nu21 + nu03); b.hu7 = (3*nu21 - nu03)*(nu30 + nu12)*(sqr(nu30 + nu12) - 3*sqr(nu21 + nu03)) + (3*nu12 - nu30)*(nu21 + nu03)*(3*sqr(nu30 + nu12) - sqr(nu21 + nu03)); for( i = 0; i < 7; i++ ) { double t = rel_err( ((double*)&b)[i], ((double*)&a)[i] ); if( t > err ) err = t; } sprintf( buffer, "Accuracy: %.4e", err ); return trsResult( err > success_error_level ? TRS_FAIL : TRS_OK, buffer ); }
VALUE new_object(CvMoments *src_moments) { VALUE object = rb_allocate(rb_klass); try { cvGetHuMoments(src_moments, CVHUMOMENTS(object)); } catch (cv::Exception& e) { raise_cverror(e); } return object; }
void mvHuMoments(IplImage *src, double *hus){ CvMoments moments; cvMoments(src, &moments, true); cvGetHuMoments(&moments, (CvHuMoments*)hus); }
/*F/////////////////////////////////////////////////////////////////////////////////////// // Name: cvMatchContours // Purpose: // Calculates matching of the two contours // Context: // Parameters: // contour_1 - pointer to the first input contour object. // contour_2 - pointer to the second input contour object. // method - method for the matching calculation // (now CV_IPPI_CONTOURS_MATCH_I1, CV_CONTOURS_MATCH_I2 or // CV_CONTOURS_MATCH_I3 only ) // rezult - output calculated measure // //F*/ CV_IMPL double cvMatchShapes( const void* contour1, const void* contour2, int method, double /*parameter*/ ) { CvMoments moments; CvHuMoments huMoments; double ma[7], mb[7]; int i, sma, smb; double eps = 1.e-5; double mmm; double result = 0; if( !contour1 || !contour2 ) CV_Error( CV_StsNullPtr, "" ); // calculate moments of the first shape cvMoments( contour1, &moments ); cvGetHuMoments( &moments, &huMoments ); ma[0] = huMoments.hu1; ma[1] = huMoments.hu2; ma[2] = huMoments.hu3; ma[3] = huMoments.hu4; ma[4] = huMoments.hu5; ma[5] = huMoments.hu6; ma[6] = huMoments.hu7; // calculate moments of the second shape cvMoments( contour2, &moments ); cvGetHuMoments( &moments, &huMoments ); mb[0] = huMoments.hu1; mb[1] = huMoments.hu2; mb[2] = huMoments.hu3; mb[3] = huMoments.hu4; mb[4] = huMoments.hu5; mb[5] = huMoments.hu6; mb[6] = huMoments.hu7; switch (method) { case 1: { for( i = 0; i < 7; i++ ) { double ama = fabs( ma[i] ); double amb = fabs( mb[i] ); if( ma[i] > 0 ) sma = 1; else if( ma[i] < 0 ) sma = -1; else sma = 0; if( mb[i] > 0 ) smb = 1; else if( mb[i] < 0 ) smb = -1; else smb = 0; if( ama > eps && amb > eps ) { ama = 1. / (sma * log10( ama )); amb = 1. / (smb * log10( amb )); result += fabs( -ama + amb ); } } break; } case 2: { for( i = 0; i < 7; i++ ) { double ama = fabs( ma[i] ); double amb = fabs( mb[i] ); if( ma[i] > 0 ) sma = 1; else if( ma[i] < 0 ) sma = -1; else sma = 0; if( mb[i] > 0 ) smb = 1; else if( mb[i] < 0 ) smb = -1; else smb = 0; if( ama > eps && amb > eps ) { ama = sma * log10( ama ); amb = smb * log10( amb ); result += fabs( -ama + amb ); } } break; } case 3: { for( i = 0; i < 7; i++ ) { double ama = fabs( ma[i] ); double amb = fabs( mb[i] ); if( ma[i] > 0 ) sma = 1; else if( ma[i] < 0 ) sma = -1; else sma = 0; if( mb[i] > 0 ) smb = 1; else if( mb[i] < 0 ) smb = -1; else smb = 0; if( ama > eps && amb > eps ) { ama = sma * log10( ama ); amb = smb * log10( amb ); mmm = fabs( (ama - amb) / ama ); if( result < mmm ) result = mmm; } } break; } default: CV_Error( CV_StsBadArg, "Unknown comparison method" ); } return result; }