How to Detect Mouse Clicks and Moves

OpenCV supports for detecting mouse events. Mouse events include mouse clicks and movements over an attached OpenCV window.


OpenCV Example Code


It is very simple to do that. All you have do is to define a callback function in the OpenCV C++ code attaching to the OpenCV window. That callback function will be called every time, mouse events occur. That callback function will also give the coordinates of the mouse events. (e.g - (x, y) coordinate of a mouse click).

Here is the simple OpenCV code to detect left, right and middle mouse clicks and mouse movements with its coordinates

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace std;
using namespace cv;

void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
if  ( event == EVENT_LBUTTONDOWN )
{
cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
}
else if  ( event == EVENT_RBUTTONDOWN )
{
cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
}
else if  ( event == EVENT_MBUTTONDOWN )
{
cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
}
     else if ( event == EVENT_MOUSEMOVE )
     {
          cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;

     }
}

int main(int argc, char** argv)
{
// Read image from file 
Mat img = imread("MyPic.JPG");

//if fail to read the image
if ( img.empty() ) 

cout << "Error loading the image" << endl;
return -1; 
}

//Create a window
namedWindow("My Window", 1);

//set the callback function for any mouse event
setMouseCallback("My Window", CallBackFunc, NULL);

//show the image
imshow("My Window", img);

// Wait until user press some key
waitKey(0);

return 0;

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
You can download this OpenCV visual C++ project from here

Detect Mouse Clicks and Moves Over the OpenCV Window
Detect Mouse Clicks and Moves Over the OpenCV Window


Summary

In the above OpenCV sample code,  "CallbackFunc" function will be called on any mouse event (Moving a mouse over the attached OpenCV window is also a mouse event). By using suitable if - else blocks, I printed only left, right and middle mouse clicks and mouse movements over the window.

Here are new OpenCV functions, found in the above example code. If you are not familiar with the other OpenCV functions as well, please go through the other lessons in this tutorial.


  • void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0)
This function sets a callback function to be called every time any mouse events occurs in the specified window. Here is the detailed explanation of the each parameters of the above OpenCV function.

    • winname - Name of the OpenCV window. All mouse events related to this window will be registered
    • onMouse - Name of the callback function. Whenever mouse events related to the above window occur, this callback function will be called. This function should have the signature like the following
      • void FunctionName(int event, int x, int y, int flags, void* userdata)
        • event - Type of the mouse event. These are the entire list of mouse events
          • EVENT_MOUSEMOVE
          • EVENT_LBUTTONDOWN
          • EVENT_RBUTTONDOWN
          • EVENT_MBUTTONDOWN
          • EVENT_LBUTTONUP
          • EVENT_RBUTTONUP
          • EVENT_MBUTTONUP
          • EVENT_LBUTTONDBLCLK
          • EVENT_RBUTTONDBLCLK
          • EVENT_MBUTTONDBLCLK
        • x - x coordinate of the mouse event
        • y - y coordinate of the mouse event
        • flags - Specific condition whenever a mouse event occurs. See the next OpenCV example code for the usage of this parameter. Here is the entire list of enum values which will be possesed by "flags"
          • EVENT_FLAG_LBUTTON
          • EVENT_FLAG_RBUTTON
          • EVENT_FLAG_MBUTTON
          • EVENT_FLAG_CTRLKEY
          • EVENT_FLAG_SHIFTKEY
          • EVENT_FLAG_ALTKEY
        • userdata - Any pointer passes to the "setMouseCallback" function as the 3rd parameter (see below)
    • userdata - This pointer will be passed to the callback function


OpenCV Example to Detect Mouse Clicks While Pressing a Key


I am going to explain you how to detect a mouse event while pressing a key of the keyboard. 

The following OpenCV example code will detect left mouse clicks while pressing the "CTRL" key , right mouse clicks while pressing the "SHIFT" key and movements of the mouse over the OpenCV window while pressing the "ALT" key.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace std;
using namespace cv;

void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
if ( flags == (EVENT_FLAG_CTRLKEY + EVENT_FLAG_LBUTTON) )
{
cout << "Left mouse button is clicked while pressing CTRL key - position (" << x << ", " << y << ")" << endl;
}
else if ( flags == (EVENT_FLAG_RBUTTON + EVENT_FLAG_SHIFTKEY) )
{
cout << "Right mouse button is clicked while pressing SHIFT key - position (" << x << ", " << y << ")" << endl;
}
else if ( event == EVENT_MOUSEMOVE && flags == EVENT_FLAG_ALTKEY)
{
cout << "Mouse is moved over the window while pressing ALT key - position (" << x << ", " << y << ")" << endl;
}
}

int main(int argc, char** argv)
{
// Read image from file 
Mat img = imread("MyPic.JPG");

//if fail to read the image
if ( img.empty() ) 

cout << "Error loading the image" << endl;
return -1; 
}

//Create a window
namedWindow("My Window", 1);

//set the callback function for any mouse event
setMouseCallback("My Window", CallBackFunc, NULL);

//show the image
imshow("My Window", img);

// Wait until user press some key
waitKey(0);

  return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

You can download this visual C++ OpenCV project from here.

No new OpenCV functions in the above example. If you have some doubt about any OpenCV functions in the above example, please refer to previous lessons.


