Ask Your Question
2

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

asked 2020-01-23 06:30:47 -0600

TAldhous gravatar image

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.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2020-01-27 04:29:26 -0600

TAldhous gravatar image

Solved it myself! It turns out that the contours for two of the shapes were doubling back on themselves, effectively making a long, thin perimeter instead of a large squarish blob. The solution was to apply a bilateral filter to the grayscale image before thresholding, edge detection and contour extraction. This gives similar Hu moments for all the images.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2020-01-23 06:30:47 -0600

Seen: 533 times

Last updated: Jan 27 '20