OpenCV中鼠标事件的响应是采用回调函数的方式来处理。即为了响应鼠标点击事件,必须首先创建一个鼠标回调函数,使鼠标点击事件发生时OpenCV可以调用该函数。创建这个函数后,需要在OpenCV中注册这个函数,以便将特定的窗口与鼠标回调函数绑定。
鼠标回调函数的形式:
void cvMouseCallback(int mouseEvent,int x,int y,int flags,void* param);
其中 int mouseEvent 是鼠标事件类型,是用宏定义的一些int型:
CV_EVENT_MOUSEMOVE =0,表示鼠标移动事件
CV_EVENT_LBUTTONDOWN =1,表示左键双击
CV_EVENT_RBUTTONDOWN =2,
CV_EVENT_MBUTTONDOWN =3,
CV_EVENT_LBUTTONUP =4,
CV_EVENT_RBUTTONUP =5,
CV_EVENT_MBUTTONUP =6,
CV_EVENT_LBUTTONDBLCLK =7,
CV_EVENT_RBUTTONDBLCLK =8,
CV_EVENT_MBUTTONDBLCLK =9
x,y表示鼠标事件发生时鼠标的坐标位置;
int flags,每一位指定了附加状态:
CV_EVENT_FLAG_LBUTTON =1,
CV_EVENT_FLAG_RBUTTON =2,
CV_EVENT_FLAG_MBUTTON =4,
CV_EVENT_FLAG_CTRLKEY =8,
CV_EVENT_FLAG_SHIFTKEY =16,
CV_EVENT_FLAG_ALTKEY =32
鼠标回调函数的注册:
void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param=NULL );
其中:
const char* window_name 表示所要绑定窗口名
CvMouseCallback on_mouse 表示鼠标回调函数,此参数传入回调函数的地址(函数名相当于函数地址),不要带小括号(表示函数调用)
void* param=NULL 用户定义传入鼠标指定消息处理函数的参数
const char* window_name 表示所要绑定窗口名
CvMouseCallback on_mouse 表示鼠标回调函数,此参数传入回调函数的地址(函数名相当于函数地址),不要带小括号(表示函数调用)
void* param=NULL 用户定义传入鼠标指定消息处理函数的参数
#include
#include
#include
using namespace std;
CvRect box; //定义2个全局变量
bool drawing_box=false;
void my_mouse_callback(int event,int x,int y,int flag,void *param);//鼠标回调函数申明
void draw_box(IplImage *img,CvRect box); //画矩形声明
int main()
{ box=cvRect(-1,-1,0,0);
const char *windowName="Box test";
IplImage *image=cvCreateImage(cvSize(400,400),IPL_DEPTH_8U,3);
cvZero(image);
IplImage *tempImg=cvCloneImage(image);
cvNamedWindow(windowName,0);
cvMoveWindow(windowName,100,100);
cvSetMouseCallback(windowName,my_mouse_callback,(void*)image); //注册鼠标回调函数
while(1)
{
cvCopyImage(image,tempImg);
if (drawing_box)
{
draw_box(tempImg,box);
}
cvShowImage(windowName,tempImg);
if (27==cvWaitKey(200)) //按下Esc程序退出
{
break;
}
}
cvReleaseImage(&image);
cvReleaseImage(&tempImg);
cvDestroyWindow(windowName);
}
void my_mouse_callback(int event,int x,int y,int flag,void *param)
{
IplImage *image=(IplImage*)param;
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
{
drawing_box=true; //左键按下时drawing_box=ture,可以画图
box=cvRect(x,y,0,0); //同时给出box的左上角x,y 宽高为0
}
break;
case CV_EVENT_MOUSEMOVE:
{
if (drawing_box)
{
box.width=x-box.x; //移动时给出width,height
box.height=y-box.y;
}
}
break;
case CV_EVENT_LBUTTONUP:
{
drawing_box=false; //左键松开时drawing_box=false
if (box.width<=0) //如何向左上角拖动鼠标,重新给box的x,y,width,height赋值
{
box.x+=box.width;
box.width*=-1;
}
if (box.height<=0)
{
box.y+=box.height;
box.height*=-1;
}
draw_box(image,box); //松开时画矩形
}
break;
}
}
void draw_box(IplImage *img,CvRect box) //在一个mat上画矩形
{
cvRectangle(img,cvPoint(box.x,box.y),cvPoint(box.x+box.width,box.y+box.height),cvScalar(200));
}