OpenCV3 鼠标事件和滑动条事件

鼠标事件

    cv::waitKey()函数进行键值辅捉,下一个逻辑事件就是对鼠标事件进行“监听”和做出响应。
    与键盘不同,鼠标事件使用更传统的回调函数函数机制来完成,这就意味着,我们必须先写好一个回调程序,
    使得OpenCV在发生任何鼠标事件时都可以调用这个回调程序,当完成回调程序以后,需要在OpenCV中注册这个函数,
    即告诉OpenCV这是一个正确的回调程序。
    指向回调函数的指针是 cv::MouseCallback,定义回调函数的接口协议:
  

 void your_mouse_callback
    (
        int event,        //Event type
        int x,            //x-location of mouse event
        int y,            //y-location of mouse event
        int flags,        //More details on event
        void* param        //Parameters from cv::setMouseCallback()
    );

    第一个参数为鼠标事件类型,如下所示:
    鼠标事件类型:
      

        EVENT_MOUSEMOVE      = 0, //!< indicates that the mouse pointer has moved over the window.
        EVENT_LBUTTONDOWN    = 1, //!< indicates that the left mouse button is pressed.
        EVENT_RBUTTONDOWN    = 2, //!< indicates that the right mouse button is pressed.
        EVENT_MBUTTONDOWN    = 3, //!< indicates that the middle mouse button is pressed.
        EVENT_LBUTTONUP      = 4, //!< indicates that left mouse button is released.
        EVENT_RBUTTONUP      = 5, //!< indicates that right mouse button is released.
        EVENT_MBUTTONUP      = 6, //!< indicates that middle mouse button is released.
        EVENT_LBUTTONDBLCLK  = 7, //!< indicates that left mouse button is double clicked.
        EVENT_RBUTTONDBLCLK  = 8, //!< indicates that right mouse button is double clicked.
        EVENT_MBUTTONDBLCLK  = 9, //!< indicates that middle mouse button is double clicked.
        EVENT_MOUSEWHEEL     = 10,//!< positive and negative values mean forward and backward scrolling, respectively.
        EVENT_MOUSEHWHEEL    = 11 //!< positive and negative values mean right and left scrolling, respectively.


    第二个和第三个参数将被设置为鼠标事件的x坐标和y坐标,这里的坐标是图像上的像素坐标,是独立于窗口的
    第四个参数是标志位,是一个bit位,每一个bit位都代表在事件发生时的不同条件。具体如下所示:
      

       EVENT_FLAG_LBUTTON   = 1, //!< indicates that the left mouse button is down.
       EVENT_FLAG_RBUTTON   = 2, //!< indicates that the right mouse button is down.
       EVENT_FLAG_MBUTTON   = 4, //!< indicates that the middle mouse button is down.
       EVENT_FLAG_CTRLKEY   = 8, //!< indicates that CTRL Key is pressed.
       EVENT_FLAG_SHIFTKEY  = 16,//!< indicates that SHIFT Key is pressed.
       EVENT_FLAG_ALTKEY    = 32 //!< indicates that ALT Key is pressed.


    第五个参数是一个void*类型的指针,OpenCV可以用来传递额外的信息到任何类型的结构。

 

   void cv::setMouseCallback
    (
        const string& windowName,    //Handle used to identify window
        cv::MouseCallback on_mouse,    //Callback function
        void*                        //Additional parameters for callback fn.
    );


    第一个参数,回调函数作用的窗口名称,只有事件在这个特定的窗口上时才能触发回调。
    第二个参数,注册的回调函数。
    第三个参数,可以在回调函数执行时给回调函数传递特定的信息。

 

#include<iostream>
#include<opencv2\highgui.hpp>
#include<opencv2\core.hpp>
#include<opencv2\imgproc.hpp>


void my_mouse_callback(int event, int x, int y, int flags, void*params);
cv::Rect box;
bool drawing_box = false;
void draw_box(cv::Mat& img, cv::Rect box)
{
	cv::rectangle
	(
		img,
		box.tl(),
		box.br(),
		cv::Scalar(0x00, 0x00, 0xff)
	);
}

int main()
{
	cv::Mat image(200, 200, CV_8UC3), tmp;


	box = cv::Rect(-1, -1, 0, 0);
	image = cv::Scalar::all(0);

	cv::namedWindow("Box Example");

	cv::setMouseCallback("Box Example", my_mouse_callback, (void*)&image);
	for (;;)
	{
		image.copyTo(tmp);
		cv::imshow("1", image);
		//std::cout << drawing_box << std::endl;
		if (drawing_box) draw_box(tmp, box);
		cv::imshow("Box Example", tmp);
		//cv::imshow("2", image);
		cv::waitKey(33);
	}
	return 0;
}

