Calculate Image Moments of an Ellipse#
Image moments can be used to determine the center of gravity or average pixel location of a binary object as well as the orientation of an object according to its axes of variation.
The interactive plot below demonstrates how to calculate the image moments of an ellipse-defined mask.
[1]:
import itk
import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import interact
[2]:
output_size = [100, 100] # size of binary image containing the ellipse
@interact(
tx=(0, output_size[0], 1),
ty=(0, output_size[1], 1),
a=(5, 50, 1),
b=(5, 50, 1),
theta=(0, 2 * np.pi, 0.1),
)
def foo(tx=30, ty=50, a=5, b=10, theta=np.pi / 4.0):
"""
Creates a binary image of an ellipse and calculates the image moments. Major (purple) and minor (green)
principal axes are displayed.
Parameters
==========
tx, ty : translation x and y
a, b : ellipse horizontal and vertical widths before rotation
theta : angle of rotation (radians)
"""
# ellipse starts as unit circle, use world transform to define final ellipse
ellipse = itk.EllipseSpatialObject[2].New()
ellipse_transform = itk.AffineTransform[itk.D, 2].New()
ellipse_transform.Scale([a, b])
ellipse_transform.Rotate2D(theta)
ellipse_transform.Translate([tx, ty])
ellipse.SetObjectToWorldTransform(ellipse_transform)
ellipse_img = itk.spatial_object_to_image_filter(
input=ellipse, inside_value=1, outside_value=0, size=output_size
)
momentor = itk.ImageMomentsCalculator.New(Image=ellipse_img)
momentor.Compute()
centroid = momentor.GetCenterOfGravity()
prin_axes = itk.array_from_matrix(momentor.GetPrincipalAxes())
minor_axes = prin_axes[0]
major_axes = prin_axes[1]
fig, ax = plt.subplots(figsize=[8, 8])
plt.imshow(ellipse_img, cmap="gray")
plt.scatter(centroid[0], centroid[1])
minor_pt = centroid + minor_axes * 5
plt.plot([centroid[0], minor_pt[0]], [centroid[1], minor_pt[1]], color="green")
major_pt = centroid + major_axes * 5
plt.plot([centroid[0], major_pt[0]], [centroid[1], major_pt[1]], color="purple")
print(momentor)
[ ]: