Skip to main content

5-5 Adding to Your Images

PANDORA DEVELOPER GUIDE · CHAPTER 05

Draw Lines on an Image​

OpenCV drawing functions let you annotate frames, visualize detections, and generate simple overlays without leaving the image-processing pipeline. Start with cv.line, which draws a straight segment between two points.

The signatures below follow the official OpenCV drawing functions reference.


cv.line: draw a line segment​

Pass the source image, start and end coordinates, a BGR color, and optional line settings.


Signature​

The Python binding uses this signature:

cv.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img

pt1 and pt2 are (x, y) coordinates. color is normally a BGR tuple, thickness is measured in pixels, lineType controls rasterization, and shift specifies fractional bits in the point coordinates. The function modifies and returns img.


Example: draw a red diagonal line​

The following code will draw a red line from the top-left to the bottom-right corner of an image.

import cv2 as cv
# Set the path to the original image file.
# Don't forget to replace 'Pandora.png' with your own image!
file_path = "Pandora.png"
# Read the image using OpenCV's imread function.
source_picture = cv.imread(file_path)
# Check if the image was loaded successfully.
if source_picture is None:
print("Warning: Could not load the image.")
print(f"Please check if the path is correct: {file_path}")
else:
# --- Create a "canvas copy" of the image ---
# We create a "copy" of the original image called `modified_image`.
# This way, when we draw on `modified_image`,
# we don't affect the original `source_picture`.
# You'll be able to see a side-by-side comparison of the original and
# the modified image!
modified_image = source_picture.copy()
# --- Draw a red line segment on the image! ---
# The cv.line function will draw a line on `modified_image`.
# (0, 0): The starting point of the line, which is the top-left corner of the image.
# (1024, 344): The ending point of the line. This will depend on your image size.
# You can try changing it to
# (modified_image.shape[1]-1, modified_image.shape[0]-1)
# to draw a corner-to-corner diagonal line.
# (0, 0, 255): The color of the line. In OpenCV's BGR format, this is pure red.
# 2: The thickness of the line, set to 2 pixels wide here.
cv.line(modified_image, (0, 0), (1024, 344), (0, 0, 255), 2)
# --- Image display loop ---
# Enter an infinite loop to continuously display the image windows.
while True:
# Display the original image.
cv.imshow("Original Picture", source_picture)
# Display the image with the line drawn on it.
cv.imshow("Picture with Line", modified_image) # Clearer window name!
# The cv.waitKey(1) function pauses the program for
# 1 millisecond to check for a key press.
key = cv.waitKey(1)
# If the ESC key (number 27) is pressed, exit the loop and end the display.
if key & 0xFF == 27:
break
# --- Release resources ---
# Finally, close all image windows created by OpenCV to free up computer resources.
cv.destroyAllWindows()

Program Result:

Graphic confirming that OpenCV is successfully installed on the system

The example opens the original image beside a copy containing the red line.


Common uses include:

  • Marking boundaries, vectors, or regions of interest.
  • Building geometric overlays from multiple segments.
  • Visualizing measurements and algorithm output.

Change pt1, pt2, color, or thickness to experiment with placement and appearance.

Draw Rectangles​

Use cv.rectangle to outline a detection, highlight a region of interest, or draw a filled rectangular overlay.


cv.rectangle: draw a rectangular region​

Define two opposite corners, then provide the color and optional line settings.


Signature​

The Python binding uses this signature:

cv.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img

pt1 and pt2 identify opposite corners. Set thickness to a positive pixel width for an outline or use cv.FILLED to fill the rectangle. The function modifies and returns img.


Example: draw a blue rectangle​

The following code will draw a blue rectangle on an image.

