Drawing over Images

Raghunath D
Jan 28, 2019 · 5 min read

In this, we will learn how to draw lines, rectangles, circles, etc. over images.

OpenCV provides easy to use functions for drawing over an image. The most common drawing operations are given below:

  • Line
  • Circle
  • Rectangle
  • Text

Apart from these, there are other drawing operations like polylines, fillPoly which are used in certain cases.

Creating a black canvas

Let’s start off my making a black square image.

import cv2
import numpy as np
# Create a black image
image = np.zeros((512,512,3), np.uint8)
# Can we make this in black and white?
image_bw = np.zeros((512,512), np.uint8)
cv2.imshow("Black Rectangle (Color)", image)
cv2.imshow("Black Rectangle (B&W)", image_bw)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output:


Python Functions for Drawing

Below we have provided the arguments the function takes. Then we show example code that draws different shapes on an image.

cv2.line ( image, starting point , end point , color , line thickness, line type)

cv2.circle ( image, center, radius, color of border, line thickness / fill type, line type)

cv2.ellipse ( image, center, axes lengths, rotation degree of ellipse, starting angle , ending angle, color, line thickness / fill type, line type)

cv2.rectangle ( image, upper left corner vertex, lower right corner vertex, line thickness / fill type, line type)

cv2.putText ( image, text, starting point of text, font type, font scale, color, linetype )

The thickness of the boundary is controlled by the thickness parameter. By default, only an outline of the shape is drawn. To draw a shape that is filled with the specified color, the thickness should be -1.

The lineType parameter controls the quality of rendering. When lineType is set to CV_AA, anti-aliased ( smooth ) lines are drawn. Type of line, whether 8-connected, anti-aliased line etc. By default, it is 8-connected. cv2.LINE_AA gives anti-aliased line which looks great for curves.


Draw lines

# Draw a diagonal blue line of thickness of 5 pixels
image = np.zeros((512,512,3), np.uint8) # black canvas
cv2.line(image, (0,0), (511,511), (255,127,0), 5)
cv2.imshow("Blue Line", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# drawing a linecv2.line(imageLine,    # image
(322, 179), # starting point
(400, 183), # end point
(0, 255, 0), # color
thickness=2, # thickness
lineType=cv2.LINE_AA # line type
)
cv2.imshow("imageLine", imageLine)
cv2.imwrite("imageLine.jpg", imageLine)

Draw a Rectangle

cv2.rectangle(image, starting vertex, opposite vertex, color, thickness)

# Draw a rectangle (thickness is a positive integer)cv2.rectangle(imageRectangle,     # source image
(208, 55), # upper left corner vertex
(450, 355), # lower right corner vertex
(0, 255, 0), # color
thickness=2, # line thickness
lineType=cv2.LINE_8 # line type
)
cv2.imshow("rectangle", imageRectangle)
cv2.imwrite("imageRectangle.jpg", imageRectangle)

To draw a shape that is filled with the specified color, the thickness should be -1.

# Draw a Rectangle in
image = np.zeros((512,512,3), np.uint8)
cv2.rectangle(image, (100,100), (300,250), (127,50,127), -1)
cv2.imshow("Rectangle", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Draw a Circle

cv2.cirlce(image, center, radius, color, fill)

cv2.circle(imageCircle,      # source image
(350, 200), # center
150, # radius
(0, 255, 0), # color or border
thickness=2, # line thickness
lineType=cv2.LINE_AA # line type
)
cv2.imshow("imageCircle", imageCircle)
cv2.imwrite("imageCircle.jpg", imageCircle)
image = np.zeros((512,512,3), np.uint8)cv2.circle(image, (350, 350), 100, (15,75,50), -1) 
cv2.imshow("Circle", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Draw Concentric circles

# draw concentric white circles
# calculate the center point of canvas
# generate circles using for loop
canvas = np.zeros((300,300,3), dtype ="uint8")
white = (255,255,255)
(centerX, centerY) =
(canvas.shape[1]//2, canvas.shape[0]//2) # width, height
for r in range(0, 175, 25):
cv2.circle(canvas, (centerX, centerY), r, white)
cv2.imshow("concentric circles", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()

Draw Random circles

# generate random radius, center point, color
# draw circles in for loop
canvas = np.zeros((300,300,3), dtype ="uint8")
for i in range(0, 25):
radius = np.random.randint(5, high = 200)
color = np.random.randint(0, high = 256, size = (3,)).tolist()
pt = np.random.randint(0, high = 300, size = (2,))
cv2.circle(canvas, tuple(pt), radius, color, -1)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()

Add Polygons

image = np.zeros((512,512,3), np.uint8)# Let's define four points
pts = np.array( [[10,50], [400,50], [90,200], [50,500]], np.int32)
# Let's now reshape our points in form required by polylines
pts = pts.reshape((-1,1,2))
cv2.polylines(image, [pts], True, (0,0,255), 3)
cv2.imshow("Polygon", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Drawing Text over Image

cv2.putText(image, ‘Text to Display’, bottom left starting point, Font, Font Size, Color, Thickness)

  • FONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN
  • FONT_HERSHEY_DUPLEX,FONT_HERSHEY_COMPLEX
  • FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL
  • FONT_HERSHEY_SCRIPT_SIMPLEX
  • FONT_HERSHEY_SCRIPT_COMPLEX
image = np.zeros((512,512,3), np.uint8)cv2.putText(image, 'Hello World!', (75,290), cv2.FONT_HERSHEY_COMPLEX, 2, (100,170,0), 3)
cv2.imshow("Hello World!", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Example Code

import cv2
import numpy as np
image = cv2.imread('../data/images/mark.jpg')# Draw a line
imageLine = image.copy()
cv2.line(imageLine, (322, 179), (400, 183), (0, 255, 0),
thickness=2, lineType=cv2.LINE_AA)
cv2.imshow("imageLine", imageLine)
cv2.imwrite("imageLine.jpg", imageLine)
# Draw a circle
imageCircle = image.copy()
cv2.circle(imageCircle, (350, 200), 150, (0, 255, 0),
thickness=2, lineType=cv2.LINE_AA)
cv2.imshow("imageCircle", imageCircle)
cv2.imwrite("imageCircle.jpg", imageCircle)
# Draw an ellipse
# IMP Note: Ellipse Centers and Axis lengths must be integers
imageEllipse = image.copy()
cv2.ellipse(imageEllipse, (360, 200), (100, 170), 45, 0, 360,
(255, 0, 0), thickness=2, lineType=cv2.LINE_AA)
cv2.ellipse(imageEllipse, (360, 200), (100, 170), 135, 0, 360,
(0, 0, 255), thickness=2, lineType=cv2.LINE_AA)
cv2.imshow("ellipse", imageEllipse)
cv2.imwrite("imageEllipse.jpg", imageEllipse)
# Draw a rectangle (thickness is a positive integer)
imageRectangle = image.copy()
cv2.rectangle(imageRectangle, (208, 55), (450, 355), (0, 255, 0),
thickness=2, lineType=cv2.LINE_8)
cv2.imshow("rectangle", imageRectangle)
cv2.imwrite("imageRectangle.jpg", imageRectangle)
# Put text into image
imageText = image.copy()
cv2.putText(imageText, "Mark Zuckerberg", (205, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow("text", imageText)
cv2.imwrite("imageText.jpg", imageText)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output:

Raghunath D

Written by

Software Engineer working in Oracle. Data Enthusiast interested in Computer Vision and wanna be a Machine learning engineer.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade