Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to Compute Image Moments in OpenCV Python?
Image moments are statistical measures that describe the shape and size characteristics of objects in an image. They are essential for computing features like center of mass, area, and orientation of objects. In OpenCV, image moments are calculated using contours of detected objects.
Syntax
The basic syntax for computing image moments is ?
cv2.moments(contour)
Where contour is a NumPy array containing the contour points of an object.
Understanding Image Moments
Image moments provide valuable information about objects ?
- m00 ? Area of the object
- m10, m01 ? First-order moments used to find centroid
- m20, m11, m02 ? Second-order moments for orientation
- mu20, mu11, mu02 ? Central moments (translation invariant)
- nu20, nu11, nu02 ? Normalized central moments (scale invariant)
Step-by-Step Process
Follow these steps to compute image moments ?
- Load and convert the image to grayscale
- Apply thresholding to create a binary image
- Find contours using
cv2.findContours() - Compute moments using
cv2.moments() - Extract required features from the moments
Example 1: Computing Moments for Single Contour
This example demonstrates how to find moments for the first detected contour ?
import cv2
import numpy as np
# Create a sample image with geometric shapes
img = np.zeros((400, 400, 3), dtype=np.uint8)
cv2.rectangle(img, (50, 50), (150, 150), (255, 255, 255), -1)
cv2.circle(img, (300, 100), 50, (255, 255, 255), -1)
cv2.polygon(img, [np.array([(200, 200), (300, 200), (250, 300)])], (255, 255, 255))
# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply thresholding
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# Find contours
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print(f"Number of contours detected: {len(contours)}")
# Get moments of the first contour
if contours:
cnt = contours[0]
M = cv2.moments(cnt)
# Calculate centroid
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
print(f"Centroid: ({cx}, {cy})")
# Draw contour and centroid
cv2.drawContours(img, [cnt], -1, (0, 255, 0), 2)
cv2.circle(img, (cx, cy), 5, (0, 0, 255), -1)
print("Key moments:")
print(f"Area (m00): {M['m00']}")
print(f"Centroid X (m10/m00): {cx}")
print(f"Centroid Y (m01/m00): {cy}")
Example 2: Computing Moments for All Contours
This example processes all detected contours and computes their moments ?
import cv2
import numpy as np
# Create a sample image with multiple shapes
img = np.zeros((400, 400, 3), dtype=np.uint8)
cv2.rectangle(img, (50, 50), (150, 150), (255, 255, 255), -1)
cv2.circle(img, (300, 100), 50, (255, 255, 255), -1)
cv2.polygon(img, [np.array([(200, 250), (300, 250), (250, 350)])], (255, 255, 255))
# Convert to grayscale and threshold
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# Find all contours
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print(f"Total contours found: {len(contours)}")
# Process each contour
for i, cnt in enumerate(contours):
# Calculate moments
M = cv2.moments(cnt)
# Skip if contour has zero area
if M["m00"] == 0:
continue
# Calculate centroid
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
# Draw contour and label
cv2.drawContours(img, [cnt], -1, (0, 255, 255), 2)
cv2.circle(img, (cx, cy), 3, (0, 0, 255), -1)
cv2.putText(img, f'Shape {i+1}', (cx-20, cy-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
print(f"\nShape {i+1} moments:")
print(f" Area: {M['m00']:.2f}")
print(f" Centroid: ({cx}, {cy})")
print(f" Central moments - mu20: {M['mu20']:.2f}, mu02: {M['mu02']:.2f}")
print("\nProcessing complete!")
Computing Object Features from Moments
You can derive useful geometric properties from moments ?
import cv2
import numpy as np
import math
# Function to calculate object features from moments
def calculate_features(moments):
features = {}
if moments["m00"] != 0:
# Centroid
features["cx"] = int(moments["m10"] / moments["m00"])
features["cy"] = int(moments["m01"] / moments["m00"])
# Area
features["area"] = moments["m00"]
# Orientation (angle of major axis)
mu20 = moments["mu20"]
mu02 = moments["mu02"]
mu11 = moments["mu11"]
if mu20 != mu02:
theta = 0.5 * math.atan2(2 * mu11, mu20 - mu02)
features["orientation"] = math.degrees(theta)
else:
features["orientation"] = 0
# Eccentricity
denominator = (mu20 + mu02)**2
if denominator != 0:
numerator = (mu20 - mu02)**2 + 4 * mu11**2
features["eccentricity"] = math.sqrt(numerator) / (mu20 + mu02)
else:
features["eccentricity"] = 0
return features
# Create sample image and process
img = np.zeros((300, 300, 3), dtype=np.uint8)
cv2.ellipse(img, (150, 150), (80, 40), 30, 0, 360, (255, 255, 255), -1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if contours:
M = cv2.moments(contours[0])
features = calculate_features(M)
print("Object Features:")
print(f"Area: {features['area']:.2f}")
print(f"Centroid: ({features['cx']}, {features['cy']})")
print(f"Orientation: {features['orientation']:.2f} degrees")
print(f"Eccentricity: {features['eccentricity']:.3f}")
Conclusion
Image moments in OpenCV provide powerful tools for shape analysis and object characterization. Use cv2.moments() to extract geometric features like area, centroid, and orientation from object contours for computer vision applications.