import cv2 as cv
# Set the path to the original image file.
file_path = "Pandora.png"
# Read the image using OpenCV's imread function.
source_picture = cv.imread(file_path)
# Check if the image was loaded successfully.
if source_picture is None:
print(f"Warning: Couldn't load the image. Please check the path: {file_path}")
else:
# --- Create a "canvas copy" of the image ---
# We create a "copy" of the original image called `modified_image`.
# This way, when we draw on `modified_image`,
# we don't affect the original `source_picture`.
# You'll be able to see a side-by-side comparison of the original and
# the modified image!
modified_image = source_picture.copy()
# --- Draw a blue rectangle on the image! ---
# The cv.rectangle function will draw a box on `modified_image`.
# (30, 30): The top-left corner's coordinate (x=30, y=30).
# (30 + 632, 30 + 200): The bottom-right corner's coordinate.
# This means starting from the top-left corner,
# it extends 632 pixels to the right and 200 pixels down.
# So the actual bottom-right coordinate is (662, 230).
# (255, 0, 0): The color of the rectangle's border.
# In OpenCV's BGR format, this is pure blue.
# 8: The thickness of the border, set to 8 pixels wide here.
cv.rectangle(modified_image, (30, 30), (30 + 632, 30 + 200),
(255, 0, 0), 8)
# --- Image display loop ---
# Enter an infinite loop to continuously display the image windows.
while True:
# Display the original image.
cv.imshow("Original Picture", source_picture)
# Display the image with the rectangle drawn on it.
cv.imshow("Picture with Rectangle", modified_image) # Clearer window name!
# The cv.waitKey(1) function pauses the program for
# 1 millisecond to check for a key press.
key = cv.waitKey(1)
# If the ESC key (number 27) is pressed, exit the loop and end the display.
if key & 0xFF == 27:
break
# --- Release resources ---
# Finally, close all image windows created by OpenCV to free up computer resources.
cv.destroyAllWindows()

Program Result:

Visual chart of different Python built-in data types like int, float, str, and list

The example opens the original image beside a copy containing the blue rectangle.


Common uses include:

  • Drawing bounding boxes around detected objects.
  • Highlighting regions of interest.
  • Creating simple interface or status overlays.

Change pt1, pt2, color, or thickness to test different positions and styles.

Draw Circles​

Use cv.circle to mark keypoints, centers, round objects, or target locations.


cv.circle: draw a circle​

Provide the center coordinate, radius, BGR color, and optional line settings.


Signature​

The Python binding uses this signature:

cv.circle(img, center, radius, color[, thickness[, lineType[, shift]]]) -> img

Set thickness to a positive pixel width for an outline or use cv.FILLED for a solid circle. The function modifies and returns img.


Example: draw a green circle​

The following code will draw a magenta ellipse on an image.

import cv2 as cv
# Set the path to the original image file.
file_path = "Pandora.png"
# Read the image using OpenCV's imread function.
source_picture = cv.imread(file_path)
# Check if the image was loaded successfully.
if source_picture is None:
print("Warning: Could not load the image.")
print(f"Please check if the path is correct: {file_path}")
else:
# --- Create a "canvas copy" of the image ---
# We create a "copy" of the original image called `modified_image`.
# This way, when we draw on `modified_image`,
# we don't affect the original `source_picture`.
# You'll be able to see a side-by-side comparison of the original and
# the modified image!
modified_image = source_picture.copy()
# --- Draw a green circle on the image! ---
# The cv.circle function will draw a circle on `modified_image`.
# (410, 172): The center's coordinate (x=410, y=172).
# 50: The radius of the circle, set to 50 pixels here.
# (0, 255, 0): The color of the circle's border. In OpenCV's BGR format,
# this is pure green.
# 5: The thickness of the border, set to 5 pixels wide here.
cv.circle(modified_image, (410, 172), 50, (0, 255, 0), 5)
# --- Image display loop ---
# Enter an infinite loop to continuously display the image windows.
while True:
# Display the original image.
cv.imshow("Original Picture", source_picture)
# Display the image with the circle drawn on it.
cv.imshow("Picture with Circle", modified_image) # Clearer window name!
# The cv.waitKey(1) function pauses the program for
# 1 millisecond to check for a key press.
key = cv.waitKey(1)
# If the ESC key (number 27) is pressed, exit the loop and end the display.
if key & 0xFF == 27:
break
# --- Release resources ---
# Finally, close all image windows created by OpenCV to free up computer resources.
cv.destroyAllWindows()

Program Result:

5-5 Adding to Your Images

The example opens the original image beside a copy containing the green circle.


Common uses include:

  • Marking keypoints, eyes, or round objects.
  • Showing target or tracking coordinates.
  • Visualizing radii and distance thresholds.

Change center, radius, color, or thickness to test different placements and styles.


Draw Ellipses​

Use cv.ellipse when a circle does not accurately represent the object or region you need to annotate. You can control the center, axis lengths, rotation, arc range, color, and line style.


cv.ellipse: draw an elliptic arc​

An ellipse requires a center point, half-axis lengths, a rotation angle, and start and end angles. Use 0 and 360 for the arc angles to draw a complete ellipse.


Signature​

The Python binding uses this signature:

cv.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) -> img

axes contains the horizontal and vertical half-axis lengths. angle rotates the ellipse, while startAngle and endAngle select the portion of the arc to render. The function modifies and returns img.


Example: draw a rotated magenta ellipse​

The following code will draw a magenta ellipse on an image.

