Sunday, September 17, 2023

User Interaction in OpenCV- Draw Circles with Mouse

This example will use mouse to draw circles with cv2.circle() function provided by OpenCV. Here's the basic syntax of the function:

cv2.circle(img, center, radius, color, thickness)

The parameters: 


This example works in this way, when the left key of the mouse is pressed the center of the circle is decided, then hold the left key and move the mouse, the radius of the circle is continuously calculated while the mouse is moving. When the mouse left key is released the radius is finalized and the final circle is drawn on the canvas, the center coordinates and the radius are also shown on the canvas. While the mouse is moving with the left key down, a thin circle is drawn alone with the mouse moving in order to indicate how the circle looks like.


Here are the codes:

1 import cv2

2 import numpy as np

3 import math

4 import common.Draw as dw

5

6 drawing = False

7 final_color = (255, 255, 255)

8 drawing_color = (125, 125, 125)

9

10 def on_mouse(event, x, y, flags, param):

11 global drawing, ctr, radius, img, img_bk

12 if event == cv2.EVENT_LBUTTONDOWN:

13 drawing = True

14 ctr = x, y

15 radius = 0

16 draw_circle(img, ctr, radius, drawing_color)

17 elif event == cv2.EVENT_MOUSEMOVE:

18 if drawing == True:

19 img = img_bk.copy()

20 radius = calc_radius(ctr, (x,y))

21 draw_circle(img, ctr, radius, drawing_color)

22 elif event == cv2.EVENT_LBUTTONUP:

23 drawing = False

24 radius = calc_radius(ctr, (x,y))

25 draw_circle(img, ctr, radius, final_color, 2, True)

26 img_bk = img.copy()

The source codes are a little bit longer, we break it into three parts, first take a look

at the mouse callback function on_mouse(), it captures three events:

EVENT_LBUTTONDOWN, EVENT_MOUSEMOVE and EVENT_RBUTTONDOWN.


The next part of the source codes is to define several functions, calc_radius() is using a math function math.hypot() to calculate the radius based on the center point and current point; draw_circle() is to draw a circle, which includes drawing a point for the center, and drawing texts to display the center coordinates and radius. print_instruction() is to display the instruction texts on the top of the canvas.

28 def calc_radius(center, current_point):

29 cx, cy = current_point

30 tx, ty = center

31 return int(math.hypot(cx - tx, cy - ty))

32

33 def draw_circle(img, center, r, color,

line_scale=1, is_final=False ):

34 txtCenter = "ctr=(%d,%d)" % center

35 txtRadius = "r=%d" % radius

36 if is_final == True:

37 print("Completing circle with %s and %s" % (txtCenter, txtRadius))

38 dw.draw_circle(img, center, 1, color, line_scale) # draw center

39 dw.draw_circle(img, center, r, color, line_scale) # draw circle

40 dw.draw_text(img, txtCenter, (center[0]-60, center[1]+20), 0.5, color)

41 dw.draw_text(img, txtRadius, (center[0]-15, center[1]+35), 0.5, color)

42 43 def print_instruction(img):

44 txtInstruction = "Press and hold left key to draw a circle. ESC to exit."

45 dw.draw_text(img,txtInstruction, (10, 20), 0.5, (255, 255, 255))

46 print(txtInstruction)

The final part of the source code is the main function, which is similar to previous example codes and straightforward, we will not explain it in detail here.

48 def main():

49 global img, img_bk

50 windowName = 'Mouse Drawing Circles'

51 img = np.zeros((500, 640, 3), np.uint8)

52 print_instruction(img)

53 img_bk = img.copy()

54 cv2.namedWindow(windowName)

55 cv2.setMouseCallback(windowName, on_mouse)

56 while (True):

57 cv2.imshow(windowName, img)

58 if cv2.waitKey(20) == 27:

59 break

60 cv2.destroyAllWindows()

61

62 if __name__ == '__main__':

63 main()

Execute the codes in DrawCircleWithMouse.py, you will be able to draw circles on the canvas with mouse operations, the results are something like Figure shown at the beginning of the post.

Share:

0 comments:

Post a Comment