Community
cancel
Showing results for
Did you mean: 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). 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.

5 Replies Employee
128 Views

Hi ,

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

Thank you 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);
ippsFree(state);
===== End =====

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 )
{
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 = s;
hu = d * d + n4 * m.nu11;
hu = q0 + q1;
hu = 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 = q0 * q0 + q1 * q1;
hu = q0 * t0 + q1 * t1;
hu = q1 * t0 - q0 * t1;
} 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)

{
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 = s;
hu = d * d + n4 * nu11;
hu = q0 + q1;
hu = d * (q0 - q1) + n4 * t0 * t1;

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

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

hu = q0 * q0 + q1 * q1;
hu = q0 * t0 + q1 * t1;
hu = q1 * t0 - q0 * t1;
} Employee
128 Views  