5 Best Ways to Draw Polylines on an Image in OpenCV Using Python

πŸ’‘ Problem Formulation: Drawing polylines on images is a common task in image processing that can be used for annotating, geometric transformations, or creating masks. The challenge is to draw a series of connected lines – or a polyline – on the given image accurately, and OpenCV provides the functionality in Python to achieve this. For example, given an image of a road, we may want to draw the approximate path of the lanes as a polyline on the image.

Method 1: Using the cv2.polylines() function

The cv2.polylines() function is the most straightforward method to draw polylines on an image using OpenCV in Python. It draws a series of connected lines by taking a sequence of points, which defines the polyline, and whether the polyline should be closed or not. You also have the option to specify the color, line thickness, and line type.

Here’s an example:

import cv2
import numpy as np

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

# Define points for the polyline
points = np.array([[100, 50], [200, 300], [700, 200], [500, 100]], np.int32)
points = points.reshape((-1, 1, 2))

# Draw the polyline
cv2.polylines(image, [points], isClosed=False, color=(0, 255, 0), thickness=3)

# Show the image
cv2.imshow('Polyline on Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

The output is an image window displaying the original image with a green polyline drawn on it.

This example takes an image and draws a polyline connecting four predefined points. The np.array() contains the coordinates of the points, and reshaping is done for compatibility with the polylines() function. The flag isClosed is set to False to leave the polyline open. The polyline is drawn in green with a thickness of 3 pixels.

Method 2: Drawing Multiple Polylines

When multiple distinct polylines are needed on the same image, you can call the cv2.polylines() function multiple times with different point sets or write a loop to process a list of point sets. This method offers flexibility to customize each polyline individually.

Here’s an example:

import cv2
import numpy as np

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

# Define multiple sets of points for polylines
points_list = [
    np.array([[50, 80], [70, 200], [100, 100]], np.int32),
    np.array([[200, 50], [255, 200], [300, 150]], np.int32)
]

# Draw the polylines
for points in points_list:
    points = points.reshape((-1, 1, 2))
    cv2.polylines(image, [points], isClosed=True, color=(255, 0, 0), thickness=2)

# Show the image
cv2.imshow('Multiple Polylines on Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

The output is an image window displaying the original image with two red polylines drawn on it.

This code snippet demonstrates how to draw multiple polylines on an image. Each set of points for a polyline is stored in a list (points_list). A loop goes through each point set, reshapes it, and then the cv2.polylines() function is called to draw the polyline on the image. This example uses a closed polyline with red color and a thickness of 2 pixels.

Method 3: Anti-Aliased Polylines

For smoother polylines with reduced aliasing, the cv2.polylines() function provides an lineType argument where you can specify anti-aliasing with cv2.LINE_AA. This can be particularly useful when drawing diagonal lines or curves.

Here’s an example:

import cv2
import numpy as np

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

# Define points for the polyline
points = np.array([[40, 70], [60, 150], [120, 80], [180, 20]], np.int32)
points = points.reshape((-1, 1, 2))

# Draw the anti-aliased polyline
cv2.polylines(image, [points], isClosed=False, color=(0, 0, 255), thickness=2, lineType=cv2.LINE_AA)

# Show the image
cv2.imshow('Anti-Aliased Polyline on Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

The output is an image window displaying the original image with a smooth blue polyline drawn on it.

This code snippet illustrates the use of anti-aliasing while drawing polylines. The lineType=cv2.LINE_AA is specified to enhance the visual quality of the polyline. The example produces a smooth blue polyline with a thickness of 2 pixels.

Method 4: Filling a Closed Polyline

In case you need to draw a filled closed polyline (a polygon), you can use the cv2.fillPoly() function. This is particularly useful for creating masks, selections, or just drawing solid shapes.

Here’s an example:

import cv2
import numpy as np

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

# Define points for the polygon
points = np.array([[40, 30], [70, 120], [110, 80], [150, 50]], np.int32)
points = points.reshape((-1, 1, 2))

# Fill the closed polyline (polygon)
cv2.fillPoly(image, [points], color=(0, 255, 255))

# Show the image
cv2.imshow('Filled Polygon on Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

The output is an image window displaying the original image with a filled polygon in a cyan color.

This method extends the idea of drawing polylines to create a filled polygon. The cv2.fillPoly() function is called with the same set of points and fills the area enclosed by the polyline. The result is a solid cyan colored shape that completely fills the defined area.

Bonus One-Liner Method 5: Drawing a Simple Open Polyline

For a quick-and-dirty, one-liner method to draw a simple open polyline on an image, you can use a lambda function to compact the syntax with the necessary steps to draw using cv2.polylines().

Here’s an example:

(lambda img, pts: cv2.polylines(img, [np.array(pts, np.int32).reshape((-1, 1, 2))], False, (255, 255, 0), 2))(cv2.imread('path_to_image.jpg'), [[50, 80], [120, 200], [200, 150]])

The output would be the image with a polyline, although the example does not include the code to display it.

This example represents a condensed way of drawing a polyline using a lambda function, which includes loading the image, defining the points, reshaping, and drawing the polyline in one line. It omits the display sequence in the interest of space and demonstrates a more compact approach for simple scripts or small-scale applications. However, it is not recommended for readability or complex tasks.

Summary/Discussion

    Method 1: Standard Use of cv2.polylines(). Easy to understand. Best suited for simple polylines. Limited aesthetic control for anti-aliasing. Method 2: Drawing Multiple Polylines. Ideal for drawing various shapes in one go. It can be less efficient due to multiple function calls. Method 3: Anti-Aliased Polylines. Provides smooth edges, suitable for high-quality graphics. May be slower due to anti-aliasing processing. Method 4: Filling a Closed Polyline. Useful for drawing solid shapes (polygons). It’s specific to filled shapes, not polylines. Bonus Method 5: One-Liner Approach. Quick for simple tasks. Lacks clarity for maintenance or collaborative coding.