How to Listen Mouse Events in OpenCV

In this post will be having a illustration of an app on how the mouse events work in opencv and will provide a light on callback function and the cv2.setMouseCallback() function

Introduction

Welcome! In this post I am going to illustrate how to listen mouse events in OpenCV, in last post I have described how to convert colour image to grayscale image in OpenCV using Python, do read it if your are new to openCV and also if you like reading the post do checkout our all posts about OpenCV here
So in this tutorial we will create a small application which will draw the path followed by the mouse pointer on the canvas. In order to do this we will divide the creation into two simple steps:

  • Writing the Callback Function
  • Adding the Callback function to cv2.setMouseCallback() function

Basically a Callback Function is a kind of normal function definition but is used to define the instructions to be executed during the happening of the event (i.e., the click or drag of the mouse), we will discuss in detail in the upcoming section and in the second section we will see how to add that Callback Function to the main program so that the active frame execute the Callback Function when event happens.
So with this let's step up towards our first step to create the application, that is building the Callback Function.

Mouse Callback Function

A callback function is the function which will get executed whenever the event happens, so basically the callback function have a same syntax definition wherever it is used but can differ in what it does as it totally depends on what instruction are written in it.

def draw(event,x,y,flags,param):
​ if event == cv2.EVENT_MOUSEMOVE:
​  cv2.circle(img,(x,y),10,(255,0,0),-1)​

​So in the above code snippet we are declaring a Callback function having five parameters. The first parameter event holds the value of the type of event such as left button click, right button click, etc. The second and thrid parameter x, y are the coordinates of the pointer.

​This is all which we need to create our logic and draw a dot on the canvas wherever our pointer is. So in the first line of the code we declare the function draw_circle() having the five paramters which are needed. In the second line of code we check for the type of event which is required to be handled, in our case we are handeling the left button click of the mouse to draw the circle and if the condition satisfies we will draw the circle using the cv2.circle() function. The circle would be drawn on img at x and y coordinates of 10 radius with blue color (BGR) and would be filled circle as we passed the thickness parameter to be -1.​

Adding CallBack to cv2.setMouseCallback() function

Now as our callback function is ready to perform some action on listening the event we need to add it to the eventHandler in opencv using the cv2.setMouseCallback() function which will trigger the callback function for the particular window on which it is listening the event.

So firstly we have to create our canvas on which we would be drawing with mouse and then we would provide it a window with a name and finally add the callback function to that window. and in order to show the image and keep taking the input we will run the cv2.imshow() function in a continuous while loop.

img = np.zeros((512,512,3), np.uint8)
​cv2.namedWindow('image')
​cv2.setMouseCallback('image', draw)

​while(True):
​ cv2.imshow('image', img)
​ if cv2.waitKey(20) & 0xff == 27:
​  break

​cv2.destroyAllWindows()​

In the above code we firstly creating the img image which is a black canvas and then in second line we created a named window and on that named window in third line we added the callback function. Then in infinite while loop we are showing the image and the to break the while loop we added a condition to listen the keyboard presses and if the Escape button is pressed exit the loop and then execute the cv2.destroyAllWindows() function which will destroy all windows created by OpenCV.

Combining the Whole Code

def draw(event,x,y,flags,param):
​ if event == cv2.EVENT_MOUSEMOVE:
​  cv2.circle(img,(x,y),10,(255,0,0),-1)

​img = np.zeros((512,512,3), np.uint8)
​cv2.namedWindow('image')
​cv2.setMouseCallback('image', draw)

​while(True):
​ cv2.imshow('image', img)
​ if cv2.waitKey(20) & 0xff == 27:
​  break

​cv2.destroyAllWindows()​​

Output

Akash Srivastava
Software Engineer @ Seawoods Ventures Inc.
© 2019-2024 dev-akash.in