天天看點

Opencv函數setMouseCallback滑鼠事件響應

使用者通過滑鼠對圖像視窗最常見的操作有:

1. 左鍵單擊按下

2. 左鍵單擊擡起

3. 左鍵按下拖動

4. 滑鼠指針位置移動

單次單擊操作響應事件及順序

Opencv中setMouseCallback()建立了一個滑鼠回調函數,每次在圖像上單擊滑鼠左鍵再擡起的過程,都會分3次調用滑鼠響應函數,并且響應順序是:

1.左鍵單擊按下;

2.左鍵單擊擡起;

3.滑鼠指針位置移動(即使原地單擊,滑鼠位置并沒有移動);

可以編碼驗證一下回調函數的這個調用機制:

#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include<iostream>

using namespace cv;
using namespace std;

void OnMouseAction(int event,int x,int y,int flags,void *ustc);  //滑鼠回調事件函數
int static times; //記錄調用次數


int main(int argc,char*argv[])
{
	Mat image=imread(argv[1]);
	imshow("image",image);
	setMouseCallback("image",OnMouseAction);
	waitKey();
	system("pause");
}

//*******************************************************************//
//滑鼠回調函數

void OnMouseAction(int event,int x,int y,int flags,void *ustc)
{	
	times++;
	cout<<"第 "<<times<<" 次回調滑鼠事件"<<endl;
	if(event==CV_EVENT_MOUSEMOVE)
	{
		cout<<"觸發滑鼠移動事件"<<endl;
	}
	if(event==CV_EVENT_LBUTTONDOWN)
	{
		cout<<"觸發左鍵按下事件"<<endl;
	}
	if(event==CV_EVENT_LBUTTONUP)
	{
		cout<<"觸發左鍵擡起事件"<<endl;
	}
	if(event==CV_EVENT_RBUTTONDOWN)
	{
		cout<<"觸發右鍵按下事件"<<endl;
	}
	if(event==CV_EVENT_RBUTTONUP)
	{
		cout<<"觸發右鍵擡起事件"<<endl;
	}
	if(event==CV_EVENT_LBUTTONDBLCLK)
	{
		cout<<"觸發左鍵輕按兩下事件"<<endl;
	}
	if(event==CV_EVENT_RBUTTONDBLCLK)
	{
		cout<<"觸發右鍵輕按兩下事件"<<endl;
	}
}
           
Opencv函數setMouseCallback滑鼠事件響應

前3次調用是在左鍵單擊前滑鼠指針在圖像視窗移動造成的。不移動位置,單擊左鍵,觸發了第4次調用,紅色框框内的就是一個完整的滑鼠按下再擡起的調用過程:

第一次傳入的event事件是左鍵單擊“CV_EVENT_LBUTTONDOWN”;

第二次傳入的event事件是左鍵擡起“CV_EVENT_LBUTTONUP”;

第三次傳入的event事件是滑鼠移動“CV_EVENT_MOUSEMOVE”,這時候滑鼠實體位置其實并沒有移動;

setMouseCallback()函數

了解了滑鼠回調函數的調用機制後再來看一下建立回調函數的函數setMouseCallback();

原型:

void setMouseCallback(const string& winname,     //圖像視窗名稱
MouseCallback onMouse,     //滑鼠響應函數,監視到滑鼠操作後調用并處理相應動作
void* userdata = 0        //滑鼠響應處理函數的ID,識别号
);
           

OnMouseAction()響應函數

滑鼠事件回調函數onMouse按照固定格式建立響應函數:

void OnMouseAction(int event,int x,int y,int flags,void *ustc) 
           

event事件代表了滑鼠的各種操作,詳細看一下各個event事件:

