Open CV 学习笔记:鼠标操作(回调函数)

一、指定鼠标消息回调函数 SetMouseCallback

  

 opencv中的鼠标响应的函数是setMouseCallback()。

    c++: void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)

  •     winname:窗口的名字
  •     onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的原型应该为void on_Mouse(int event, int x, int y, int flags, void* param);
  •     userdate:传给回调函数的参数 
    
     void on_Mouse(int event, int x, int y, int flags, void* param);
  • event是 CV_EVENT_*变量之一
    • EVENT_MOUSEMOVE 滑动
    • EVENT_LBUTTONDOWN 左击
    • EVENT_RBUTTONDOWN 右击
    • EVENT_MBUTTONDOWN 中键点击
    • EVENT_LBUTTONUP 左键放开
    • EVENT_RBUTTONUP 右键放开
    • EVENT_MBUTTONUP 中键放开
    • EVENT_LBUTTONDBLCLK 左键双击
    • EVENT_RBUTTONDBLCLK 右键双击
    • EVENT_MBUTTONDBLCLK 中键双击
  • x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系) 
  • flags是CV_EVENT_FLAG的组合,flag的状态有:
    • EVENT_FLAG_LBUTTON 左键拖拽
    • EVENT_FLAG_RBUTTON 右键拖拽
    • EVENT_FLAG_MBUTTON 中键拖拽
    • EVENT_FLAG_CTRLKEY 按住Ctrl不放
    • EVENT_FLAG_SHIFTKEY 按住Shift不放
    • EVENT_FLAG_ALTKEY 按住Alt不放
  • param是用户定义的传递到setMouseCallback函数调用的参数。

  

示例:利用鼠标绘制矩形


#include <opencv2/opencv.hpp>
#include <vector>
#include <stdio.h>
#define WINDOW_NAME "chengxuchuangkou"

using namespace cv;


void on_MouseHandle(int event,int x,int y,int flags,void* param);
void DrawRectangle(cv::Mat& img,cv::Rect box);

Rect g_rectangele;
bool g_bDrawingBox = false;
RNG g_rng(12345);

int main(int argc,char** argv){//画矩形窗口

	g_rectangele = Rect(-1,-1,0,0);
	Mat srcImage(600,800,CV_8UC3),tempImage;
	srcImage.copyTo(tempImage);
	srcImage = cv::Scalar::all(0);
	
	namedWindow(WINDOW_NAME);
	setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);

	while(1){
		//imshow("temp",srcImage);
		srcImage.copyTo(tempImage);
		if(g_bDrawingBox) DrawRectangle(tempImage,g_rectangele);
		imshow(WINDOW_NAME,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){
				g_rectangele.width = x - g_rectangele.x;
				g_rectangele.height = y - g_rectangele.y;
			}		
		}
		break;
		case EVENT_LBUTTONDOWN:{
			g_bDrawingBox = true;
			g_rectangele = Rect(x,y,0,0);

		}
		break;
		case EVENT_LBUTTONUP:{
			g_bDrawingBox = false;
			if(g_rectangele.width < 0){
				g_rectangele.x += g_rectangele.width;
				g_rectangele.width *= -1;
			}
			if(g_rectangele.height < 0){
				g_rectangele.y += g_rectangele.height;
				g_rectangele.height *= -1;
			}
			DrawRectangle(image,g_rectangele);
		}
		break;
	}
}
void DrawRectangle(cv::Mat& img,cv::Rect box){//绘制矩形
	printf("%d %d\n",box.width,box.height);
	rectangle(img,box.tl(),box.br(),Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)));
}


二、创建滑动条createTrackbar()函数

opencv中的滑动条创建函数是createTrackbar()。

C++: int createTrackbar(const string& trackbarname, const string& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0)
Parameters:                                     
  • trackbarname – Name of the created trackbar.在标签中显示的文字(提示滑动条的用途) 
  • winname – Name of the window that will be used as a parent of the created trackbar.创建的滑动条要放置窗体的名字 
  • value – Optional pointer to an integer variable whose value reflects the position of the slider. Upon creation, the slider position is defined by this variable.滑动条的初始位置
  • count – Maximal position of the slider. The minimal position is always 0.滑动条的最大位置
  • onChange – Pointer to the function to be called every time the slider changes position. This function should be prototyped as  void Foo(int,void*); , where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but only  value is updated.
    • 每当滑动条的值改变, 就会调用 on_trackbar 回调函数
  • userdata – User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables.

The function createTrackbar creates a trackbar (a slider or range control) with the specified name and range, assigns a variable valueto be a position syncronized with the trackbar and specifies the callback function onChange to be called on the trackbar position change. The created trackbar is displayed in the specified window winname.


示例:图像对比度和亮度的调节


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

using namespace cv;
using namespace std;



int g_nBrightValue;
int g_nContrastValue;
Mat g_srcImage,g_dstImage;

static void On_BrightAndContrast(int,void *){
	for(int i = 0;i < g_dstImage.rows;i++){
		for(int j = 0;j < g_dstImage.cols;j++){
			for(int k = 0;k < 3;k++){
				g_dstImage.at<Vec3b>(i,j)[k] = static_cast<uchar>(g_srcImage.at<Vec3b>(i,j)[k]*(g_nContrastValue*0.01)+g_nBrightValue);
			}
		}
	}
	imshow("原始窗口",g_srcImage);
	imshow("效果窗口",g_dstImage);
}

int main(){
	g_srcImage = imread("img.jpg");
	if(!g_srcImage.data){
		cout<<"input error!"<<endl;
		return 0;
	}
	g_dstImage = Mat::zeros(g_srcImage.size(),g_srcImage.type());

	g_nBrightValue = 70;
	g_nContrastValue = 70;

	namedWindow("效果窗口",1);

	createTrackbar("Brightness","效果窗口",&g_nBrightValue,200,On_BrightAndContrast);
	createTrackbar("Contrast","效果窗口",&g_nContrastValue,300,On_BrightAndContrast);

	On_BrightAndContrast(g_nBrightValue,0);
	On_BrightAndContrast(g_nContrastValue,0);

	while(waitKey(0) == 'q') {}
	return 0;
}




版权声明:本文为ymmqwe原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。