opencv鼠标操作cvSetMouseCallback和文本显示cvPutText的总结

来源:互联网 发布:如何理解数组的概念 编辑:程序博客网 时间:2024/05/16 13:44

opencv鼠标操作cvSetMouseCallback和文本显示cvPutText的总结

1) cvSetMouseCallback
void   cvSetMouseCallback( const  char*   window_name, CvMouseCallback  on_mouse, void*   param=NULL );
window_name 窗口的名字。
on_mouse 指定窗口里每次鼠标事件发生的时候,被调用的函数指针。就是回调函数。
param 用户定义的传递到回调函数的参数,也就是传递额外的信息给回调函数的void  *param参数。


2)CvMouseCallback
这个回调函数的原型应该为 void CvMouseCallback(int event, int x, int y, int flags, void* param);
其中:
1、event:是 CV_EVENT_* 变量之一,表示事件,回调过程中发生的是鼠标按下或放开、移动等操作。
2、x,y:表示鼠标此刻的在窗口中的位置信息,不是窗口坐标系,而是图像坐标系。
3、flags:是CV_EVENT_FLAG的组合,表示拖拽、组合键等标志,与event搭配使用
4、param:表示传入或传出的数据,每一位指定了在事件发生时的不同状态。

只要将操作方法定义成CvMouseCallback即可实现任何形式的鼠标操作


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_LBUTTONDBLCLK

7

左键双击

CV_EVENT_RBUTTONDBLCLK

8

右键双击

CV_EVENT_MBUTTONDBLCLK

9

中键双击

 

Flags的可选项及含义

功能

CV_EVENT_FLAG_LBUTTON

1

 左键拖曳

CV_EVENT_FLAG_RBUTTON

2

右键拖曳

CV_EVENT_FLAG_MBUTTON 

4

中键拖曳

CV_EVENT_FLAG_CTRLKEY 

8~15

Ctrl不放事件

CV_EVENT_FLAG_SHIFTKEY

16~31

Shift不放事件

CV_EVENT_FLAG_ALTKEY

32~39

Alt不放事件

 

然后使用cvSetMouseCallback()进入鼠标操作的入口方法进行回调,但需要传入一个handler,也就是事件驱动的子程序名称,Handler必须是CvMouseCallback函数指针类型.

cvSetMouseCallback("窗口名称",自行定义子程序名称,自行定义子程序的传入传出参数);



3)cvRectangle  通过对角线上的两个顶点绘制简单、指定粗细或者带填充的矩形

函数原型:void  cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,int thickness=1, int line_type=8, int shift=0 );

参数介绍:

img -- 图像.

pt1 -- 矩形的一个顶点。

pt2 -- 矩形对角线上的另一个顶点

color -- 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。

thickness -- 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。

line_type -- 线条的类型。见cvLine的描述

shift -- 坐标点的小数点位数。


4)cvPutText 绘制文字字符串

void cvPutText(CvArr*   img, const  char*  text, CvPoint  origin, const  CvFont*  font, CvScalar  color);

函数中各个参数的含义如下所示:

img---图片指针(需要说明的是,CvArr* 等价于void*,一般我们在这里传递一个IplImage*)

text---显然是需要打印到图片上的字符串的内容;

origin---字符串在图片上打印的原点(即,字符串的左下角在图片中的位置)

font---描述字体属性的变量;

color---字体的颜色;

上面函数中出现了一个较为生僻的变量CvFont*,从名称不难发现,该类型用于进行字符属性的描述;

需要刻意提醒的是,CvFont类型的指针并不能像CvMatIplImage类型的指针那样,存在一个cvCreate**之类的

函数对其进行初始化。CvFont类型变量的初始化是通过函数cvInitFont来实现的;该函数的申明如下所示:

void cvInitFont(CvFont*  font, int  font_face,  double  h_scale, double  v_scale, double  shear=0, int                thickness=1, int line_type=8);

该函数中各个变量的含义如下所示:

font---传入及传出的字体属性类型指针;

font_face---表示字体的类型,其取值只能为以下数值之一:

1. CV_FONT_HERSHEY_SIMPLEX

2. CV_FONT_HERSHEY_PLAIN

3. CV_FONT_HERSHEY_DUPLEX

4. CV_FONT_HERSHEY_COMPLEX

5. CV_FONT_HERSHEY_TRIPLEX

6. CV_FONT_HERSHEY_COMPLEX_SMALL

7. CV_FONT_HERSHEY_SCRIPT_SIMPLEX

8. CV_FONT_HERSHEY_SCRIPT_COMPLEX


h_scale---只能为10.5,表示水平方向字体的缩放系数;

v_scale---只能为10.5,表示垂直方向字体的缩放系数;

shear---取值从0---1,表示字体的倾斜程度,0表示不倾斜,1表示倾斜45度;

thichness, line_type这两个参数同OpenCV的其它绘图函数中定义的一样,表示线型的宽度和线条的类型;



5)下面我们实现一个简单的程序,使得用户可以通过鼠标来画方形图。函数my_mouse_callback()用来响应鼠标事件,并且根据event来确定给出的响应。

程序代码:

#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;
using namespace cv;
void my_mouse_callback(int event,int x,int y,int flags,void* param);
CvRect box;
CvFont font;
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(0xff,0x00,0x00));
}
int main()
{
box=cvRect(-1,-1,0,0);//初始设定
IplImage* image=cvCreateImage(cvSize(400,400),IPL_DEPTH_8U,3);
cvZero(image);
IplImage* temp=cvCloneImage(image);
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0,1,8);
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);
cvSaveImage("result.jpg",temp);
if(cvWaitKey(15)==27) break;//27是Esc键
}
cvReleaseImage(&image);
cvReleaseImage(&temp);
cvDestroyWindow("Box Example");
}
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)//如果可画,立即计算矩形区域
{ //矩形区域=实际坐标位置-初始位置
//x,y为鼠标位置的坐标值
box.width=x-box.x;
box.height=y-box.y;
}
}
break;
case CV_EVENT_LBUTTONDOWN://左键点击  
{
drawing_box=true;//置1,为可画
box=cvRect(x,y,0,0);//设定矩形区域的起点坐标,为x,y坐标
}
break;
case CV_EVENT_LBUTTONUP://左键放开
{
drawing_box=false;//置0,不可画
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);//开始画矩形
//在画矩形框的起始点cvPoint(box.x,box.y)位置,显示文本框
cvPutText(image,"drawing",cvPoint(box.x,box.y),&font,CV_RGB(255,0,0));
}
break;
case CV_EVENT_RBUTTONDOWN://鼠标右键点击
{
cvZero(image);//清0
}
break;
}
}

效果:





0 0
原创粉丝点击