OpenCV highgui

OpenCV highgui模块相关的一些简单笔记

Posted by YuCong on October 14, 2020

OpenCV库提供了High-level GUI相关的一些方法,包括HighGUI windows和mouse events鼠标事件,OpenGL,Qt等。本文暂且只记录HighGUI windows和mouse events以及trackbar等使用方法。

OpenCV highgui


Created 2020.10.14 by Cong Yu; Last modified: 2022.09.05-v1.1.4 -> 2022.09.05-v1.1.6

Contact: windmillyucong@163.com

Copyleft! 2022 Cong Yu. Some rights reserved.


References

0. Intro

opencv highgui 提供了一些简单的GUI操作,且可以在功能丰富的 UI 框架(例如 Qt、WinForms 或 Cocoa*)中使用。

本文主要总结三个部分:

  • ButtonCallback 按键交互
  • MouseCallback 鼠标交互
  • TrackbarCallback 滑动条交互

头文件

1
#include <opencv2/highgui.hpp>

1. ButtonCallback

注意:需要有Qt支持

ButtonCallback

1
typedef void(* cv::ButtonCallback) (int state, void *userdata)

Callback function for a button created by cv::createButton.

Parameters

  • state:current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button.
  • userdata:The optional parameter.

createButton()

1
2
3
4
5
6
int cv::createButton	(	const String & 	bar_name,
ButtonCallback 	on_change,
void * 	userdata = 0,
int 	type = QT_PUSH_BUTTON,
bool 	initial_button_state = false 
)		

Attaches a button to the control panel.

The function createButton attaches a button to the control panel. Each button is added to a buttonbar to the right of the last button. A new buttonbar is created if nothing was attached to the control panel before, or if the last element attached to the control panel was a trackbar or if the QT_NEW_BUTTONBAR flag is added to the type.

See below various examples of the cv::createButton function call: :

1
2
3
4
5
6
createButton("",callbackButton);//create a push button "button 0", that will call callbackButton.
createButton("button2",callbackButton,NULL,QT_CHECKBOX,0);
createButton("button3",callbackButton,&value);
createButton("button5",callbackButton1,NULL,QT_RADIOBOX);
createButton("button6",callbackButton2,NULL,QT_PUSH_BUTTON,1);
createButton("button6",callbackButton2,NULL,QT_PUSH_BUTTON|QT_NEW_BUTTONBAR);// create a push button in a new row

Parameters

  • bar_name: Name of the button.
  • on_change: Pointer to the function to be called every time the button changes its state. This function should be prototyped as void Foo(int state,void); . *state is the current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button.
  • userdata: Pointer passed to the callback function.
  • type: Optional type of the button. Available types are: (cv::QtButtonTypes)
  • initial_button_state: Default state of the button. Use for checkbox and radiobox. Its value could be 0 or 1. (Optional)

2. MouseCallback

MouseCallback

MouseCallback的原型:

1
typedef void(* cv::MouseCallback) (int event, int x, int y, int flags, void *userdata)

参数:

Parameters 说明
event one of the cv::MouseEventTypes constants.
x The x-coordinate of the mouse event. 鼠标事件的坐标
y The y-coordinate of the mouse event.
flags one of the cv::MouseEventFlags constants.
userdata The optional parameter.

MouseEventTypes

再看看MouseEventTypes 类型都有些什么?

Enumerator  
EVENT_MOUSEMOVE
Python: cv.EVENT_MOUSEMOVE
indicates that the mouse pointer has moved over the window.
鼠标移动
EVENT_LBUTTONDOWN
Python: cv.EVENT_LBUTTONDOWN
indicates that the left mouse button is pressed.
左键按下
EVENT_RBUTTONDOWN
Python: cv.EVENT_RBUTTONDOWN
indicates that the right mouse button is pressed.
右键按下
EVENT_MBUTTONDOWN
Python: cv.EVENT_MBUTTONDOWN
indicates that the middle mouse button is pressed.
中键按下
EVENT_LBUTTONUP
Python: cv.EVENT_LBUTTONUP
indicates that left mouse button is released.
左键释放
EVENT_RBUTTONUP
Python: cv.EVENT_RBUTTONUP
indicates that right mouse button is released.
右键释放
EVENT_MBUTTONUP
Python: cv.EVENT_MBUTTONUP
indicates that middle mouse button is released.
中键释放
EVENT_LBUTTONDBLCLK
Python: cv.EVENT_LBUTTONDBLCLK
indicates that left mouse button is double clicked.
左键双击
EVENT_RBUTTONDBLCLK
Python: cv.EVENT_RBUTTONDBLCLK
indicates that right mouse button is double clicked.
右键双击
EVENT_MBUTTONDBLCLK
Python: cv.EVENT_MBUTTONDBLCLK
indicates that middle mouse button is double clicked.
中键双击
EVENT_MOUSEWHEEL
Python: cv.EVENT_MOUSEWHEEL
positive and negative values mean forward and backward scrolling, respectively.
向前(正值)向后(负值)滚动
EVENT_MOUSEHWHEEL
Python: cv.EVENT_MOUSEHWHEEL
positive and negative values mean right and left scrolling, respectively.
向左(正值)向右(负值)滚动

