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 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.
