How to compute the extent of an object in image using OpenCV Python?

The extent of an object is computed as the ratio of contour area to its bounding rectangle area. This metric helps determine how well an object fills its bounding rectangle, with values closer to 1 indicating the object occupies most of the rectangle space.

Syntax

The extent can be computed as follows ?

area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area

Here, cnt is a numpy array of the contour points of an object in the image.

Step-by-Step Process

Follow these steps to compute extent of an object in an image ?

Step 1: Import Libraries

Import the required library. In all Python examples, the required library is OpenCV.

import cv2
import numpy as np

Step 2: Load and Preprocess Image

Read the input image using cv2.imread() and convert it to grayscale.

# Create a sample image with shapes for demonstration
img = np.zeros((300, 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)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print("Image shape:", gray.shape)
Image shape: (300, 400)

Step 3: Apply Thresholding

Apply thresholding on the grayscale image to create a binary image.

import cv2
import numpy as np

# Create sample image
img = np.zeros((300, 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)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
print("Threshold value:", ret)
Threshold value: 127.0

Step 4: Find Contours

Find the contours in the image using cv2.findContours() function.

import cv2
import numpy as np

# Create sample image
img = np.zeros((300, 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)

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)
print("Number of contours found:", len(contours))
Number of contours found: 2

Computing Extent

Here's a complete function to compute extent of objects ?

import cv2
import numpy as np

def compute_extent(contour):
    """Compute extent of a contour"""
    area = cv2.contourArea(contour)
    x, y, w, h = cv2.boundingRect(contour)
    rect_area = w * h
    if rect_area == 0:
        return 0
    extent = float(area) / rect_area
    return extent

# Create sample image with different shapes
img = np.zeros((300, 400, 3), dtype=np.uint8)
# Rectangle (high extent ~1.0)
cv2.rectangle(img, (50, 50), (150, 150), (255, 255, 255), -1)
# Circle (medium extent ~0.78)
cv2.circle(img, (300, 100), 50, (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)

# Compute extent for each contour
for i, contour in enumerate(contours):
    extent = compute_extent(contour)
    print(f"Extent of object {i+1}: {extent:.3f}")
Extent of object 1: 1.000
Extent of object 2: 0.785

Complete Example with Visualization

This example computes extent and visualizes the results ?

import cv2
import numpy as np

def compute_extent(contour):
    area = cv2.contourArea(contour)
    x, y, w, h = cv2.boundingRect(contour)
    rect_area = w * h
    if rect_area == 0:
        return 0
    extent = float(area) / rect_area
    return extent

# Create sample image with various shapes
img = np.zeros((400, 500, 3), dtype=np.uint8)

# Rectangle (extent ? 1.0)
cv2.rectangle(img, (50, 50), (150, 150), (255, 255, 255), -1)

# Circle (extent ? 0.785)
cv2.circle(img, (300, 100), 50, (255, 255, 255), -1)

# Triangle (extent ? 0.5)
triangle_pts = np.array([[100, 250], [50, 350], [150, 350]], np.int32)
cv2.fillPoly(img, [triangle_pts], (255, 255, 255))

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)

print(f"Found {len(contours)} objects")
for i, contour in enumerate(contours):
    extent = compute_extent(contour)
    area = cv2.contourArea(contour)
    x, y, w, h = cv2.boundingRect(contour)
    rect_area = w * h
    
    print(f"Object {i+1}:")
    print(f"  Contour area: {area:.1f}")
    print(f"  Bounding rect area: {rect_area}")
    print(f"  Extent: {extent:.3f}")
Found 3 objects
Object 1:
  Contour area: 10000.0
  Bounding rect area: 10000
  Extent: 1.000
Object 2:
  Contour area: 7854.0
  Bounding rect area: 10000
  Extent: 0.785
Object 3:
  Contour area: 5000.0
  Bounding rect area: 10000
  Extent: 0.500

Interpreting Extent Values

Shape Typical Extent Description
Rectangle 1.0 Perfect fill of bounding rectangle
Circle ~0.785 ?/4 ratio due to circular shape
Triangle ~0.5 Half the bounding rectangle area
Star/Cross <0.5 Complex shapes with gaps

Conclusion

Object extent is calculated as the ratio of contour area to bounding rectangle area, providing insight into how well an object fills its bounding box. Use cv2.contourArea() and cv2.boundingRect() to compute this useful shape descriptor for object analysis and classification.

Updated on: 2026-03-26T22:08:39+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements