鼠标事件
与键盘事件响应不同,鼠标事件响应采用回调函数的方式来处理,即为了响应鼠标点击事件,首先必须创建一个回调函数,使得鼠标在发生点击事件时,OpenCV可以调用这个函数。创建这个函数之后,需要在OpenCV中注册这个函数,以便特定窗口被触发鼠标事件后,OpenCV可以正确的调用这个函数。
回调函数必须符合的形式:
void Foo(int event, int x, int y, int flags, void* param);其中,event是鼠标事件,鼠标事件主要包括:
// 鼠标事件类型
#define CV_EVENT_MOUSEMOVE 0 #define CV_EVENT_LBUTTONDOWN 1 #define CV_EVENT_RBUTTONDOWN 2 #define CV_EVENT_MBUTTONDOWN 3 #define CV_EVENT_LBUTTONUP 4 放开鼠标左键 #define CV_EVENT_RBUTTONUP 5 #define CV_EVENT_MBUTTONUP 6 #define CV_EVENT_LBUTTONDBLCLK 7 #define CV_EVENT_RBUTTONDBLCLK 8 #define CV_EVENT_MBUTTONDBLCLK 9
// 鼠标事件标志
#define CV_EVENT_FLAG_LBUTTON 1 #define CV_EVENT_FLAG_RBUTTON 2 #define CV_EVENT_FLAG_MBUTTON 4 #define CV_EVENT_FLAG_CTRLKEY 8 #define CV_EVENT_FLAG_SHIFTKEY 16 #define CV_EVENT_FLAG_ALTKEY 32
x,y是鼠标事件发生是鼠标位置的坐标,这些坐标是窗口中图像的像素坐标,与窗口的大小没有关系。flags指定事件发生是的不同状态,void以任何结构方式传递额外信息
接下来需要注册回调函数到OpenCV中,实现注册的函数是:
void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param=NULL );
-
window_name
- 窗口的名字。 on_mouse
- 指定窗口里每次鼠标事件发生的时候,被调用的函数指针。这个函数的原型应该为
void Foo(int event, int x, int y, int flags, void* param);
其中event是 CV_EVENT_*变量之一, x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系), flags是CV_EVENT_FLAG的组合(即上面的一些有关现在动作状态的预定义,现在鼠标没任何操作时为0), param是用户定义的传递到cvSetMouseCallback函数调用的参数。
-
param
- 用户定义的传递到回调函数的参数。
函数cvSetMouseCallback设定指定窗口鼠标事件发生时的回调函数。
实现:在窗口中画正方形
代码:
/*
在窗口中画正方形
*/
#include "cv.h"
#include "highgui.h"
void my_mouse_callback( int event, int x, int y, int flags, void* param);
CvRect box;
bool drawing_box = false;
// 画矩形
void draw_box(IplImage* img, CvRect rect)
{
cvRectangle(
img,
cvPoint(box.x, box.y),
cvPoint(box.x + box.width, box.y + box.height),
cvScalar(0x00, 0xff, 0x00)
);
}
// 函数实现:在窗口中画出矩形
void doMouseDemo()
{
box = cvRect(-1,-1,0,0);
IplImage* image = cvCreateImage(
cvSize(500,500),
IPL_DEPTH_8U,
3
);
cvZero(image);
IplImage* temp = cvCloneImage(image);
cvNamedWindow("box");
cvSetMouseCallback(
"box",
my_mouse_callback,
(void*) image
);
while(1)
{
cvCopyImage(image,temp);
if( drawing_box )
{
draw_box(temp, box);
}
cvShowImage("box", temp);
if(cvWaitKey(15) == 27)
{
break;
}
}
cvReleaseImage(&image);
cvReleaseImage(&temp);
cvDestroyWindow("box");
}
//回调函数
void my_mouse_callback( int event, int x, int y, int flags, void* param)
{
IplImage* image = (IplImage*) param;
switch( event )
{
case CV_EVENT_MOUSEMOVE:
{
if(drawing_box)
{
box.width = x - box.x;
box.height = y - box.y;
}
}
break;
case CV_EVENT_LBUTTONDOWN:
{
drawing_box = true;
box = cvRect(x,y,0,0);
}
break;
case CV_EVENT_LBUTTONUP:
{
drawing_box = false;
if(box.width < 0)
{
box.x += box.width;
box.width *= -1;
}
if(box.height < 0)
{
box.y += box.height;
box.height *= -1;
}
draw_box(image, box);
}
break;
}
}
实现结果:鼠标左键点击,拖动,即可画出矩形