MouseEventFlags

再看看MouseEventFlags 类型都有些什么?

Enumerator  
EVENT_FLAG_LBUTTON
Python: cv.EVENT_FLAG_LBUTTON
indicates that the left mouse button is down.
左键是按下的
EVENT_FLAG_RBUTTON
Python: cv.EVENT_FLAG_RBUTTON
indicates that the right mouse button is down.
右键是按下的
EVENT_FLAG_MBUTTON
Python: cv.EVENT_FLAG_MBUTTON
indicates that the middle mouse button is down.
中键是按下的
EVENT_FLAG_CTRLKEY
Python: cv.EVENT_FLAG_CTRLKEY
indicates that CTRL Key is pressed.
CTRL是按下的
EVENT_FLAG_SHIFTKEY
Python: cv.EVENT_FLAG_SHIFTKEY
indicates that SHIFT Key is pressed.
shift是按下的
EVENT_FLAG_ALTKEY
Python: cv.EVENT_FLAG_ALTKEY
indicates that ALT Key is pressed.
ALT是按下的

setMouseCallback()

方法原型

1
2
3
4
void cv::setMouseCallback	(	const String & 	winname,
MouseCallback 	onMouse,
void * 	userdata = 0 
)	

Sets mouse handler for the specified window.

Parameters

  • winname: Name of the window.
  • onMouse: Callback function for mouse events.
  • userdata: The optional parameter passed to the callback.

代码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

/**
 * @brief Callback on mouse.
 */
const std::string kWindowName = "Mouse test";
void MouseTestCallback(int event, int x, int y, int flags, void *userdata) {
  auto src = (cv::Mat *)userdata;
  const auto point = cv::Point2f(x, y);
  if (flags == cv::EVENT_FLAG_SHIFTKEY) {
    LOG(ERROR) << "EVENT_FLAG_SHIFTKEY";

    if (event == cv::EVENT_LBUTTONDOWN) {
      LOG(ERROR) << "EVENT_LBUTTONDOWN";
      cv::circle(*src, point, 3, cv::Scalar(255, 0, 0), -1);
    } else if (event == cv::EVENT_RBUTTONDOWN) {
      LOG(ERROR) << "EVENT_LBUTTONDOWN";
      cv::circle(*src, point, 3, cv::Scalar(0, 0, 255), -1);
    } else if (event == cv::EVENT_LBUTTONUP) {
      LOG(ERROR) << "EVENT_LBUTTONUP";
      cv::circle(*src, point, 3, cv::Scalar(255, 255, 0), -1);
    } else if (event == cv::EVENT_RBUTTONUP) {
      LOG(ERROR) << "EVENT_RBUTTONUP";
      cv::circle(*src, point, 3, cv::Scalar(0, 255, 255), -1);
    }
  } else {
    if (event == cv::EVENT_LBUTTONDOWN) {
      LOG(ERROR) << "EVENT_LBUTTONDOWN";
      cv::circle(*src, point, 10, cv::Scalar(255, 0, 0), 1);
    } else if (event == cv::EVENT_RBUTTONDOWN) {
      LOG(ERROR) << "EVENT_LBUTTONDOWN";
      cv::circle(*src, point, 10, cv::Scalar(0, 0, 255), 1);
    } else if (event == cv::EVENT_LBUTTONUP) {
      LOG(ERROR) << "EVENT_LBUTTONUP";
      cv::circle(*src, point, 10, cv::Scalar(255, 255, 0), 1);
    } else if (event == cv::EVENT_RBUTTONUP) {
      LOG(ERROR) << "EVENT_RBUTTONUP";
      cv::circle(*src, point, 10, cv::Scalar(0, 255, 255), 1);
    }
  }

  cv::imshow(kWindowName, *src);
}

bool TestMouseGUI() {
  cv::Mat src(cv::Size(800, 600), CV_8UC3);
  cv::namedWindow(kWindowName, cv::WINDOW_NORMAL);
  cv::resizeWindow(kWindowName, 960, 720);
  cv::setMouseCallback(kWindowName, MouseTestCallback, &src);
  cv::imshow(kWindowName, src);

  while (true) {
    auto key = cv::waitKey(20);
    if ('q' == key || 27 == key) {  // quit
      cv::destroyWindow(kWindowName);
      break;
    }
  }

  return true;
}

