OpenCV2学习(6)之基本鼠标操作

上次我们学习到滑动条的添加,实际就是创建滑动条,然后按照格式写回调函数即可。

现在学习的鼠标操作也有异曲同工之妙,也是按照固定的格式变写回调函数,然后识别鼠标左键与右键的标识符或者鼠标移动标识符即可。

enum
{
        //鼠标移动标识符
        EVENT_MOUSEMOVE      =0,
        //左键按下标识符
        EVENT_LBUTTONDOWN    =1,
        //右键按下标识符
        EVENT_RBUTTONDOWN    =2,
        //中间按钮按下标识符
        EVENT_MBUTTONDOWN    =3,
        //左键弹起标识符
        EVENT_LBUTTONUP      =4,
        //右键弹起标识符
        EVENT_RBUTTONUP      =5,
        //中间键弹起标识符
        EVENT_MBUTTONUP      =6,
        //左键双击标识符
        EVENT_LBUTTONDBLCLK  =7,
        //右键双击标识符
        EVENT_RBUTTONDBLCLK  =8,
        //中间键双击标识符
        EVENT_MBUTTONDBLCLK  =9
};

程序例子:

//头文件
#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 DrawCircle(cv::Mat& img, Point center);
void ShowHelpText();

//-----------------------------------【全局变量声明部分】-----------------------------------
//		描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Rect g_rectangle;
bool g_bDrawingBox = false;//是否进行绘制矩形
bool g_bDrawingCircle = false;//是否进行绘制圆形
RNG g_rng(12345);
Point g_CircleCenter;

//主函数
int main(int argc, char** argv)
{
	//【0】改变console字体颜色
	system("color 9F");

	//【0】显示欢迎和帮助文字
	ShowHelpText();

	//【1】准备参数
	g_rectangle = Rect(-1, -1, 0, 0);
	Mat srcImage(600, 800, CV_8UC3), tempImage;
	srcImage.copyTo(tempImage);
	g_rectangle = Rect(-1, -1, 0, 0);
	srcImage = Scalar::all(0);

	//【2】设置鼠标操作回调函数
	namedWindow(WINDOW_NAME);
	setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);

	//【3】程序主循环,当进行绘制的标识符为真时,进行绘制
	while (1)
	{
		srcImage.copyTo(tempImage);//拷贝源图到临时变量
		//当进行绘制的标识符为真,则进行绘制
		if (g_bDrawingBox)
		{
			DrawRectangle(tempImage, g_rectangle);
		}
		//当进行绘制的标识符为真,则进行绘制
		if (g_bDrawingCircle)
		{
			DrawCircle(tempImage, g_CircleCenter);
		}
		imshow(WINDOW_NAME, tempImage);
		if (waitKey(10) == 27) break;//按下ESC键,程序退出
	}
	return 0;
}


//--------------------------------【on_MouseHandle( )函数】-----------------------------
//		描述:鼠标回调函数,根据不同的鼠标事件进行不同的操作
//-----------------------------------------------------------------------------------------------
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_rectangle.width = x - g_rectangle.x;
				g_rectangle.height = y - g_rectangle.y;
			}
		}
		break;

		//左键按下消息
		case EVENT_LBUTTONDOWN:
		{
			g_bDrawingBox = true;
			g_rectangle = Rect(x, y, 0, 0);//记录起始点
		}
		break;

		//左键抬起消息
		case EVENT_LBUTTONUP:
		{
			//置标识符为false
			g_bDrawingBox = false;
			//对宽和高小于0的处理
			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;

		//右键按下消息
		case EVENT_RBUTTONDOWN:
		{
			g_bDrawingCircle = true;
			g_CircleCenter.x = Rect(x, y, 0, 0).x;//记录右键点击的点
			g_CircleCenter.y = Rect(x, y, 0, 0).y;//记录右键点击的点
			//调用函数进行绘制
			DrawCircle(image, g_CircleCenter);
		}
		break;
	}
}


//-----------------------------------【DrawRectangle( )函数】------------------------------
//		描述:自定义的矩形绘制函数
//-----------------------------------------------------------------------------------------------
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
	cv::rectangle(img, box.tl(), box.br(), cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//随机颜色
}


//-----------------------------------【DrawCircle( )函数】------------------------------
//		描述:自定义的矩形绘制函数
//-----------------------------------------------------------------------------------------------
void DrawCircle(cv::Mat& img, Point center)
{
	cv::circle(img, center, 10, cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//随机颜色
}


//-----------------------------------【ShowHelpText( )函数】-----------------------------
//          描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
void ShowHelpText()
{
	//和OpenCV版本
	printf("\n\n\t\t\t   当前使用的OpenCV版本为:" CV_VERSION);
	printf("\n\n  ----------------------------------------------------------------------------\n");
	//输出一些帮助信息
	printf("\n\n\n\t欢迎来到【鼠标交互演示】示例程序\n");
	printf("\n\n\t请在窗口中点击鼠标左键并拖动以绘制矩形\n");
	printf("\n\n\t请在窗口中点击鼠标右键以绘制圆形\n");
}

上面用到了一个矩形类cv::Rect

//如果创建一个Rect对象rect(100, 50, 50, 100),那么rect会有以下几个功能:  
rect.area();     //返回rect的面积 5000  
rect.size();     //返回rect的尺寸 [50 × 100]  
rect.tl();       //返回rect的左上顶点的坐标 [100, 50]  
rect.br();       //返回rect的右下顶点的坐标 [150, 150]  
rect.width();    //返回rect的宽度 50  
rect.height();   //返回rect的高度 100  
rect.contains(Point(x, y));  //返回布尔变量,判断rect是否包含Point(x, y)点 

效果图:

猜你喜欢

转载自blog.csdn.net/kou_ching/article/details/85403635
今日推荐