欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

鼠标操作

程序员文章站 2024-01-13 12:42:04
...
#include <opencv2/opencv.hpp>
using namespace cv;
 
#define WINDOW_NAME "【程序窗口】"
 
//全局函数声明部分
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(cv::Mat& img, cv::Rect box);  //在临时变量的图片上绘制矩形
void ShowHelpText();
//全局变量声明部分
Rect g_rectanle;
bool g_bDrawingBox = false; //是否进行绘制
RNG g_rng(12345);
//main函数
int main(int argc, char** argv)
{
	//准备参数
	g_rectanle = Rect(-1,-1,0,0);
	Mat srcImage(600,800,CV_8UC3), tempImage;
	srcImage.copyTo(tempImage);	//复制源图到临时变量
	g_rectanle = Rect(-1,-1,0,0);
	srcImage  = Scalar::all(0);
	//设置鼠标操作回调函数
	namedWindow(WINDOW_NAME);
	setMouseCallback(WINDOW_NAME, on_MouseHandle,(void*)&srcImage);
 
	//程序主循环,当进行绘制的标示符 为真时,进行绘制
	while (1)
	{
		srcImage.copyTo(tempImage); //复制源图到临时变量
		if (g_bDrawingBox)
		{
			DrawRectangle(tempImage,g_rectanle); //当绘制的标示符为真,则进行绘制
		}
		imshow(WINDOW_NAME, tempImage);
		imwrite("123.jpg", tempImage);
		if (waitKey(10) == 27)
		{
			break;
		}
	}
	return 0;
}
///////////鼠标的回调函数,根据不同的鼠标事件进行不同的操作
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
	Mat& image = *(cv::Mat*)param;
	//鼠标移动 消息
	switch (event)
	{
	case EVENT_MOUSEMOVE:
		{
			if (g_bDrawingBox) //如果是否进行绘制的表示为真,则记录下长和宽到RECT变量中
			{
				g_rectanle.width = x - g_rectanle.x;
				g_rectanle.height = y - g_rectanle.y;
			}
		}
		break;
	//左键按下
	case EVENT_LBUTTONDOWN:
		{
			g_bDrawingBox = true;
			g_rectanle = Rect(x, y, 0, 0); //记录起始点
		}
		break;     // 起初此处遗漏掉了break;造成只能绘制出随机颜色的点,不能绘制矩形
	//左键抬起消息
	case EVENT_LBUTTONUP:
		{
			g_bDrawingBox = false;//置标示符为false
			//对宽和高小于0的处理
			if (g_rectanle.width < 0)
			{
				g_rectanle.x += g_rectanle.width;
				g_rectanle.width *= -1;
			}
			if (g_rectanle.height < 0)
			{
				g_rectanle.y += g_rectanle.height;
				g_rectanle.height *= -1;
			}
			//调用函数进行绘制
			DrawRectangle(image, g_rectanle);
		}
		break;
	default:
		break;
	}	
}
 
//自定义的矩形绘制函数
 
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
	rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0,255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));
}

 

OpenCv中的鼠标操作和滑动条的消息映射方式类似

SetMouseCallback 函数的作用是为指定的窗口设置鼠标回调函数

Void setMouseCallback(const string& winname,MouseCalllback onMouse,void* userdata = 0)

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

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

这个函数的原型的大概形式为 void Foo(int event,int x,int y,int flags,void* param).

其中event是EVENT_+变量之一,X和Y是鼠标指针在图像坐标系()中的坐标值,flags是EVENT_FLAG的组合,param 是用户定义的传递到SetMouseCallback函数调用的参数,如EVENT_MOUSEMOVE为鼠标移动消息,EVENT_LBUTTONDOWN为鼠标左键按下消息等。

在OpenCv2中,上述“EVENT_”之前可以加上“CV_”前缀。

第三个参数,void*类型的userdata,用户定义的传递到回调函数的参数,有默认值0.