5 Best Ways to Draw Multiple Rectangles in Images Using OpenCV Python

πŸ’‘ Problem Formulation:

When working with images, a common task is to annotate them by drawing shapes – like rectangles to highlight certain objects. Take, for example, face detection where it’s desirable to outline each detected face with a rectangle. How do we efficiently draw multiple rectangles on an image using OpenCV with Python? Our input is a raw image and a list of rectangle coordinates, and the output should be the same image with the rectangles drawn over it.

Method 1: Using the cv2.rectangle Function

This method involves iterating over a list of rectangles and using the cv2.rectangle() function to draw each one. This function requires the top-left corner and bottom-right corner coordinates, the color of the rectangle (BGR format), and the thickness of the rectangle’s edge.

Here’s an example:

import cv2

# Load an image
image = cv2.imread('image.jpg')

# Define some rectangles as tuples [(top-left-x, top-left-y, bottom-right-x, bottom-right-y)...]
rectangles = [(50, 50, 150, 150), (200, 200, 300, 300)]

# Draw rectangles on the image
for rect in rectangles:
    top_left = (rect[0], rect[1])
    bottom_right = (rect[2], rect[3])
    cv2.rectangle(image, top_left, bottom_right, (0, 255, 0), 3)

# Save the image with rectangles
cv2.imwrite('image_with_rectangles.jpg', image)

The output will be the original image overlaid with green rectangles at the specified coordinates.

This code snippet is straightforward – it reads an image, defines rectangle coordinates, and iterates over them to draw with the specified color and thickness. Finally, the modified image is saved.

Method 2: Drawing Rectangles with a Filled Option

OpenCV allows not only to draw an outline of a rectangle but also to fill it with a solid color using the same cv2.rectangle() function. By setting thickness to cv2.FILLED, the interior of the rectangle is painted.

Here’s an example:

import cv2

# Load an image
image = cv2.imread('image.jpg')

# Specify rectangles and color
rectangles = [(50, 50, 150, 150), (200, 200, 300, 300)]
color = (255, 0, 0) # Blue color in BGR

# Draw filled rectangles
for (x1, y1, x2, y2) in rectangles:
    cv2.rectangle(image, (x1, y1), (x2, y2), color, cv2.FILLED)

# Save the modified image
cv2.imwrite('image_filled_rectangles.jpg', image)

The output is an image with solid blue-filled rectangles in the given coordinates.

In this snippet, after loading the image, we loop through the rectangle coordinates and paint each one blue. The key here is setting the thickness to cv2.FILLED, which fills the rectangle with color.

Method 3: Creating ROI (Region of Interest) with Rectangles

Regions of Interest (ROIs) are used in image processing when you want to focus on a certain area, such as when detecting features. With OpenCV, you can draw rectangles to represent ROIs and apply operations only within these areas.

Here’s an example:

import cv2

# Load an image
image = cv2.imread('image.jpg')

# Specify the ROI rectangle coordinates
roi_rectangles = [(100, 100, 200, 200)]

# Process each ROI
for (x1, y1, x2, y2) in roi_rectangles:
    # Draw the rectangle
    cv2.rectangle(image, (x1, y1), (x2, y2), (0, 0, 255), 1)
    # Extract ROI from the image
    roi = image[y1:y2, x1:x2]

    # Here you can process the ROI as needed...

cv2.imwrite('image_with_roi.jpg', image)

The output is an image with a red rectangle delineating the ROI.

We define the coordinates of the ROI and draw them on the image. After that, we extract the ROI for further processing, such as feature detection or filtering, and then save the image.

Method 4: Batch Drawing with Numpy and cv2

For an efficient approach to drawing multiple rectangles, use NumPy to create a batch of rectangle specifications and apply them all at once with vectorized operations. This method is faster but a bit more complex to understand in comparison to simple looping.

Here’s an example:

import cv2
import numpy as np

# Load an image
image = cv2.imread('image.jpg')

# Create a batch of rectangles [(x, y, w, h), ...]
rect_batch = np.array([[40, 60, 100, 100], [160, 220, 50, 50]])

# Draw all rectangles at once
for (x, y, w, h) in rect_batch:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 0), 2)

cv2.imwrite('image_batch_rectangles.jpg', image)

The output of this code will be an image containing rectangles at the given coordinates with a black color edge.

Instead of defining tuples for each rectangle, we create a NumPy array to hold all rectangle specifications. Then we draw each rectangle with OpenCV by calculating the bottom-right coordinate from the width and height.

Bonus One-Liner Method 5: Using List Comprehension

If you prefer concise code, Python list comprehensions paired with the cv2.rectangle() function allow for drawing multiple rectangles in a single line. Note this method still loops internally, but the syntax is more elegant.

Here’s an example:

import cv2

# Load an image
image = cv2.imread('image.jpg')

# Coordinates and color
rectangles = [(60, 80, 160, 180), (220, 230, 320, 330)]
color = (0, 200, 200) # Cyan color

# Draw all rectangles in a one-liner
[cv2.rectangle(image, (x1, y1), (x2, y2), color, 2) for (x1, y1, x2, y2) in rectangles]

cv2.imwrite('image_oneliner_rectangles.jpg', image)

The resulting image includes cyan-colored rectangles at the specified coordinates.

This clever use of list comprehension in Python allows for a very concise code to draw multiple rectangles efficiently. Just be cautious, as this may slightly reduce code clarity.

Summary/Discussion

  • Method 1: Using cv2.rectangle(). Strengths: Simple and clear. Weaknesses: May not be the most efficient for large image sets.
  • Method 2: Filled rectangles with cv2.rectangle(). Strengths: Offers visual distinction between regions. Weaknesses: Filling can obscure underlying image details.
  • Method 3: ROI with rectangles. Strengths: Useful for image processing within specific areas. Weaknesses: Requires extra steps for processing the ROI.
  • Method 4: Batch Drawing with NumPy and cv2. Strengths: Efficient for large number of rectangles. Weaknesses: Slightly more complex setup.
  • Method 5: One-liner list comprehension. Strengths: Elegant and concise. Weaknesses: Can be less readable, and it’s essentially syntactic sugar for a loop.