【Opencv】Opencv鼠标事件的使用

鼠标的使用

鼠标函数的定义


void cv::setMouseCallback	(	
	const String & 	winname,
	MouseCallback 	onMouse,
	void * 	userdata = 0 )

这个函数定义包含了三个参数,分别是把鼠标函数放置在哪个窗口,鼠标事件发生的时候调用哪个回调函数,以及向回调函数中传递什么数值。

回调函数的定义

回调函数必须满足下面的结构

void MouseCallback(
	int event,
	int x,
	int y,
	int flag,
	void *userdata
	)

第一个参数event,是一个int类型的变量,用来接收具体接收到了哪一种类型的鼠标事件,这里简略举几个例子

变量名 意义
EVENT_MOUSEMOVE 鼠标移动
EVENT_LBUTTONDOWN 鼠标左键按下
EVENT_RBUTTONDOWN 鼠标右键按下
EVENT_LBUTTONUP 鼠标左键松开
EVENT_RBUTTONUP 鼠标右键松开

第二个和第三个参数用来接收鼠标的坐标位置,这个位置是图片的作伴,不是窗口的坐标
第四个参数flag,意义与event参数比较相似,具有指示鼠标按下事件完成、shift键按下等检查功能。

具体例子

这个例子是参考《Opencv3编程入门》写下来的(p79页)

下面这个程序的运行思路为,当鼠标左键按下的时候开始绘图,鼠标左键松开的时候结束绘图,鼠标移动的偏移量作为图片的长和宽。srcImage图片作为底片,上面绘制的矩形边长是鼠标按下到松开的偏移量。而tempImage图片是一个中间量,绘制的是从鼠标左键按下到鼠标左键松开这个过程的所有矩形。不过按书中的程序,对srcImage图片绘制边长为负值的时候做了校正,但是这个步骤却没有对tempImage做。

但是我发现并不需要对rect矩形的坐标进行重新变换,width和height都是负值的时候,仍然可以正常的绘图。

#include<opencv2/opencv.hpp>
using namespace cv;

//程序说明:实现功能为鼠标按下后可以拖动进行绘制矩形框

bool g_value = false;//全局变量,用来判断什么时候开始画矩形框
Rect g_rect(-1,-1,0,0);//用来绘图的矩阵


void DrawRectangle(Mat& m, Rect r) //用来绘制矩形的函数
{
	Scalar s(255, 0, 255);//相当于定义三通道的颜色,三通道分别是255,0,255
	rectangle(m, g_rect, s);//用定义的颜色s,在图像m中绘制矩形g_rect
}
void MouseCallBack(int event,int x,int y,int flags,void* param)//回调函数
{
	Mat m = *(Mat*)param;
	switch (event)
	{
	case(EVENT_MOUSEMOVE):
		if (g_value)//如果鼠标左键按下,g_value变为真,运行进行绘图,绘图矩阵记录鼠标移动的距离,作为宽和高
		{
			g_rect.width = x - g_rect.x;
			g_rect.height = y - g_rect.y;
		}
		break;

	case(EVENT_LBUTTONDOWN):  //鼠标左键按下的时候,给矩阵重新定义初始位置
		g_value = true;
		g_rect = Rect(x, y, 0, 0);
		break;
	case(EVENT_LBUTTONUP): //鼠标左键放开的时候,把矩形画入srcImage。
		g_value = false;
		DrawRectangle(m, g_rect);
		
		
		break;

	}
}

int main()
{

	Mat srcImage, tempImage;  //两个用来存放图片的变量,在绘图中srcImage绘制最后的图片,tempImage绘制绘制中间过程的图片
	srcImage = imread("1.jpg");
	srcImage.copyTo(tempImage);
	namedWindow("a", WINDOW_AUTOSIZE);
	setMouseCallback("a", MouseCallBack, (void*)&srcImage); //鼠标函数

		while(1)
		{
			srcImage.copyTo(tempImage);
			if (g_value)
			{
				DrawRectangle(tempImage, g_rect); //这句话实际上是在记录整个鼠标的移动过程
			}
			imshow("a", tempImage);
			if (waitKey(10) == 27)break;//按ESC键退出
		}



	return 0;
}


运行效果如下:

在这里插入图片描述

发布了14 篇原创文章 · 获赞 1 · 访问量 505

猜你喜欢

转载自blog.csdn.net/qq_41741344/article/details/104334662