OpenCV学习笔记之鼠标响应回调函数setMouseCallback

        openCv中的鼠标回调函数是为了处理鼠标操作消息的响应事件,函数原型为:

                     C++:   void   SetMouseCallback(const string & winname,MouseCallback onMouse,void* userdata=0)

第一个参数:const string & 类型的winname ,窗口的名字;

第二个参数: MouseCallback 类型的onMouse,指定窗口里每次鼠标事件发生时的时候被调用的函数指针。

这个函数的原型的大概形势为:void Foo(int event ,int x ,int y ,int flags  ,void  * param)。event 是鼠标响应类型,CV_EVENT_*变量之一:

EVENT_MOUSEMOVE 滑动 EVENT_LBUTTONDOWN 左击 EVENT_RBUTTONDOWN 右击

EVENT_MBUTTONDOWN 中键点击 EVENT_LBUTTONUP 左键放开 EVENT_RBUTTONUP 右键放开

EVENT_LBUTTONDBLCLK 左键双击 EVENT_RBUTTONDBLCLK 右键双击 EVENT_MBUTTONDBLCLK 中键双击

x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系)。

                                              flags是CV_EVENT_FLAG的组合,flag的状态有:

EVENT_FLAG_LBUTTON 左键拖拽 EVENT_FLAG_RBUTTON 右键拖拽 EVENT_FLAG_MBUTTON 中键拖拽 EVENT_FLAG_CTRLKEY 按住Ctrl不放 EVENT_FLAG_SHIFTKEY 按住Shift不放 EVENT_FLAG_ALTKEY 按住Alt不放 param是用户定义的传递到setMouseCallback函数调用的参数。

第三个参数:void *userdata   传给回调函数的参数(onMouse)。

示例代码如下:

//--------------------------------【鼠标响应函数声明部分】----------------
//             描述:
//------------------------------------------------------------------------
void onMouseHandle(int event,int x,int y,int flags,void *param);
void onMouseHandle1(int event,int x,int y);
void DrawRectangle(Mat &img,Rect box);

Rect g_rectangle;
bool g_bDrawingBox=false;	//是否进行绘制
RNG g_rng(12345);

void Main2()
{
	g_rectangle=Rect(-1,-1,0,0);
	Mat srcImage(600,800,CV_8UC3),tempImage;
	srcImage.copyTo(tempImage);
	srcImage=Scalar::all(0);

	//设置鼠标操作回调函数
	namedWindow(windowName);
	setMouseCallback(windowName,onMouseHandle,(void*)&srcImage);
	

	//程序主循环
	while (1)
	{
		srcImage.copyTo(tempImage);
		if(g_bDrawingBox) 
			DrawRectangle(tempImage,g_rectangle);
		imshow(windowName,tempImage);
		if(waitKey(10)==27)
			break;
	}


}
//鼠标回调函数
void onMouseHandle(int event,int x,int y,int flags,void *param)
{

	Mat &image=*(Mat *) param;
	switch(event)
	{
		//鼠标移动消息
	case EVENT_MOUSEMOVE:
		{
			if(g_bDrawingBox)	//是否进行绘制
			{
				g_rectangle.width=x-g_rectangle.x;
				g_rectangle.height=x-g_rectangle.y;
			}
		}
		break;
	case EVENT_LBUTTONDOWN:
		g_bDrawingBox=true;
		g_rectangle=Rect(x,y,0,0);	//记录起始点
		break;
	//左键抬起消息
	case EVENT_LBUTTONUP:
		g_bDrawingBox=false;
		if(g_rectangle.width<0)
		{
			g_rectangle.x+=g_rectangle.width;
			g_rectangle.width*=-1;
		}
		if(g_rectangle.height<0)
		{
			g_rectangle.y+=g_rectangle.height;
			g_rectangle.height*=-1;

		}
		//调用函数进行绘制
		DrawRectangle(image,g_rectangle);
		break;
	}
	
}
//矩形绘制函数
void DrawRectangle(Mat &img,Rect box)
{
	rectangle(img,box.tl(),box.br(),Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)));//随机颜色
}
效果图:



二、滑动条的创建

        创建滑动条的函数是createTrackbar,函数原型如下:

C++ :int    createTrackbar(const string & trackbarname,   const string & winname  ,int * value  ,int  count   ,TrackbarCallback onChange=0  ,  void * userdata =0 );

        第一个参数:const string & 类型的trackbarname  。滑动条名称。

        第二个参数:const string & 类型的 winname ,窗口的名称。

        第三个参数:int * 类型的value 。整型的指针,表示滑块创建时初始位置。

        第四个参数:int 类型的count ,表示滑块可达到的最大位置。

        第五个参数:TrackbarCallback 类型的onChange。回调函数,滑块移动时会调用onChange函数。

        第六个参数:void *类型的userdata参数。这个参数是用户用来传递给回调函数的参数。

利用滑块调整图像透明度的函数代码:

//创建滑动条
const char windowName[]="【线性混合示例】";

//---------------------【全局变量】-----------------------

const int g_nMAxAlphaValue=100;
int g_nAlphaValueSlider;	//滑动条对应的变量
double g_dAlphaValue;
double g_dBetaValue;

//声明存储图像的变量
cv::Mat g_srcImage1;
cv::Mat g_srcImage2;
cv::Mat g_srcImage;

//--------------------------【onTrackBar()函数】----------------------
//          描述:响应滑动条的回调函数
//
//--------------------------------------------------------------------
void onTrackBar(int ,void *)
{
	//求当前alpha值相对于最大值得比例
	g_dAlphaValue=(double)g_nAlphaValueSlider/(double)g_nMAxAlphaValue;
	//则beta值为1减去alpha值
	g_dBetaValue=1-g_dAlphaValue;

	//根据alpha和beta值进行线性混合
	addWeighted(g_srcImage1,g_dAlphaValue,g_srcImage2,g_dBetaValue,0.0,g_srcImage);

	//显示效果图
	imshow(windowName,g_srcImage);


}
void Main1()
{
	//加载图像(两图像尺寸需相同)
	g_srcImage1=imread("1-s.jpg");
	g_srcImage2=imread("1-s.jpg");
	if(!g_srcImage1.data)
	{
		printf("读取第一幅图片错误!!!");
		return ;
	}
	if(!g_srcImage2.data)
	{
		printf("读取第二幅图片错误!!!");
		return ;
	}

	//设置滑动条初始位置为70
	g_nAlphaValueSlider=70;

	//创建窗体
	namedWindow(windowName,1);
	
	//在创建的窗体中创建一个滑动条控件
	char TrackbarName[50];
	sprintf(TrackbarName,"透明值 %d",g_nMAxAlphaValue);

	createTrackbar(TrackbarName,windowName,&g_nAlphaValueSlider,g_nMAxAlphaValue,onTrackBar);

	//结果在回调函数中显示
	onTrackBar(g_nAlphaValueSlider,0);

	waitKey(0);
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值