滑动条的创建
1、creatTrackbar函数
要创建一个跟踪栏,首先我们必须创建一个它将被放置的窗口。所以
namedWindow("Linear Blend", WINDOW_AUTOSIZE); // Create Window
通过使用cv :: createTrackbar在OpenCV窗口中添加一个Trackbar
CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,
int* value, int count,
TrackbarCallback onChange = 0,
void* userdata = 0);
参数解释:
①const string&类型的trackbarname:表示轨迹条的名字,用来代表我们创建的轨迹条。
②const string&类型的winname:表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
③int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
④int类型的count:表示滑块可以达到的最大位置的值。滑块最小的位置的值为0。
⑤TrackbarCallback类型的onChange:首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。
⑥void* userdata:用户传给回调函数的数据,如果第三个值为全局变量,忽略这个值.
2、TrackbarCallback():回调函数;
typedef void (*TrackbarCallback)(int pos, void* userdata);
参数1:其中第一个参数是跟踪栏位置
参数2: 第二个参数是用户数据,如果回调函数是NULL指针,则不会调用回调函数,而只会更新值(比如窗口中的图像数据地址)
TrackbarCallback为函数void (int pos,void* userdata)的别名,onChange 为TrackbarCallback类型的一个变量。关系如下:
*TrackbarCallback = onChange = void (int pos,void* userdata) ;
也就是说赋给函数指针的函数应该和函数指针所指的函数原型是一致的(*TrackbarCallback)
为函数体void (int pos,void* userdata)
的别名,所以回调函数声明应为 void onChange(int,void*)
。
TrackbarCallback
为void (int,void*)
类型的指针。指向的是函数类型为
void (int,void*)
的地址,也就是函数名onChange;
例如:int (*p)(int x, int y);
p指针可以指向int (int x, int y)类型的函数的首地址。
3、函数指针:
一个函数总是占据一段连续的内存区域,函数名在表达式中有时也会被转换为函数所在内存区域的首地址,这概念和数组十分相似如果把函数的入口地址赋予指针变量,使得这个指针变量指向函数所在的内存区域,然后通过这个指针变量就能调用该函数,这个指针就是函数指针。
指针函数的用处之一就是回调函数:
主要优势是解耦,即调用者和被调用者被分开,调用者无需了解谁是被调用者,它只需知道如果满足某条件之后,函数将被调用
具体请看:
函数调用不添加括号代表什么?
例子:
#include
using namespace std;
void onChangeTrackBar(int , void* );
int R_value = 0;
int G_value = 0;
int B_value = 0;
int R_value_u = 127;
int G_value_u = 127;
int B_value_u = 127;
cv::Mat src, dst;
void main()
{
cv::namedWindow("Trackbar", cv::WINDOW_AUTOSIZE);
src = cv::imread("C:\\Users\\Administrator\\Desktop\\test.png");
cv::inRange(src, cv::Scalar(B_value, G_value, R_value), cv::Scalar(B_value_u, G_value_u, R_value_u), dst);
int count = 255;
cv::createTrackbar("R_u", "Trackbar", &R_value_u, count, onChangeTrackBar, 0);
cv::createTrackbar("G_u", "Trackbar", &G_value_u, count, onChangeTrackBar, 0);
cv::createTrackbar("B_u", "Trackbar", &B_value_u, count, onChangeTrackBar, 0);
cv::createTrackbar("R", "Trackbar", &R_value, count, onChangeTrackBar, 0);
cv::createTrackbar("G", "Trackbar", &G_value, count, onChangeTrackBar, 0);
cv::createTrackbar("B", "Trackbar", &B_value, count, onChangeTrackBar, 0);
cv::imshow("Trackbar", dst);
cv::waitKey(0);
}
void onChangeTrackBar(int, void* )
{
/*cv::Mat dst;*/
cv::inRange(src, cv::Scalar(B_value, G_value, R_value), cv::Scalar(B_value_u, G_value_u, R_value_u), dst);
cv::imshow("Trackbar", dst);
/*cv::waitKey(0);*/
}