Next Tutorial : Rotate Image & Video

Previous Tutorial : How to Add Trackbar
   



27 comments:

  1. Exactly what I wanted!! Thanks a lot!!

    ReplyDelete
  2. Thanku so much.it helped me a lot

    ReplyDelete
  3. hello friends
    when I compile the code, I have finaly an error,"error:invalid preprocessing directive #Include

    please help me
    thanks

    ReplyDelete
    Replies
    1. You haven't properly configured your IDE or you are including a wrong header file. Please refer to
      http://opencv-srf.blogspot.com/2013/05/installing-configuring-opencv-with-vs.html
      or
      http://opencv-srf.blogspot.com/2011/09/getting-started-with-opencv_16.html

      Delete
  4. in fact, I use the version 12.11,

    ReplyDelete
  5. Hi, pro.Thanks for your sharing.
    I have an issue that it does not work well when i change the program by changing only mouseEvent() function as following:
    if(evt==CV_EVENT_LBUTTONDOWN && flags==CV_EVENT_FLAG_CTRLKEY){
    printf("%d %d\n",x,y);
    }

    After running, i tried to click left-mouse and press CONTROLKEY simultaneously but nothing happened on the command window as it should be.
    Plz help me to check it out.
    Thanks.

    ReplyDelete
    Replies
    1. Hi,
      As it is stated in OpenCV documentation, the parameter "flags" is a combination of CV_EVENT_FLAG. In Your's case, when You are pressing left mouse button and ctrl key simultaneously flags = CV_EVENT_FLAG_CTRLKEY + CV_EVENT_FLAG_LBUTTON and this gives 9. You can catch this event as flags== CV_EVENT_FLAG_CTRLKEY + CV_EVENT_FLAG_LBUTTON or define Your own event like: #define CV_EVENT_FLAG_CTRLKEY_WITH_LBUTTON 9. Your code should look like this:

      if(evt==CV_EVENT_LBUTTONDOWN && flags==CV_EVENT_FLAG_CTRLKEY_WITH_LBUTTON){
      printf("%d %d\n",x,y);
      }

      Delete
  6. You got a definitely helpful blog I’ve been right here reading for about an hour. I’m a newbie and your accomplishment is quite a lot an inspiration for me.

    ReplyDelete
  7. @Blog writer : First I told you that your blog is really helpfull and i learn a lot from your blog in short time . And I also want to ask you that i want to simulate cursor by my tracking object .(mean when i move my object the cursor is also moving according to object ) can you tell me how the required functions and how to approach this ?

    ReplyDelete
    Replies
    1. First you have to find the location of a object. For this purpose, refer to
      http://opencv-srf.blogspot.com/2010/09/object-detection-using-color-seperation.html
      http://opencv-srf.blogspot.com/2011/09/object-detection-tracking-using-contours.html

      Then you have to move the cursor to the location of the object. But I am not sure what you mean by cursor? Is it the mouse pointer?

      Delete
  8. After some tutorial (I think Track Bars) you started using C API and not C++ API. For example using IplImage* with needs memory deallocates instead of using Mat that does it automatically from CV2 and on. Also using like cvNamedWindow (C) instead of namedWindow (C++).

    Why is that, do you have a reason?

    ReplyDelete
    Replies
    1. This tutorial is written in C initially. Now I am converting this whole tutorial to C++. This post will also be updated surely in the next week.

      Delete
    2. First of all Fernando thank you very much for this tutorial its by far the best I've found. but i was wondering when will you be updating the rest of the tutorials to C++ I got very confused when I got to color detection. one more thing if you have the time and want to, if you could do a small tutorial on how to get video from an ip camera. Once more thank you very much for all this it has been very very helpful

      Delete
  9. You got a definitely helpful blog I’ve been right here reading for about an hour. I’m a newbie and your accomplishment is quite a lot an inspiration for me.

    ReplyDelete
  10. can you suggest me function or macros that can control moment of cursor i.e. I want to control cursor position with my application not by mouse?Your help would be appreciated
    Thank you
    -Jay Kothari

    ReplyDelete
  11. Hi,
    it's a good blog, It worked!. I have small query, can you help me please, I want to store the point coordinates which i clicked. How can I do this, for this coordinate i have crop that image.

    ReplyDelete
  12. This blog is just awesome... Keep up the good work man.....

    ReplyDelete
  13. How do i save the x y coordinate in a csv file...?

    ReplyDelete
  14. Is it possible to have the coordinates with double precision?

    thanks!

    ReplyDelete
  15. Good post....thanks for sharing.. very useful for me i will bookmark this for my future needs. Thanks.

    bigrock coupon code

    ReplyDelete
  16. I'm learning OpenCV from your blog. Thanks a lot for sharing your knowledge with us.
    Would you please upload one more examples of Detecting Face and the Co-ordinate of the detected face?

    ReplyDelete
  17. Very interesting topic, can you post some further information on this subject.
    EMV pos

    ReplyDelete
  18. Nice service there are just few who are providing this service great job.
    Gorilla Case

    ReplyDelete
  19. This is great article and so helpful and i really appreciate your all work.well done.
    Samsung accessories

    ReplyDelete
  20. the second example should be changed, because waitKey(0) is qutting, when I press a Key. Would be better to specify a exit-key.

    ReplyDelete