OpenCV鼠标事件详解(附带实例)
在 OpenCV 中存在鼠标的操作,比如单击、双击等。对于 OpenCV 来讲,用户的鼠标操作被认为发生了一个鼠标事件,需要对这个鼠标事件进行处理,这就是事件的响应。
鼠标事件包括左键按下、左键松开、左键双击、鼠标移动等。当鼠标事件发生时,OpenCV 会让一个鼠标响应函数自动被调用,相当于一个回调函数,这个回调函数就是鼠标事件处理函数。
OpenCV 提供了 setMousecallback() 来预先设置回调函数,相当于告诉系统鼠标处理的回调函数已经设置好了,有鼠标事件发生时,系统调用这个回调函数即可。注意是系统调用,而不是开发者调用,因此称为回调函数。
函数 setMousecallback() 声明如下:
鼠标事件回调函数类型 MouseCallback 定义如下:
鼠标事件 event 主要有以下几种:
鼠标事件标志 flags 主要有以下几种:
【实例】在图片上用鼠标画线。
1) 打开 Qt Creator,新建一个控制台工程,工程名是 test。
2) 在 IDE 中打开 main.cpp,输入如下代码:
本例我们关心的是按下鼠标左键,然后按住左键时的鼠标移动。一旦按下鼠标左键,就记录下当时的位置(也就是画线的开始点),位置记录在 previousPoint 中。接着如果继续有鼠标移动事件发生,我们就开始调用函数 line 画线。最后把画了线的图像数据 g_srcImage 用函数 imshow 显示出来。
3) 保存工程并运行,结果如下图所示:
鼠标事件包括左键按下、左键松开、左键双击、鼠标移动等。当鼠标事件发生时,OpenCV 会让一个鼠标响应函数自动被调用,相当于一个回调函数,这个回调函数就是鼠标事件处理函数。
OpenCV 提供了 setMousecallback() 来预先设置回调函数,相当于告诉系统鼠标处理的回调函数已经设置好了,有鼠标事件发生时,系统调用这个回调函数即可。注意是系统调用,而不是开发者调用,因此称为回调函数。
函数 setMousecallback() 声明如下:
void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0);其中参数 winname 表示窗口的名字,onMouse 是鼠标事件响应的回调函数指针,userdate 是传给回调函数的参数。这个函数名也比较形象,一看就知道是用来设置鼠标回调函数的(set Mouse call back)。
鼠标事件回调函数类型 MouseCallback 定义如下:
typedef void(* cv::MouseCallback)(int event, int x, int y, int flags, void *useradata);其中参数 event 表示鼠标事件,x 表示鼠标事件的 x 坐标,y 表示鼠标事件的 y 坐标,flags 表示鼠标事件的标志,userdata 是可选的参数。
鼠标事件 event 主要有以下几种:
enum { EVENT_MOUSEMOVE =0, // 滑动 EVENT_LBUTTONDOWN =1, // 左键单击 EVENT_RBUTTONDOWN =2, // 右键单击 EVENT_MBUTTONDOWN =3, // 中键单击 EVENT_LBUTTONUP =4, // 左键放开 EVENT_RBUTTONUP =5, // 右键放开 EVENT_MBUTTONUP =6, // 中键放开 EVENT_LBUTTONDBLCLK =7, // 左键双击 EVENT_RBUTTONDBLCLK =8, // 右键双击 EVENT_MBUTTONDBLCLK =9 // 中键双击 };
鼠标事件标志 flags 主要有以下几种:
enum { EVENT_FLAG_LBUTTON = 1, // 左键拖曳 EVENT_FLAG_RBUTTON = 2, // 右键拖曳 EVENT_FLAG_MBUTTON = 4, // 中键拖曳 EVENT_FLAG_CTRLKEY = 8, // 按Ctrl EVENT_FLAG_SHIFTKEY = 16, // 按Shift EVENT_FLAG_ALTKEY = 32 // 按Alt };通过 event 和 flags 就能清楚地了解当前鼠标发生了哪种操作。
【实例】在图片上用鼠标画线。
1) 打开 Qt Creator,新建一个控制台工程,工程名是 test。
2) 在 IDE 中打开 main.cpp,输入如下代码:
#include <opencv2/opencv.hpp> using namespace cv; #include<iostream> using namespace std; #define WINDOW "原图" Mat g_srcImage, g_dstImage; Point previousPoint; bool P = false; void on_mouse(int event, int x, int y, int flags, void*); int main() { g_srcImage = imread("ter.jpg", 1); imshow(WINDOW, g_srcImage); setMouseCallback(WINDOW, On_mouse, 0); waitKey(0); return 0; } void on_mouse(int event, int x, int y, int flags, void*) { if (event == EVENT_LBUTTONDOWN) { previousPoint = Point(x, y); } else if (event == EVENT_MOUSEMOVE && (flags&EVENT_FLAG_LBUTTON)) { Point pt(x, y); line(g_srcImage, previousPoint, pt, Scalar(0, 255), 2, 5, 0); previousPoint = pt; imshow(WINDOW, g_srcImage); } }在上述代码中,on_mouse 就是用来处理鼠标事件的回调函数,当鼠标有动作产生时,on_mouse 会被系统调用,然后在 on_mouse 中判断发生了哪种动作,进而进行相应的处理。
本例我们关心的是按下鼠标左键,然后按住左键时的鼠标移动。一旦按下鼠标左键,就记录下当时的位置(也就是画线的开始点),位置记录在 previousPoint 中。接着如果继续有鼠标移动事件发生,我们就开始调用函数 line 画线。最后把画了线的图像数据 g_srcImage 用函数 imshow 显示出来。
3) 保存工程并运行,结果如下图所示:
