Compute Image Moments#
Image moments describe the shape of a region. They’re useful for computing centroids, orientation, and shape descriptors.
All moments#
Get raw, central, and normalized central moments in one call:
m = mask.moments()
# Raw moments (area, center of mass, spread)
area = m['m00']
cx = m['m10'] / m['m00'] # centroid x
cy = m['m01'] / m['m00'] # centroid y
# Central moments (translation-invariant)
mu20 = m['mu20'] # variance in x
mu02 = m['mu02'] # variance in y
mu11 = m['mu11'] # covariance
# Normalized central moments (scale-invariant)
nu20 = m['nu20']
nu11 = m['nu11']
The dictionary has the same keys as cv2.moments().
Hu moment invariants#
For shape matching across translation, scale, and rotation [1]:
hu = mask.hu_moments() # Returns array of 7 values
Hu moments are derived from normalized central moments and are invariant under translation, scale, and rotation. The first 6 are also invariant under reflection; the 7th changes sign under reflection.
Compare two shapes:
hu1 = mask1.hu_moments()
hu2 = mask2.hu_moments()
# Log-transform for numerical stability (like cv2.matchShapes)
hu1_log = np.sign(hu1) * np.log10(np.abs(hu1) + 1e-10)
hu2_log = np.sign(hu2) * np.log10(np.abs(hu2) + 1e-10)
distance = np.sum(np.abs(hu1_log - hu2_log))
Orientation from moments#
Compute the orientation (angle of the major axis) of a region:
m = mask.moments()
# Angle of principal axis in radians
theta = 0.5 * np.arctan2(2 * m['mu11'], m['mu20'] - m['mu02'])
Eccentricity#
Measure how elongated a shape is:
m = mask.moments()
# Eigenvalues of the covariance matrix
a = m['mu20'] / m['m00']
b = m['mu11'] / m['m00']
c = m['mu02'] / m['m00']
lambda1 = 0.5 * (a + c + np.sqrt((a - c)**2 + 4*b**2))
lambda2 = 0.5 * (a + c - np.sqrt((a - c)**2 + 4*b**2))
eccentricity = np.sqrt(1 - lambda2 / lambda1)
References