OpenCV鼠標事件和滑動條事件

鼠標事件

① 鼠標事件是通過傳統的回調函數機制來完成。

void your_mouse_callback(int event, int x, int y, int flags, void* param)

其中,第一個參數要指明事件,第二個和第三個參數是鼠標事件的位置,第四個參數是標誌位,第五個參數是一個void類型的指針,可用於傳遞額外的信息。

鼠標事件類型
事件 數值 含義
cv::EVENT_MOUSEMOVE 0 鼠標移動事件
cv::EVENT_LBUTTONDOWN 1 鼠標左鍵按下事件
cv::EVENT_RBUTTONDOWN 2 鼠標右鍵按下事件
cv::EVENT_MBUTTONDOWN 3 鼠標中鍵按下事件
cv::EVENT_LBUTTONUP 4 鼠標左鍵釋放事件
cv::EVENT_RBUTTONUP 5 鼠標右鍵釋放事件
cv::EVENT_MBUTTONUP 6 鼠標中鍵釋放事件
cv::EVENT_LBUTTONBLCLK 7 鼠標左鍵雙擊事件
cv::EVENT_RBUTTONBLCLK 8 鼠標右鍵雙擊事件
cv::EVENT_MBUTTONBLCLK 9 鼠標中鍵雙擊事件
cv::EVENT_MOUSEWHEEL 10 滑動滾輪上下滾動
cv::EVENT_MOUSEHWHEEL 11 滑動滾輪左右滾動

 

鼠標事件標誌
標誌 數值 含義
cv::EVENT_FlAG_LBUTTON 1 指示鼠標左鍵已關閉。
cv::EVENT_FlAG_RBUTTON 2 指示鼠標右鍵已關閉。
cv::EVENT_FlAG_MBUTTON 4 指示鼠標中鍵已關閉。
cv::EVENT_FlAG_CTRLKEY 8 指示CTRL鍵被按下。
cv::EVENT_FlAG_SHIFTKEY 16 指示SHIFT鍵被按下。
cv::EVENT_FlAG_ALTKEY 32 指示ALT鍵被按下。

② 在定義完回調函數後需要註冊該回調函數。

void cv::setMouseCallback(const string& windowName, cv::MouseCallback on_mouse, void* param=NULL)

其中,第一個參數是回調函數作用的窗口名稱,第二個參數是要註冊的回調函數,第三個是要給回調函數傳遞的特定信息。

#include "stdafx.h"
#include <opencv2/opencv.hpp>


// 定義回調函數
void my_mouse_callback(int event, int x, int y, int flags, void* param);

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));
}

void help() {
	std::cout << "Call: ./ch4_ex4_1\n" << "show how to use a mouse to draw regions in an image." << std::endl;
}

int main()
{
	help();
	box = cv::Rect(-1, -1, 0, 0);
	cv::Mat image(200, 200, CV_8UC3);
	cv::Mat temp;
	image.copyTo(temp);

	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(temp);
		if (drawing_box)
		{
			draw_box(temp, box);
		}
		cv::imshow("Box Example", temp);

		if (cv::waitKey(15) == 27)
		{
			break;
		}
	}
	cv::destroyWindow("Box Example");
    return 0;
}

void my_mouse_callback(int event, int x, int y, int flags, void* param) {
	cv::Mat& image = *(cv::Mat*) param;

	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);
		}
		break;
	}
}

 運行結果:

滑動條、滾動條和開關

① 創建一個滑動條

int cv::createTrackbar(const string& trackbarName, const string& windowName, int* value, int count, cv::TrackbarCallback onChange, void* param)

其中:第一個參數是滑動條名稱,第二個參函數是將要添加到的父窗口的名稱,第三個參數是指向整數的指針,這個整數值會隨着滑動鈕的移動自動變化,第四個參數是滑動條可以滑動的最大值,第五個參數是回調函數,最後一個參數是傳給回調函數的參數。

② 可獲取或設置滑動條的位置值

int cv::getTrackbarPos(const string& trackbarName, const string& windowName)

void cv::setTrackbarPos(const string& trackbarName, const string& windowName, int pos)

③ 開關功能

開關是隻有兩個位置的滾動條,當它處於“開”狀態的時候爲1, 處於“關”狀態的時候爲0。

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;

int g_switch_value = 1;
void switch_off_function() {
	cout << "Pause\n";
}

void switch_on_function(){
	cout << "run\n";
}

void switch_callback(int position, void*) {
	if (position == 0)
	{
		switch_off_function();
	}
	else
	{
		switch_on_function();
	}
}

void help() {
	cout << "Call: my.avi" << endl;
	cout << "Shows putting a pause button in a video." << endl;
}
// 使用滾動條來創建一個“開關”,用來控制視頻的播放功能
int main()
{
	cv::Mat frame;
	cv::VideoCapture g_capture;
	g_capture.open("D:\\mgtv\\123.mp4");
	help();
	cv::namedWindow("example", 1);
	cv::createTrackbar("switch", "example", &g_switch_value, 1, switch_callback);

	for (;;)
	{
		if (g_switch_value)
		{
			g_capture >> frame;
			if (frame.empty())
			{
				break;
			}
			cv::imshow("example", frame);
		}
		if (cv::waitKey(10) == 27)
		{
			break;
		}
	}
	cv::destroyWindow("example");
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章