int main(int argc, char **argv) {
  google::InitGoogleLogging(argv[0]);
  google::InstallFailureSignalHandler();
  google::ParseCommandLineFlags(&argc, &argv, false);

  TestMouseGUI();
  cv::destroyAllWindows();
  return 0;
}

3. TrackbarCallback

TrackbarCallback

方法原型

1
typedef void(* cv::TrackbarCallback) (int pos, void *userdata)

Parameters

  • pos: current position of the specified trackbar.
  • userdata: The optional parameter.

createTrackbar()

1
2
3
4
5
6
7
int cv::createTrackbar	(	const String & 	trackbarname,
const String & 	winname,
int * 	value,
int 	count,
TrackbarCallback 	onChange = 0,
void * 	userdata = 0 
)		

Creates a trackbar and attaches it to the specified window.

The function createTrackbar creates a trackbar (a slider or range control) with the specified name and range, assigns a variable value to be a position synchronized 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.

Note

  • [Qt Backend Only] winname can be empty if the trackbar should be attached to the control panel.
  • Clicking the label of each trackbar enables editing the trackbar values manually.

Parameters

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.
userdata User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables.

注意:

  • createTrackbar 是可以不要 callback 函数的
  • 不要callback函数时就需要在while循环里面不断获取最新参数并使用
  • 一般同时处理多参数的时候可以考虑不要callback,不然每条参数都要创建一个callback函数

代码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// test trackbar using a callback func  
  
#include <gflags/gflags.h>  
#include <glog/logging.h>  
#include <opencv2/core.hpp>  
#include <opencv2/highgui.hpp>  
#include <opencv2/imgproc.hpp>  
  
int value = 10;  
const std::string kWindowName = "TrackbarTest";  
  
void TrackbarTestCallback(int value, void *userdata) {  
  auto src = (cv::Mat *)userdata;  
  cv::circle(*src, cv::Point(320, 240), value, cv::Scalar(255, value, 255), 1);  
  cv::imshow(kWindowName, *src);  
}  
  
bool TestTrackBar() {  
  cv::Mat src(cv::Size(640, 480), CV_8UC3, cv::Scalar(255, 255, 255));  
  cv::namedWindow(kWindowName, cv::WINDOW_NORMAL);  
  cv::resizeWindow(kWindowName, 640, 480);  
  cv::imshow(kWindowName, src);  
  
  cv::createTrackbar("value", kWindowName, &value, 256, TrackbarTestCallback,  
                     &src);  
  
  while (true) {  
    auto key = cv::waitKey(20);  
    if ('q' == key || 27 == key) {  // quit  
      cv::destroyWindow(kWindowName);  
      break;    }  
  }  
  return true;  
}  
  
int main(int argc, char **argv) {  
  google::InitGoogleLogging(argv[0]);  
  google::InstallFailureSignalHandler();  
  google::ParseCommandLineFlags(&argc, &argv, false);  
  
  TestTrackBar();  
  cv::destroyAllWindows();  
  return 0;  
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// test trackbar without a callback func

#include <gflags/gflags.h>
#include <glog/logging.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

int value_b = 10;
int value_g = 10;
int value_r = 10;
const std::string kWindowName = "TrackbarTest";

bool TestTrackBar() {
  cv::Mat src(cv::Size(640, 480), CV_8UC3, cv::Scalar(255, 255, 255));
  cv::namedWindow(kWindowName, cv::WINDOW_NORMAL);
  cv::resizeWindow(kWindowName, 640, 480);
  cv::imshow(kWindowName, src);

  cv::createTrackbar("b", kWindowName, &value_b, 256);
  cv::createTrackbar("g", kWindowName, &value_g, 256);
  cv::createTrackbar("r", kWindowName, &value_r, 256);

  while (true) {
    auto key = cv::waitKey(20);
    if ('q' == key || 27 == key) {  // quit
      cv::destroyWindow(kWindowName);
      break;
    }

    cv::circle(src, cv::Point(320, 240), 100,
               cv::Scalar(value_b, value_g, value_r), -1);
    cv::imshow(kWindowName, src);
  }

  return true;
}

int main(int argc, char **argv) {
  google::InitGoogleLogging(argv[0]);
  google::InstallFailureSignalHandler();
  google::ParseCommandLineFlags(&argc, &argv, false);

  TestTrackBar();
  cv::destroyAllWindows();
  return 0;
}

效果:

track_bar_test.png

Fig1.  Tune color using trackbars


Contact

Feel free to contact me windmillyucong@163.com anytime for anything.

License

Creative Commons BY-SA 4.0

CC0