void my_mouse_callback(int event, int x, int y, int flags, void*params)
{
	cv::Mat& image = *(cv::Mat*)params;
	switch (event)
	{
	//鼠标动
	case cv::EVENT_MOUSEMOVE:
	{
		if (drawing_box)
		{
			box.width = x - box.x;
			box.height = y - box.y;
		}
		break;
	}
	//左鼠标按下
	case cv::EVENT_LBUTTONDOWN:
	{
		drawing_box = true;
		box = cv::Rect(x, y, 0, 0);
		break;
	}
	//左鼠标按下抬起
	case cv::EVENT_LBUTTONUP:
	{
		drawing_box = false;
		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);
	}
	default:
		break;
	}
	
}


滑动条/滚动条 (slider/trackbar)

最初设计的目的就是在视频播放帧中选择特定帧。
在和父窗口使用时,需要给滑动条赋予一个特别的名字(通常是一个字符串),接下来将直接通过那个名字进行引用;
 

 int cv::createTrackbar(
    const string&         trackbarName,      // Handle used to identify trackbar
    const string&         windowName,      // Handle used to identify window
    int*                 value,              // Slider position gets put here
    int                     count,              // Total counts for slider at far right
    cv::TrackbarCallback onChange = NULL, // Callback function (option)
    void*                 param      = NULL  // Addition params for callback fn
    );


    第一个参数是滑动条的名称,
    第二个参数是滑动条将要添加到父窗口的名称,一旦滑动条创建好,它将被添加到窗口的顶部或底部。
        滑动条不会挡住任何已经在窗口中的图像,只会让窗口变大,窗口的名将作为一个窗口的标记,至于滑动条上滑动钮的
        的确切位置,由操作系统决定,一般都是最左边。
    第三个参数 value,一个指向整数的指针,这个整数值会随着滑动钮的移动自动变化。
    第四个参数 count,是滑动条可以滑动的最大值。
    第五个参数 onChange,是一个指向回调函数的指针,当滑动钮移动时,回调函数就会自动调用。
    第六个参数 param,可以是一个任何类型的指针,一旦回调函数执行,这个参数可以传递给回调函数
        的param参数,这样不创建全局变量也可以处理滑动条事件。

    回调函数的特定形式,也就是说必须满足一下定义:
  

  void your_trackbar_callback
    (
        int pos,                //Trackbar slider position
        void* param    = NULL   //Parameters from cv::serTrackbarCallback()
    );


    这个回调函数不是必须的,如果不需要直接赋值为NULL,没有回调函数,移动滑动钮的唯一响应就是
    value指向的变量值得变化,

    //获取滑动条的位置
    

int cv::getTrackbarPos
    (
        const string& trackName,    //Handle used to identify trackbar, label
        const string& windowName    //Handle used to identify window
    );


    //设置滑动条的位置
  

 void cv::setTrackbarPos
    (
        const string& trackName,    //Handle used to identify trackbar, label
        const string& windowName,    //Handle used to identify window
        int pos                        //Trackbar slider position
    );

 

#include<iostream>
#include<opencv2\highgui.hpp>
#include<opencv2\core.hpp>

int g_switch_value = 1;
void switch_off_function() { std::cout << "Puase" << std::endl; }
void switch_on_function() { std::cout << "Run" << std::endl; }

void switch_callback(int position, void*)
{
	if (position)
	{
		switch_on_function();
	}
	else
	{
		switch_off_function();
	}
}
char* videopath = "D:/Coder/vs/1_OpenCV/videoTest.mp4";
const cv::String nameWin = "Example";
int main()
{
	cv::Mat frame;
	cv::VideoCapture g_capture;
	g_capture.open(videopath);
	if (!g_capture.isOpened())
	{
		std::cout << "Error" << std::endl;
	}
	cv::namedWindow(nameWin, cv::WINDOW_AUTOSIZE);
	cv::createTrackbar(
		"Switch",
		nameWin,
		&g_switch_value,
		1,
		switch_callback
	);
	for (;;)
	{
		if (g_switch_value)
		{
			g_capture >> frame;
			if (frame.empty())
				break;
			cv::imshow(nameWin, frame);
		}
		if (cv::waitKey(33) == 27)
			break;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&小鹏鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值