Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

The way this series of columns are written

This series of columns will use the first question-and-answer writing format to quickly introduce you to the beginner, intermediate, and advanced levels of OpenCV.

3. How to draw various graphics in Python OpenCV?

This blog post is about drawing different geometries in Python OpenCV.

Geometric figures here mainly involve plane figures, such as straight lines, circles, rectangles and ellipses. Of course, drawing text on the image also belongs to the category of figures

The specific functions involved include cv2.line, cv2.circle, cv2.rectangle, cv2.ellipse, and cv2.puttext

In the following sections, we will explain these functions, with emphasis on explaining the various problems associated with their use.

Although there are many functions above, the internal parameters of the function are roughly the same, including the following contents, which can be remembered in advance

  • image: To manipulate the image, is you want to draw graphics on the original;
  • color: Color of the graph. Take BGR as an example. The data type of the parameter is a tuple(0,0,255)Red, if it is grayscale, just need to pass in a grayscale value;
  • thickness: Line thickness of the graph. The default value is 1. If you want to fill the graph internally, that is, close the graph, set this parameter to- 1;
  • linetype: Type of lines, 8 connected lines, 4 connected lines, anti-aliasing. The default value is 8 connected lines. If anti-aliasing is enabled, the efficiency is affected, but the lines will become smooth.

Draw a straight linecv2.line

The basic usage and effects of the function can be found in the following code:

import numpy as np
import cv2

Create a 400 by 400 3 channel black image
img = np.zeros((400.400.3), np.uint8)

# Draw a line
cv2.line(img, (0.0), (250.250), (0.0.255), 3)


cv2.namedWindow("img", cv2.WINDOW_AUTOSIZE)
cv2.imshow("img", img)
cv2.waitKey()
Copy the code

The result is to draw a red line with a line thickness of 3 from coordinates (0,0) to (250,250).

There is no problem with the basic use of the above code and it is easy to understand. The common problems are as follows. During the code execution, an error will be reported because of the data type of the coordinate point tuple, and the error message is as follows:

TypeError: integer argument expected, got float
Copy the code

The problem is caused by the following code sample.

# Draw a line. Note that the value in the second tuple is of type float
cv2.line(img, (0.0), (250.0.250.0), (0.0.255), 3)
Copy the code

Since it is a type error, directly modify the data type can be.

The second thing to note is that this type of function draws on the original image and does not need to receive an additional return value through a variable, so the following is true but rare.

# Draw a line
new_img = cv2.line(img, (0.0), (250.250), (0.0.255), 3)
Copy the code

Note the prototype of this function:

