Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Ladislav_K_
Beginner
128 Views

5th moment of ippiGetHuMoments_64f ?

Hi,

I am comparing results of ippiGetHuMoments_64f() with alternative implementation. There are equal results except for 5th moment (hu[4]). What can be cause of this? Does ippiGetHuMoments_64f() uses same equation as stated for example in wikipedia or in OpenCV : https://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html ?

Here are results for two objects:

1:
Alt.  :Hu moments: 0,6320094033, 0,3361693204, 0,03546582373, 0,02023822563, 0,0005380840922, 0,01160643157, -0,00006672319914
Intel: Hu moments: 0,6320094033, 0,3361693204, 0,03546582373, 0,02023822563, 0,0005388502231, 0,01160643157, -0,00006672319914
2:
Alt. :Hu moments: 0,4550913598, 0,0651230286, 0,02186730725, 0,001194923098, -5,865595432E-6, 0,0003034540164, -1,704090629E-6
Intel:Hu moments: 0,4550913598, 0,0651230286, 0,02186730725, 0,001194923098, -5,866945186E-6, 0,0003034540164, -1,704090629E-6

As you can see there is only difference in 5th moment, which is quite strange.

0 Kudos
5 Replies
Jonghak_K_Intel
Employee
128 Views

Hi , 

 

could you provide the test code you use , so we can reproduce for investigation? 

 

Thank you 

Ladislav_K_
Beginner
128 Views

My test program in written in Pascal, but is rather simple.
I can reproduce behavior with 3x3 matrix:
1 0 0
0 1 1
0 0 1

For this matrix I get:

Alt. :Hu moments: 0,296875, 0,06469726563, 0,008926391602, 0,003555297852, 0,00002001249231, 0,0008685588837, 8,046627045E-7
Intel:Hu moments: 0,296875, 0,06469726563, 0,008926391602, 0,003555297852, 0,00002140179276, 0,0008685588837, 8,046627045E-7

There is difference only on 5-th moment at six decimal place.
(probably rounding, precision error?)

Fragment of my test program is in Pascal, but I am sure you understand logic behind it:
(attached is 3x3 bitmap, which serves as input image)

===== Begin =====
var
  size: int;
  state: PIppiMomentState_64f;
  m: Ipp64f;
  hu: array[0..7] of double;
begin
  ippiMomentGetStateSize_64f(ippAlgHintNone, size);
  state := PIppiMomentState_64f(ippsMalloc_8u(size));
  ippiMomentInit_64f(state, ippAlgHintNone);
  // AImage is gray-scaled image, which I convert to binary image (not perfect I know)
  ippiThreshold_LTValGTVal_8u_C1IR(AImage.Data, AImage.Width, ROI(AImage.Width,AImage.Height), 128, 1, 128, 0); // =1 if<128, =0 if>128
  ippiMoments64f_8u_C1R(AImage.Data, AImage.Width, ROI(AImage.Width,AImage.Height), state);
  ippiGetSpatialMoment_64f(state, 0,0, 0, Point00, m); m00 := Trunc(m);
  ippiGetSpatialMoment_64f(state, 1,0, 0, Point00, m); m10 := Trunc(m);
  ippiGetSpatialMoment_64f(state, 0,1, 0, Point00, m); m01 := Trunc(m);
  ippiGetSpatialMoment_64f(state, 1,1, 0, Point00, m); m11 := Trunc(m);
  ippiGetCentralMoment_64f(state, 2,0, 0, mu20);
  ippiGetCentralMoment_64f(state, 0,2, 0, mu02);
  ippiGetCentralMoment_64f(state, 1,1, 0, mu11);
  ippiGetNormalizedCentralMoment_64f(state, 2,0, 0, nu20);
  ippiGetNormalizedCentralMoment_64f(state, 1,1, 0, nu11);
  ippiGetNormalizedCentralMoment_64f(state, 0,2, 0, nu02);
  ippiGetNormalizedCentralMoment_64f(state, 3,0, 0, nu30);
  ippiGetNormalizedCentralMoment_64f(state, 2,1, 0, nu21);
  ippiGetNormalizedCentralMoment_64f(state, 1,2, 0, nu12);
  ippiGetNormalizedCentralMoment_64f(state, 0,3, 0, nu03);
  ippiGetHuMoments_64f(state, 0, @hu[0]);
  ippsFree(state);
===== End =====

Additional information:
When I compare central normalized moments for above mentioned 3x3 shape using ippiGetNormalizedCentralMoment_64f() I get same results (for alternative and also for Intel implementation):
                                              nu20    , nu11 , nu02 , nu30          , nu21      , nu12      , nu03
CentralNormalized moments: 0,171875, 0,125, 0,125, -0,03515625, -0,03125, -0,015625, 0

As far as Hu moments are computed from central normalized moments I guess, that there will be "problem" in computation of 5-th Hu moment only ...

You can substitute these normalized central moments directly into OpenCV computation of Hu moments and compare results of OpenCV and Intel:

void cv::HuMoments( const Moments& m, double hu[7] )
{
    double t0 = m.nu30 + m.nu12;
    double t1 = m.nu21 + m.nu03;

    double q0 = t0 * t0, q1 = t1 * t1;

    double n4 = 4 * m.nu11;
    double s = m.nu20 + m.nu02;
    double d = m.nu20 - m.nu02;

    hu[0] = s;
    hu[1] = d * d + n4 * m.nu11;
    hu[3] = q0 + q1;
    hu[5] = d * (q0 - q1) + n4 * t0 * t1;

    t0 *= q0 - 3 * q1;
    t1 *= 3 * q0 - q1;

    q0 = m.nu30 - 3 * m.nu12;
    q1 = 3 * m.nu21 - m.nu03;

    hu[2] = q0 * q0 + q1 * q1;
    hu[4] = q0 * t0 + q1 * t1;
    hu[6] = q1 * t0 - q0 * t1;
}

Ladislav_K_
Beginner
128 Views

Hello,
any feedback on this issue?
As I wrote you can reproduce using 3x3 matrix, where   ippiGetNormalizedCentralMoment_64f returns correct results up to 3rd order.
But when passing these results in OpenCV implementation (see betow) I get different result in 5-th moment (hu[4])

{
    double nu20 = 0.171875;
    double nu11 = 0.125;
    double nu02 = 0.125;
    double nu30 = -0.03515625;
    double nu21 = -0.03125;
    double nu12 = -0.015625;
    double nu03 = 0;

    double t0 = nu30 + nu12;
    double t1 = nu21 + nu03;

    double q0 = t0 * t0, q1 = t1 * t1;

    double n4 = 4 * nu11;
    double s = nu20 + nu02;
    double d = nu20 - nu02;

    hu[0] = s;
    hu[1] = d * d + n4 * nu11;
    hu[3] = q0 + q1;
    hu[5] = d * (q0 - q1) + n4 * t0 * t1;

    t0 *= q0 - 3 * q1;
    t1 *= 3 * q0 - q1;

    q0 = nu30 - 3 * nu12;
    q1 = 3 * nu21 - nu03;

    hu[2] = q0 * q0 + q1 * q1;
    hu[4] = q0 * t0 + q1 * t1;
    hu[6] = q1 * t0 - q0 * t1;
}

Andrey_B_Intel
Employee
128 Views

Hi Ladislav.

I confirm your issue of wrong calculation of 5th Hu moments. There was mistake with 03 and 30 variable names in formula of 5th moment calculation. Fix will be available in next IPP release. Thanks you for improvement quality of IPP.

Ladislav_K_
Beginner
128 Views

Fixed in IPP 2019.3

Reply