import cv2 as cv
# Set the path to the original image file.
file_path = "Pandora.png"
# Read the image using OpenCV's imread function.
source_picture = cv.imread(file_path)
# Check if the image was loaded successfully.
if source_picture is None:
print(f"Warning: Couldn't load the image. Please check the path: {file_path}")
else:
# --- Create a "canvas copy" of the image ---
# We create a "copy" of the original image called `modified_image`.
# This way, when we draw on `modified_image`,
# we don't affect the original `source_picture`.
# You'll be able to see a side-by-side comparison of the original and the
# modified image!
modified_image = source_picture.copy()
# --- Draw a magenta ellipse on the image! ---
# The cv.ellipse function will draw an ellipse on `modified_image`.
# (650, 172): The center's coordinate (x=650, y=172).
# (100, 130): The half-axis lengths of the ellipse.
# This means the horizontal half-axis is 100 pixels long and
# the vertical is 130.
# (Note: The order here is (x-axis radius, y-axis radius),
# not necessarily major/minor, it depends on the `angle`.)
# 90: The rotation angle of the ellipse, set to 90 degrees counter-clockwise here.
# 0: The starting angle for drawing, starting from 0 degrees.
# 360: The ending angle, ending at 360 degrees, which means a full ellipse is drawn.
# (255, 0, 255): The color of the ellipse's border. In OpenCV's BGR format,
# this is magenta.
# 5: The thickness of the border, set to 5 pixels wide here.
cv.ellipse(modified_image, (650, 172), (100, 130), 90, 0, 360,
(255, 0, 255), 5)
# --- Image display loop ---
# Enter an infinite loop to continuously display the image windows.
while True:
# Display the original image.
cv.imshow("Original Picture", source_picture)
# Display the image with the ellipse drawn on it.
cv.imshow("Picture with Ellipse", modified_image) # Clearer window name!
# The cv.waitKey(1) function pauses the program for
# 1 millisecond to check for a key press.
key = cv.waitKey(1)
# If the ESC key (number 27) is pressed, exit the loop and end the display.
if key & 0xFF == 27:
break
# --- Release resources ---
# Finally, close all image windows created by OpenCV to free up computer resources.
cv.destroyAllWindows()

Program Result:

5-5 Adding to Your Images

The example opens the original image beside a copy containing the rotated magenta ellipse.


Common uses include:

  • Approximating elongated or rotated objects.
  • Visualizing fitted contours and orientation.
  • Drawing partial arcs by changing the start and end angles.

Change center, axes, angle, color, or thickness to test different geometries and styles.

Draw Polylines and Polygons​

Use cv.polylines to connect a sequence of vertices. It works for open paths as well as closed polygons, making it useful for irregular regions and custom overlays.


cv.polylines: connect multiple vertices​

Pass one or more arrays of points and use isClosed to control whether OpenCV connects the final vertex back to the first.


Signature​

The Python binding uses this signature:

cv.polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]]) -> img

pts is a sequence of point arrays. Set isClosed to True for polygons or False for open paths. The function modifies and returns img.


Example: draw a yellow pentagon​

The following code will draw a yellow pentagon on an image.

import cv2 as cv
import numpy as np # We need NumPy to handle the point coordinates
# Set the path to the original image file.
file_path = "Pandora.png"
# Read the image using OpenCV's imread function.
source_picture = cv.imread(file_path)
# Check if the image was loaded successfully.
if source_picture is None:
print("Warning: Could not load the image.")
print(f"Please check if the path is correct: {file_path}")
else:
# --- Create a "canvas copy" of the image ---
# We create a "copy" of the original image called `modified_image`.
# This way, when we draw on `modified_image`,
# we don't affect the original `source_picture`.
# You'll be able to see a side-by-side comparison of the original and
# the modified image!
modified_image = source_picture.copy()
# --- Define the "vertices" coordinates of the polygon ---
# These points will be connected in order to form the sides of the polygon.
# The coordinates must be of integer type (np.int32).
pts = np.int32([
[285, 215], # First point
[354, 175], # Second point
[415, 227], # Third point
[381, 300], # Fourth point
[305, 295] # Fifth point
])
# --- Adjust the data format of the points ---
# The polylines function expects the points to be in a format like this:
# [[[x1,y1]], [[x2,y2]], ...].
# So we need to use the reshape function to adjust the point array.
# `(-1, 1, 2)` means:
# -1: Let NumPy automatically calculate the number of points.
# 1: Treat each point group as a separate array
# (used for drawing multiple disconnected polygons).
# 2: Each point has two coordinates, x and y.
pts = pts.reshape((-1, 1, 2))
# --- Draw a yellow polygon on the image! ---
# The cv.polylines function will draw a polygon on `modified_image`.
# `[pts]`: Here we wrap `pts` in square brackets to indicate
# we have only one polygon to draw.
# `True`: `isClosed` is set to True, which means the last point will
# be connected to the first,
# forming a closed pentagon.
# `(0, 255, 255)`: The color of the polygon's lines. In OpenCV's BGR format,
# this is yellow.
# `5`: The thickness of the lines, set to 5 pixels wide here.
# `cv.LINE_AA`: Use "anti-aliasing" mode to draw smoother, nicer-looking lines.
cv.polylines(modified_image, [pts], True, (0, 255, 255), 5, cv.LINE_AA)
# --- Image display loop ---
# Enter an infinite loop to continuously display the image windows.
while True:
# Display the original image.
cv.imshow("Original Picture", source_picture)
# Display the image with the polygon drawn on it.
cv.imshow("Picture with Polygon", modified_image) # Clearer window name!
# The cv.waitKey(1) function pauses the program for
# 1 millisecond to check for a key press.
key = cv.waitKey(1)
# If the ESC key (number 27) is pressed, exit the loop and end the display.
if key & 0xFF == 27:
break
# --- Release resources ---
# Finally, close all image windows created by OpenCV to free up computer resources.
cv.destroyAllWindows()

