如何在图像上用鼠标绘画矩形并且能够显示出来
2013-12-11 19:12
316 查看
前面的话:依旧在学习OpenCV的道路慢慢摸索,道长且阻,但我心依旧。。。
今天学习了Highhui中提供的鼠标事件,且以实例来向大家展示如何使用鼠标事件
重点知识:
鼠标事件响应采用回调函数的方式来处理,即,为了可以响应鼠标的各种事件,首先必须创建一个回调函数,是鼠标事件发生时OpenCV可以调用这个函数。创建这个函数后,需要在OpenCV中注册这个函数,以便特定窗口被触发鼠标事件以后,OpenCV可以正确调用这个函数。
回调函数
callback可以是满足指定输入参数以及返回参数类型的任何函数。
下面是回调函数必须符合的格式:
void CvMouseCallback(
int event,
int x,
int y,
int flags,
void *param);
第一个参数event必须为以下值中的一个:
事件名称 数值 鼠标操作
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_LBUTTONBLCLK 7
CV_EVENT_RBUTTONBLCLK 8
CV_EVENT_MBUTTONBLCLK 9
第二个以及第三个参数会被设置成事件发生时鼠标位置的x,y坐标值。值得指出的是,这些坐标代表窗口中图像的像素坐标,与窗口大小无关。
第四个参数flags,每一位指定了在事件发生时的不同状态。例如,CV_EVENT_FLAG_SHIFTKEY的值为16(flags的第五位为1)。
鼠标事件标志 数值
CV_EVENT_FLAG_LBUTTON 1
CV_EVENT_FLAG_RBUTTON 2
CV_EVENT_FLAG_MBUTTON 4
CV_EVENT_FLAG_CTRLKEY 8
CV_EVENT_FLAG_SHIFTKEY16
CV_EVENT_FLAG_ALTKEY32
最后一个参数是一个void* 指针,可以用来以任何结构方式传递额外的参数信息。
下面需要注册回调函数到OpenCV中,实现注册的函数式cvSetMouseCallback(),
void cvSetMouseCallback(
const char * window_name,
CvMouseCallback on_mouse,
void * param=NULL
);
第一个参数指定了回调函数需要注册的窗口,也就是产生事件的窗口。只有在这个指定的窗口中触发的事件才会调用函数。第二个参数为回调函数。最后,第三个参数用来传递额外的信息给前面提到的void * param参数。
实例:如何在在图像上用鼠标绘画矩形并且能够显示出来
运行程序结果如下:
源代码:
#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(0,0,0xff),1,8,0); }//根据Rect类型中的值在图像img绘制一个矩形 int main() { box=cvRect(-1,-1,0,0);//初始化初值 IplImage * image=cvCreateImage(cvSize(1000,700),IPL_DEPTH_8U,3);//创建一个宽1000、高700的像素类型为无符号8位整数3通道图像 cvZero(image);//设置图像所有像素点全为黑 IplImage *temp=cvCloneImage(image);//用图像image克隆出另一个图像temp cvNamedWindow("Box Example");//创建窗口 cvSetMouseCallback("Box Example",my_mouse_callback,(void *)image);//注册函数 while(1) { cvCopyImage(image,temp); if(drawing_box) draw_box(temp,box); cvShowImage("Box Example",temp); if(cvWaitKey(10)==27)break; }//不停地把图像image Copy到图像temp中,然后在temp中根据drawing_box的值不停地画矩形并显示出来,使得在鼠标左键未松开时,画出的矩形能随着鼠标的移动动态的改变,每次停留的时间为10毫秒 cvReleaseImage(&image); cvReleaseImage(&temp); cvDestroyWindow("Box Example"); return 0; } 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; } }//在鼠标在按住左键移动的时候能设置box的width和height。 break; case CV_EVENT_LBUTTONDOWN: { drawing_box=true; box=cvRect(x,y,0,0); }//左键按住的时候设置能画矩形并且能设置矩形开始坐标 break; case CV_EVENT_LBUTTONUP://左键松开 { drawing_bo 4000 x=false;//设置为false if(box.width<0&&box.height<0) { box.x+=box.width; box.y+=box.height; box.height*=-1; box.width*=-1; }//如果矩形对角点的x,y都小于开始点的,则设置对角点为矩形的左上点,再修改宽高都为正值。 else if(box.height<0) { box.y +=box.height; box.height*=-1; }//如果矩形对角点的y小于开始点的,则将开始点的上边的点设置为左上点,修改高为正值。 else if(box.width<0) { box.x+=box.width; box.width*=-1; }//如果矩形对角点的x小于开始点的,则将开始点的左边的点设置为左上点,修改宽为正值。 draw_box(image,box);//在松开左键的时候画矩形 } break; } }//回调函数
相关文章推荐
- 读取图片,并通过鼠标交互,在图片上选择一块矩形区域,然后把这个矩形区域的子图像显示出来
- 4:在图像上通过鼠标交互,画三条线段并显示出来。
- 在C#中 从一个picturebox中 按住鼠标左键不放 画一块区域后,另外一个picturebox(在一个winform 窗体上有两个picturebox )上马上把对应的截取图像显示出来
- 最近被一个问题困扰着,如何实现类似Photoshop的多层图像操作,每层可单独操作,又可以组合显示出来。
- OpenCV中如何载入图像并且转换成灰度显示图像直方图
- 转:zTree树控件key配置之title:zTree树节点名称过长如何省略显示且鼠标移入节点上能够显示全称
- OpenCV中如何载入图像并且转换成灰度显示图像直方图
- jQuery如何让鼠标经过菜单时显示子菜单并且鼠标经过子菜单时子菜单也显示
- zTree树控件key配置之title:zTree树节点名称过长如何省略显示且鼠标移入节点上能够显示全称
- jQuery如何让鼠标经过菜单时显示子菜单并且鼠标经过子菜单时子菜单也显示
- matlab subplot(figure)如何设置使得图像最终显示出来不一样大小
- opencv提取图像的缺陷并用最小矩形框出来
- 用opencv读取图像,并且显示
- 利用OpenCV鼠标事件设置函数setMouseCallback显示图像像素坐标值!
- C#开发微信 二维码鼠标滑动 图像显示隐藏效果(推荐)
- jsp/js中如何添加调试信息以及如何显示出来
- 电脑的任务栏要把鼠标放上去才显示出来
- 如何摁下鼠标左键,图标(窗体,或者控件)能够随着鼠标移动
- 快速启动拦的“显示桌面”没有了,如何恢复出来!
- SSRS Report新加字段如何在Visual Studio 显示出来