Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Why are the Hu moments of the middle shape different to the others?

I have calculated the Hu moments of three contours extracted from three images, which are simply rotated copies of each other. I was expecting the moments of all three contours to be similar, but the moments for the middle one are wildly different. If I do the same thing for three rectangles, the Hu moments are the same. Can anyone explain why the moments for my contours are so different?

Code for calculating the Hu moments with rectangles is as follows:

import cv2
import numpy as np
from matplotlib import pyplot as plt

def plot_image(pl, nImages, nRows, imageNumber, image, imageTitle):
    plt.subplot(nImages, nRows, imageNumber)
    plt.imshow(image, cmap='gray')
    plt.title(imageTitle)
    plt.xticks([])
    plt.yticks([])

# Three rectangles at 45 degrees to each other
contours = [np.array([[[569, 108]], [[852, 391]], [[428, 815]], [[145, 532]]]),
            np.array([[[440, 220]], [[840, 220]], [[840, 820]], [[440, 820]]]),
            np.array([[[428, 391]], [[711, 108]], [[1135, 532]], [[852, 815]]])]

plotNumber = -1;
for contour in contours:
    plotNumber = plotNumber + 1
    contour_image = np.zeros((1280, 1280, 3), dtype=np.uint8)
    contour_image.fill(255)
    cv2.drawContours(contour_image, contours, -1, (192, 192, 192), 3)
    cv2.drawContours(contour_image, [contour], -1, (64, 64, 64), 3)
    moments = cv2.moments(contour)
    HuM = cv2.HuMoments(moments)
    title = "Contour {}".format(plotNumber)
    print(title)
    print("    Moments: '{}'".format(moments))
    print("    Hu moments: '{}'".format(HuM))
    plot_image(plt, 1, 3, plotNumber + 1, contour_image, title)

plt.show()

For the rectangles, this looks like this:

Rotated rectangles

and calculates the following moments:

Contour 0

Hu moments: '[[ 1.80473837e-01] [ 4.79302812e-03] [ 4.91216000e-32] [ 2.69569756e-31] [-1.58512811e-62] [-1.79162613e-32] [ 2.66642577e-62]]'

Contour 1

Hu moments: '[[0.18055556] [0.00482253] [0.        ] [0.        ] [0.        ] [0.        ] [0.        ]]'

Contour 2

Hu moments: '[[ 1.80473837e-01] [ 4.79302812e-03] [ 1.58896395e-30] [ 3.42683065e-30] [ 6.79144186e-60] [ 1.07829350e-31] [-4.22127525e-60]]'

Replacing the rectangles with my contours looks like this:

image description

and the calculated moments are:

Contour 0

Hu moments: '[[8.62421917e+01] [5.98422010e+02] [1.17817347e+05] [1.80083606e+04] [7.90111596e+08] [1.72868676e+05] [2.52571408e+08]]'

Contour 1

Hu moments: '[[ 1.71316578e-01] [ 1.60655638e-03] [ 5.04587028e-04] [ 7.51391253e-06] [-3.27447241e-10] [-3.00404360e-07] [-3.26860513e-10]]'

Contour 2

Hu moments: '[[8.66376920e+01] [6.08592878e+02] [1.19886409e+05] [1.71012017e+04] [7.20304630e+08] [1.37193728e+05] [2.84156598e+08]]'

I haven't included the contours themselves as they are quite long, but I can post them if required.

Any help would be appreciated.