Program Result:

5-5 Adding to Your Images

The example opens the original image beside a copy containing the yellow pentagon.


Common uses include:

  • Outlining irregular regions or segmentation boundaries.
  • Drawing custom geometric overlays.
  • Visualizing paths, zones, and map boundaries.

Change the coordinates in pts, add or remove vertices, or toggle isClosed to compare open and closed paths.

Add Text to an Image​

Use cv.putText to add labels, measurements, status messages, or recognition results directly to an image.


Signature​

The Python binding uses this signature:

cv.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]]) -> img

org is the bottom-left corner of the text baseline. fontFace selects an OpenCV Hershey font, fontScale controls size, and bottomLeftOrigin changes the image-origin convention. The function modifies and returns img.


Example: write “Pandora”​

The following code will write the text "Pandora" on an image and make it red.

import cv2 as cv
# Set the path to the original image file.
file_path = "Pandora.png"
# Read the image using OpenCV's imread function.
source_picture = cv.imread(file_path)
# Check if the image was loaded successfully.
if source_picture is None:
print("Warning: Could not load the image.")
print(f"Please check if the path is correct: {file_path}")
else:
# --- Create a "canvas copy" of the image ---
# We create a "copy" of the original image called `modified_image`.
# This way, when we write on `modified_image`,
# we don't affect the original `source_picture`.
# You'll be able to see a side-by-side comparison of the original and
# the modified image!
modified_image = source_picture.copy()
# --- Write text on the image! ---
# The cv.putText function will write text on `modified_image`.
# 'Pandora': The text content we want to write.
# (270, 125): The starting coordinate (x=270, y=125) of the text's
# bottom-left corner.
# cv.FONT_HERSHEY_SIMPLEX: We've chosen to use this common and simple font.
# 1.0: The font scaling factor, set to 1.0x size here.
# (0, 0, 255): The color of the text. In OpenCV's BGR format, this is pure red.
# 3: The thickness of the text strokes, set to 3 pixels wide here.
cv.putText(modified_image, 'Pandora', (270, 125), cv.FONT_HERSHEY_SIMPLEX,
1.0, (0, 0, 255), 3)
# --- Image display loop ---
# Enter an infinite loop to continuously display the image windows.
while True:
# Display the original image.
cv.imshow("Original Picture", source_picture)
# Display the image with the text written on it.
cv.imshow("Picture with Text", modified_image) # Clearer window name!
# The cv.waitKey(1) function pauses the program for
# 1 millisecond to check for a key press.
key = cv.waitKey(1)
# If the ESC key (number 27) is pressed, exit the loop and end the display.
if key & 0xFF == 27:
break
# --- Release resources ---
# Finally, close all image windows created by OpenCV to free up computer resources.
cv.destroyAllWindows()

Program Result:

5-5 Adding to Your Images

The example opens the original image beside a copy labeled “Pandora.”


Common uses include:

  • Adding watermarks or source identifiers.
  • Labeling detected objects and regions.
  • Displaying confidence scores, measurements, or status information.
  • Writing titles and explanatory overlays.

Change text, org, fontFace, fontScale, color, or thickness to adjust the label.


Adapted from the original YUAN Developer Hub article. Source ID: 248.