Mastering OpenCV 4 with Python
上QQ阅读APP看书,第一时间看更新

A theoretical introduction to drawing in OpenCV

OpenCV provides many functions to draw basic shapes. Common basic shapes include lines, rectangles, and circles. However, with OpenCV we can draw more basic shapes. As mentioned briefly in the introduction, it is a common approach to draw basic shapes on the image in order to do the following:

  • Show some intermediate results of your algorithm
  • Show the final results of your algorithm
  • Show some debugging information

In the next screenshot, you can see an image modified to include some useful information in connection with the two algorithms mentioned in the introduction (face detection and face recognition). In this way, you can process all the images in a directory and, afterward, you can see where your algorithm has detected wrong faces (false positives) or even missing faces (false negatives):

false positive  is an error where the result indicates the presence of a condition when in reality the condition is not satisfied (for example, a chair is classified as a face). A false negative is an error where the result indicates the absence of a condition when in reality the condition should be satisfied (for example, a face is not detected).

In this chapter, we are going to see how to draw some basic shapes and text in different colors. To introduce this and to review some concepts from previous chapters, we are going to show you two basic functionalities that we will be using in most of the examples in this chapter. The first functionality is building a colors dictionary, which defines the main colors to be used. In the next screenshot, you can see how it works:

It should be pointed out that this dictionary is just for training and practicing purposes; for other purposes, there are other options that you can use. A common approach is to create a constant.py file to define the colors. Each color is defined by a constant:

"""
Common colors triplets (BGR space) to use in OpenCV
"""

BLUE = (255, 0, 0)
GREEN = (0, 255, 0)
RED = (0, 0, 255)
YELLOW = (0, 255, 255)
MAGENTA = (255, 0, 255)
CYAN = (255, 255, 0)
DARK_GRAY = (50, 50, 50)
...

The following code will enable you to use these constants:

import constant

# Getting red color:
print("red: '{}'".format(constant.RED))

Constants are usually specified in capital letters (for example, BLUE) and with underscores between the words (for example, DARK_GRAY).

Additionally, as we are going to plot the figures using Matplotlib, we have created a show_with_matplotlib() function with two arguments. The first one is the image we want to show, and the second is the title of the figure to plot. Therefore, the first step of this function converts the BGR image to RGB, because you have to show color images with Matplotlib. The second and final step of this function is to show the image using Matplotlib capabilities. To put these pieces together, the testing_colors.py script has been coded. In this script, we draw some lines, each one in a color of the dictionary.

The code to create the dictionary is shown here:

# Dictionary containing some colors
colors = {'blue': (255, 0, 0), 'green': (0, 255, 0), 'red': (0, 0, 255), 'yellow': (0, 255, 255), 'magenta': (255, 0, 255), 'cyan': (255, 255, 0), 'white': (255, 255, 255), 'black': (0, 0, 0), 'gray': (125, 125, 125), 'rand': np.random.randint(0, high=256, size=(3,)).tolist(), 'dark_gray': (50, 50, 50), 'light_gray': (220, 220, 220)}

You can see that some predefined colors are included in this dictionary—blue, green, red, yellow, magenta, cyan, white, black, gray, a random one, gray, dark_gray, and light_gray. If you want to use a specific color (for example, magenta), you should perform the following:

colors['magenta']

Alternatively, you can use (255, 0, 255) to get the magenta color. But it is easier to use this dictionary rather than write triplets of numbers, because you do not need to memorize the addition properties of the RGB color space (adding blue(255,0,0) and red(0,0,255) gives magenta(255, 0, 255) ). Remember that you can use constant.py to perform this functionality.

If you do not know what these numbers are or represent, you should read Chapter 2, Image Basics in OpenCV, where these concepts are introduced. 

In order to see how to use these two functionalities, which we use in most of the examples in this chapter (the colors function and the show_with_matplotlib()function), we have created the testing_colors.py script. If you execute it, you will see the next screenshot:

In this example, we have created an image of size 500  500, with the 3 channels (we want a color image) and a uint8 type (8-bit unsigned integers). We have created it with a black background:

# We create the canvas to draw: 400 x 400 pixels, 3 channels, uint8 (8-bit unsigned integers)
# We set background to black using np.zeros()
image = np.zeros((500, 500, 3), dtype="uint8")

In this case, we want to set the background to light gray, not black. If you want to change the background, you can perform the following:

# If you want another background color, you can do the following:
image[:] = colors['light_gray']

Next, we add the functionality of drawing some lines, each one in a color of the dictionary. It should be noted that in the next section we are going to see how to create some basic shapes, so do not worry if you don't understand the code to create the lines:

# We draw all the colors to test the dictionary
# We draw some lines, each one in a color. To get the color, use 'colors[key]'
separation = 40
for key in colors:
cv2.line(image, (0, separation), (500, separation), colors[key], 10)
separation += 40

And finally, we draw the image using the created show_with_matplotlib() function:

# Show image:
show_with_matplotlib(image, 'Dictionary with some predefined colors')

The two arguments of show_with_matplotlib() are the image to plot and the title to show. So now we are ready to start creating some basic shapes with OpenCV and Python.