Event:
#define CV_EVENT_MOUSEMOVE 0             //滑動
#define CV_EVENT_LBUTTONDOWN 1           //左鍵點選
#define CV_EVENT_RBUTTONDOWN 2           //右鍵點選
#define CV_EVENT_MBUTTONDOWN 3           //中鍵點選
#define CV_EVENT_LBUTTONUP 4             //左鍵放開
#define CV_EVENT_RBUTTONUP 5             //右鍵放開
#define CV_EVENT_MBUTTONUP 6             //中鍵放開
#define CV_EVENT_LBUTTONDBLCLK 7         //左鍵輕按兩下
#define CV_EVENT_RBUTTONDBLCLK 8         //右鍵輕按兩下
#define CV_EVENT_MBUTTONDBLCLK 9         //中鍵輕按兩下
           

int x,int y,代表滑鼠位于視窗的(x,y)坐标位置,即Point(x,y);

int flags,代表滑鼠的拖拽事件,以及鍵盤滑鼠聯合事件,共有32種事件:

flags:
#define CV_EVENT_FLAG_LBUTTON 1       //左鍵拖曳
#define CV_EVENT_FLAG_RBUTTON 2       //右鍵拖曳
#define CV_EVENT_FLAG_MBUTTON 4       //中鍵拖曳
#define CV_EVENT_FLAG_CTRLKEY 8       //(8~15)按Ctrl不放事件
#define CV_EVENT_FLAG_SHIFTKEY 16     //(16~31)按Shift不放事件
#define CV_EVENT_FLAG_ALTKEY 32       //(32~39)按Alt不放事件
           

函數指針 void *ustc辨別了所響應的事件函數,相當于自定義了一個OnMouseAction()函數的ID。

簡單應用:記錄滑鼠按下時坐标和滑鼠擡起時坐标,分别做Line、Rectangle、Circle

#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include<iostream>

using namespace cv;
using namespace std;

void OnMouseAction(int event,int x,int y,int flags,void *ustc);  //滑鼠回調事件函數
int static times; //記錄調用次數

int rowsBegin,rowsEnd;
int colsBegin,colsEnd;
Mat image;

int main(int argc,char*argv[])
{
	image=imread(argv[1]);
	imshow("image",image);
	setMouseCallback("image",OnMouseAction);	
}

//*******************************************************************//
//滑鼠回調函數
void OnMouseAction(int event,int x,int y,int flags,void *ustc)
{	
	if(event==CV_EVENT_MOUSEMOVE)
	{
		cout<<"觸發滑鼠移動事件"<<endl;
	}
	if(event==CV_EVENT_LBUTTONDOWN)
	{
		rowsBegin=y;
		colsBegin=x;
		cout<<"觸發左鍵按下事件"<<endl;
	}
	if(event==CV_EVENT_LBUTTONUP)
	{
		rowsEnd=y;
		colsEnd=x;
		line(image,Point(colsBegin,rowsBegin),Point(colsEnd,rowsEnd),Scalar(255,0,0),2,8,0);
		rectangle(image,Rect(colsBegin,rowsBegin,colsEnd-colsBegin,rowsEnd-rowsBegin),Scalar(0,255,0),2,8,0);
		circle(image,Point((colsEnd+colsBegin)/2,(rowsEnd+rowsBegin)/2),rowsEnd-rowsBegin,Scalar(0,0,255),2,8,0);
		imshow("image",image);
		cout<<"觸發左鍵擡起事件"<<endl;
	}
	if(event==CV_EVENT_RBUTTONDOWN)
	{
		cout<<"觸發右鍵按下事件"<<endl;
	}
	if(event==CV_EVENT_RBUTTONUP)
	{
		cout<<"觸發右鍵擡起事件"<<endl;
	}
	if(event==CV_EVENT_LBUTTONDBLCLK)
	{
		cout<<"觸發左鍵輕按兩下事件"<<endl;
	}
	if(event==CV_EVENT_RBUTTONDBLCLK)
	{
		cout<<"觸發右鍵輕按兩下事件"<<endl;
	}
}
           

左鍵單擊按下之後拖動滑鼠到某一個位置之後松開:

Opencv函數setMouseCallback滑鼠事件響應