OpenCV Part 1: Drawing on images

This tutorial helps getting started with OpenCV. The materials in this tutorial is the accumulation of the official OpenCV tutorials.

Images in OpenCV

Generally, OpenCV image is a numpy array. In the case of color image, each element in the image 2-D array is a tuple (e.g. (r,g,b)). If the element is a scalar, the image is black and white. The image has x axis (left to right), y axis (top to bottom), and an origin at the top left corner.

Create/Load images


In [1]:
from IPython import display
from matplotlib import pyplot as plt
from matplotlib import image as mpimg
import numpy as np
import cv2

%matplotlib inline

Read an image from file and create a same size black image:


In [2]:
lineimg = cv2.imread("./line-segments-example.jpg")
lineimg = cv2.cvtColor(lineimg, cv2.COLOR_BGR2RGB)
bimg = np.zeros_like(lineimg)

In [3]:
fig, (ax1, ax2) = plt.subplots(1,2)
fig.set_size_inches(12.5,10)
ax1.set_axis_off()
ax1.imshow(bimg)
ax1.set_title("Image created from a numpy array")
ax2.set_axis_off()
ax2.imshow(lineimg)
ax2.set_title("Lane line detection example")


Out[3]:
<matplotlib.text.Text at 0x7f25e225f240>

In [6]:
print("Image shape: {}".format(bimg.shape))


Image shape: (540, 960, 3)

Drawing lines

Drawing lines is required for the first project. To draw a line in OpenCV, we need to specify a starting point and an ending point with attention to the OpenCV's coordinate system. In here, we will draw few lines in the black image: blue-horizontal, green-vertical, red-laneline.


In [4]:
# Blue line
cv2.line(bimg, (0, bimg.shape[0]//2), 
         (bimg.shape[1]-1, bimg.shape[0]//2), (0,0,255), 5)
# Green line
cv2.line(bimg, (bimg.shape[1]//2, 0), 
         (bimg.shape[1]//2, bimg.shape[0]-1), (0,255,0), 5)
# Red lines
cv2.line(bimg, (bimg.shape[1]//2, bimg.shape[0]//2), 
         (0, bimg.shape[0]-1), (255,0,0), 5)
cv2.line(bimg, (bimg.shape[1]//2, bimg.shape[0]//2), 
         (bimg.shape[1]-1, bimg.shape[0]-1), (255,0,0), 5)
plt.axis("off")
plt.imshow(bimg)


Out[4]:
<matplotlib.image.AxesImage at 0x7f25e21d13c8>

Drawing rectangles and text

To draw a rectangle, we need to specify the top left and bottom right corners of the rectangle. Drawing rectangles is often used for marking ROI (region of interest) in images or videos. Rectangles are also annotated with texts. In here, we will draw an orange rectangle with white text on top of it.


In [5]:
# Orange rectangle with thickness 3pt (-1 means fill)
padding = 20
cv2.rectangle(bimg, (bimg.shape[1]//8, bimg.shape[0]//8),
              (bimg.shape[1]//2-padding,bimg.shape[0]//2-padding),
              (233,131,0), 3)
# White text
cv2.putText(bimg, "massachuset", 
            (bimg.shape[1]//8, bimg.shape[0]//8-padding),
            cv2.FONT_HERSHEY_COMPLEX, 1, (255,255,255), 2,
            cv2.LINE_AA)
plt.axis("off")
plt.imshow(bimg)


Out[5]:
<matplotlib.image.AxesImage at 0x7f25e23356a0>

Drawing polygon

To draw a set of (opened or closed) connected lines, we need to give a list of points in a form of a 3-D array (shape: ROWSx1x2).


In [19]:
# Triangle with sky's color
pts = np.array([720, 135, 800, 285, 640, 285])
pts = pts.reshape((-1,1,2))
cv2.polylines(bimg, [pts], True, (0,255,255), 5)
plt.axis("off")
plt.imshow(bimg)


Out[19]:
<matplotlib.image.AxesImage at 0x7f25d6aea208>

Drawing circle and ellipse


In [18]:
# Circles
cv2.circle(bimg, (720,135), 64, (255,255,255), -1)
cv2.circle(bimg, (720,135), 96, (255,255,255), 7)
# Ellipse drawn partially 0 to 120 degree
cv2.ellipse(bimg, (bimg.shape[1]//2, bimg.shape[0]//2), 
            (200,100), 90, 0, 120, (151,189,61), 5)
plt.axis("off")
plt.imshow(bimg)


Out[18]:
<matplotlib.image.AxesImage at 0x7f25d6cddc18>

Merge images

We can merge two images together with cv2.addWeighted function.


In [20]:
merged = cv2.addWeighted(bimg, 0.3, lineimg, 0.7, 0)
plt.axis("off")
plt.imshow(merged)


Out[20]:
<matplotlib.image.AxesImage at 0x7f25d6b437b8>

Extra

By default, OpenCV support optimized computation, we can check if the optimization is turned on by cv2.useOptimized() (True if optimization is enabled). The optimization can be enabled by cv2.setUseOptimized(True).

OpenCV also support performance measurement. We have the elapsed time for a function my_awesome_func(*args) as follow:

e1 = cv2.getTickCount()
my_awesome_func(*args)  # procedures we want to evaluate
e2 = cv2.getTickCount()
time = e2-e1 / cv2.getTickFrequency()

In [ ]: