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
- opencv module highgui https://docs.opencv.org/4.x/d7/dfc/group__highgui.html
- post https://www.oreilly.com/library/view/learning-opencv/9780596516130/ch04.html
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;
}
效果:
Fig1. Tune color using trackbars
Contact
Feel free to contact me windmillyucong@163.com anytime for anything.