line(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img
Copy the code

Draw a rectanglecv2.rectangle

Rectangle drawing only needs to know the coordinates of the upper left corner and the lower right corner of the rectangle to be drawn.

For example:

cv2.rectangle(img, (100.100), (200.200), (0.255.0), 3, cv2.LINE_4)
Copy the code

The basic use of functions is still outside the scope of this article, and you should note that the two coordinate points are not strictly in order.

As long as it is two points on the diagonal of the rectangle, the core is based on the value of the tuple, for example, the following two lines of code get the same rectangle

cv2.rectangle(img, (100.100), (200.200), (0.255.0), 3, cv2.LINE_4)
cv2.rectangle(img, (200.200), (100.100), (0.255.0), 3, cv2.LINE_4)
Copy the code

Drawing a rectangle also raises the following code exceptions, known as data type problems, for example:

TypeError: argument for rectangle() given by name ('thickness') and position (4)
Copy the code

The reason for this exception is that the Thickness parameter provides a non-integer value, such as Thickness = 4.0

For more information, see the documentation

Draw circles and ovalscv2.circlecv2.ellipse

Drawing a circle in OpenCV is basically the same as drawing an ellipse. Use the help function to get the relevant usage.

circle(img, center, radius, color[, thickness[, lineType[, shift]]]) -> img
Copy the code

The difference between this function and the preceding two is that the center and RADIUS parameters are added, meaning the center point and radius respectively.

Test cases are as follows:

cv2.circle(img, (200.200), 100, (255.0.0))

cv2.namedWindow("img", cv2.WINDOW_AUTOSIZE)
cv2.imshow("img", img)
cv2.waitKey()
Copy the code

The operating effect is shown in the figure below:

Ellipse drawing function prototype is as follows:

ellipse(img, center, axes, angle, start_angle, end_angle, color, thickness=1, lineType=8, shift=0)
Copy the code

The new parameters are Center, axes, Angle, start_angle, and end_angle.

Test the relevant functions first, and then solve common problems.

cv2.ellipse(img, (200.200), (100.50), 0.0.180, (0.0.255))
Copy the code

After this code is run, the following graph will be formed. The above parameters are explained at the end of the picture.

  • center: the center of an ellipse;
  • axes: major and minor axes of ellipses, represented by tuples, e.g. (100,50)
  • angle: Draw the ellipse rotation Angle, you can try 0 degrees, 90 degrees, the Angle is clockwise rotation;
  • start_angle.end_angle: Starting Angle and ending Angle of elliptic arc.

To test the Angle parameter, use the following code.

cv2.ellipse(img, (200.200), (100.50), 0.0.180, (0.255.0))
cv2.ellipse(img, (200.200), (100.50), 60.0.180, (0.0.255))
cv2.namedWindow("img", cv2.WINDOW_AUTOSIZE)
cv2.imshow("img", img)
cv2.waitKey()
Copy the code

The result is as follows

Following the function introduction, we know that drawing the entire ellipse is 0,360, and drawing the lower half ellipse is 0,180.

If you want to get a solid ellipse while drawing the ellipse, you can set it as follows. Of course, the following code is still drawing a half ellipse, you can change it to loop.

cv2.ellipse(img, (200.200), (100.50), 0.0.45, (0.255.0), -1)
cv2.ellipse(img, (200.200), (100.50), 0.45.90, (0.0.255), -1)
cv2.ellipse(img, (200.200), (100.50), 0.90.135, (255.0.0), -1)
cv2.ellipse(img, (200.200), (100.50), 0.135.180, (255.255.0), -1)
Copy the code

Image rendering textcv2.putText

The biggest problem of drawing on the image is the Chinese problem, and this problem cannot be solved by OPenCV. The strategy provided on the Internet also adopts PIL to draw the text, so we can refer to it directly.

The core reason is that Cv2. putText does not support full ASCII characters, only some, let alone Unicode characters, so it can only be drawn using PIL.

The prototype of this function is as follows:

putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]]) -> img
Copy the code

The differentiated parameters are text, org, fontFace and fontScale

Implement the case first, and illustrate it:

cv2.putText(img, 'OpenCV', (50.50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255.255.255), 2)
Copy the code

For the fontFace parameter, I directly refer to OPenCV C++ source code, provided for your reference:

/ /! Only a subset of Hershey fonts
enum HersheyFonts {
    FONT_HERSHEY_SIMPLEX        = 0./ /! < normal size sans-serif font
    FONT_HERSHEY_PLAIN          = 1./ /! < small size sans-serif font
    FONT_HERSHEY_DUPLEX         = 2./ /! < normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
    FONT_HERSHEY_COMPLEX        = 3./ /! < normal size serif font
    FONT_HERSHEY_TRIPLEX        = 4./ /! < normal size serif font (more complex than FONT_HERSHEY_COMPLEX)
    FONT_HERSHEY_COMPLEX_SMALL  = 5./ /! < smaller version of FONT_HERSHEY_COMPLEX
    FONT_HERSHEY_SCRIPT_SIMPLEX = 6./ /! < hand-writing style font
    FONT_HERSHEY_SCRIPT_COMPLEX = 7./ /! < more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
    FONT_ITALIC                 = 16 / /! < flag for italic font
};
Copy the code

Other parameters, most importantly fontScale font size.

After learning this function, we can manipulate the video file, then add the English font watermark, change the position of the previous blog post, the result is as follows

Last: Many sources on the web will tell you that these graph functions do not return a value.

cv.Circle(img, center, radius, color, thickness=1, lineType=8, shift=0) -None
Copy the code

Video file, then add the English font watermark, modify the corresponding position of the previous blog

Last: Many sources on the web will tell you that these graph functions do not return a value.

cv.Circle(img, center, radius, color, thickness=1, lineType=8, shift=0) -None
Copy the code

Note that this is an error, version 3.0 or higher, this article is involved in the function return value, no longer null, while learning, please test the actual.