OpenCV滑动条事件详解(附带实例)
在 OpenCV 中,滑动条设计的主要目的是在视频播放帧中选择特定帧,它在调节图像参数时也会经常用到。在使用滑动条前,需要给滑动条赋予一个名字(通常是一个字符串),接下来将直接通过这个名字进行引用。
创建滑动条的函数是 createTrackbar(),该函数声明如下:
回调函数类型 TrackbarCallback 的定义如下:
这个回调函数不是必需的,如果直接赋值为NULL,就没有回调函数,移动滑动按钮的唯一响应就是 createTrackbar 的参数 value 指向的变量值的变化。
除了创建滑动条的函数外,OpenCV 还提供了函数 getTrackbarPos(用于获取滑动块的位置)和 setTrackbarPos(用于设置滑动条的位置)。函数 getTrackbarPos 声明如下:
函数 setTrackbarPos 声明如下:
下面来看一个专业的例子,利用滑动块调节参数。
【实例】利用滑动块控制腐蚀和膨胀。
1) 打开 Qt Creator,新建一个控制台工程,工程名是 test。
2) 在 IDE 中打开 main.cpp,输入如下代码:
Erosion 和 Dilation 都是滑动条的回调函数,用于响应用户的滑动按钮事件。函数 erode 和 dilate 分别是 OpenCV 中腐蚀和膨胀图像的函数。
3) 保存工程并运行,结果如下图所示:
创建滑动条的函数是 createTrackbar(),该函数声明如下:
int cv::createTrackbar (const String & trackbarname, const String & winname, int * value, int count, TrackbarCallback onChange = 0, void *userdata = 0);参数说明如下:
- trackbarname:表示滑动条的名称;
- Winname:是滑动条将要添加到父窗口的名称,一旦滑动条创建好,它就将被添加到窗口的顶部或底部,滑动条不会挡住任何已经在窗口中的图像,只会让窗口变大,窗口的名称将作为一个窗口的标记,至于滑动条上滑动按钮的确切位置,由操作系统决定,一般都是在最左边;
- value:是一个指向整数的指针,这个整数值会随着滑动按钮的移动而自动变化;
- count:是滑动条可以滑动的最大值;
- onChange:是一个指向回调函数的指针,当滑动按钮移动时,回调函数就会被自动调用;
- userdata:可以是任何类型的指针,一旦回调函数执行,这个参数可以传递给回调函数的 userdata 参数,这样不创建全局变量也可以处理滑动条事件。
回调函数类型 TrackbarCallback 的定义如下:
typedef void(* cv::TrackbarCallback) (int pos, void *userdata);
- 参数 pos 表示滚动块的当前位置;
- userdata是传给回调函数的可选参数。
这个回调函数不是必需的,如果直接赋值为NULL,就没有回调函数,移动滑动按钮的唯一响应就是 createTrackbar 的参数 value 指向的变量值的变化。
除了创建滑动条的函数外,OpenCV 还提供了函数 getTrackbarPos(用于获取滑动块的位置)和 setTrackbarPos(用于设置滑动条的位置)。函数 getTrackbarPos 声明如下:
int cv::getTrackbarPos (const string& trackName, const string& windowName);其中参数 trackName 是滑动条的名称,windowName 是滑动条将要添加到父窗口的名称。函数返回滑动块的当前位置。
函数 setTrackbarPos 声明如下:
void cv::setTrackbarPos(const string &trackName, const string& windowName, int pos);其中参数 trackName 表示滑动条的名称,windowName 是滑动条将要添加到父窗口的名称,pos 表示要设置的滑动块位置。
下面来看一个专业的例子,利用滑动块调节参数。
【实例】利用滑动块控制腐蚀和膨胀。
1) 打开 Qt Creator,新建一个控制台工程,工程名是 test。
2) 在 IDE 中打开 main.cpp,输入如下代码:
#include <opencv2/opencv.hpp> using namespace cv; #include <iostream> using namespace std; Mat src, erosion_dst, dilation_dst; int erosion_elem = 0; int erosion_size = 0; int dilation_elem = 0; int dilation_size = 0; const int max_elem = 2; const int max_kernel_size = 21; void Erosion(int, void*); void Dilation(int, void*); int main(int argc, char** argv) { // 读取原图 src = imread("ter.jpg", IMREAD_COLOR); if (src.empty()) { cout << "Could not open or find the image!" << endl; return -1; } // 创建窗口:腐蚀演示 namedWindow("Erosion Demo", WINDOW_AUTOSIZE); // 创建窗口:膨胀演示 namedWindow("Dilation Demo", WINDOW_AUTOSIZE); moveWindow("Dilation Demo", src.cols, 0); // 创建轨迹条:选择结构元素类型(矩形/十字/椭圆) createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo", &erosion_elem, max_elem, Erosion); // 创建轨迹条:设置结构元素大小(2n+1) createTrackbar("Kernel size:\n 2n + 1", "Erosion Demo", &erosion_size, max_kernel_size, Erosion); // 膨胀窗口对应轨迹条 createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo", &dilation_elem, max_elem, Dilation); createTrackbar("Kernel size:\n 2n + 1", "Dilation Demo", &dilation_size, max_kernel_size, Dilation); // 首次执行一次以显示初始结果 Erosion(0, 0); Dilation(0, 0); waitKey(0); return 0; } // 腐蚀回调函数 void Erosion(int, void*) { int erosion_type = 0; if (erosion_elem == 0) erosion_type = MORPH_RECT; else if (erosion_elem == 1) erosion_type = MORPH_CROSS; else if (erosion_elem == 2) erosion_type = MORPH_ELLIPSE; Mat element = getStructuringElement( erosion_type, Size(2 * erosion_size + 1, 2 * erosion_size + 1), Point(erosion_size, erosion_size)); erode(src, erosion_dst, element); imshow("Erosion Demo", erosion_dst); } // 膨胀回调函数 void Dilation(int, void*) { int dilation_type = 0; if (dilation_elem == 0) dilation_type = MORPH_RECT; else if (dilation_elem == 1) dilation_type = MORPH_CROSS; else if (dilation_elem == 2) dilation_type = MORPH_ELLIPSE; Mat element = getStructuringElement( dilation_type, Size(2 * dilation_size + 1, 2 * dilation_size + 1), Point(dilation_size, dilation_size)); dilate(src, dilation_dst, element); imshow("Dilation Demo", dilation_dst); }在上述代码中,首先读取 ter.jpg,然后利用函数 namedWindow 创建两个窗口,接着利用函数 createTrackbar 创建 4 个滑动条,每个窗口上有两个滑动条。
Erosion 和 Dilation 都是滑动条的回调函数,用于响应用户的滑动按钮事件。函数 erode 和 dilate 分别是 OpenCV 中腐蚀和膨胀图像的函数。
3) 保存工程并运行,结果如下图所示:
