如何使用OpenCV轨迹栏传递用户数据

时间:2013-10-28 13:14:06

标签: c++ opencv void-pointers trackbar

目前我有许多用于更改图像值的滑块。我正在使用滑块的OpenCV轨迹栏,它为每个滑块都有一个不同功能的回调。我想让我的滑块回调指向一个回调函数,然后使用用户数据来识别哪个跟踪栏进行了调用。

Here is the documentation for the track bar

我不确定我应该传递给void *的值是什么,以及如何从我的回调函数中检索这个值下面是我编译的跟踪栏的示例。

int ref = 1;
createTrackbar("Name","Window",0, 1, myFunc, &ref);

在我的回调函数中,我尝试检索ref的值。

void myFunc(int value, void *userdata)
{
    int val = *((int*)&userdata);
    cout << val << endl;
}

我在尝试将指针转换回int时遇到了问题,这是我在网上找到的一个解决方案,它将val作为ref的地址。

int val = *((int*)&userdata);

这似乎有很多麻烦,因为我必须从val的地址返回值。有更简单的方法吗?

2 个答案:

答案 0 :(得分:1)

不,没有更简单的方法。这是您想要的最低功能。

答案 1 :(得分:0)

传递一个看起来不那么麻烦的变量。

void cb_func(..., void *userdata) {
    int val = *static_cast<int *>(userdata);
}

调用它:

cv_function_takes_callback(..., cb_func, static_cast<void *>(&val));

C++11 传递多个变量的方式。
您可以传递引用甚至 lambda 函数。

type1 var1;
type2 var2;
auto lambda_no_capture = [](...) { ... };

typedef std::tuple<type1, const type2 &, decltype(lambda_no_capture)> tup_t;
tup_t tup(var1, var2, lambda_no_capture);

auto cb_func = [](..., void *userdata) -> void {
    tup_t &tup = *static_cast<tup_t *>(userdata);
    type1 var1 = std::get<0>(tup);
    decltype(auto) var2 = std::get<const type2 &>(tup); // requires c++14
    auto lambda_no_capture = std::get<2>(tup);
};

cv_function_takes_callback(..., cb_func, static_cast<void *>(&tup));

一些注意事项:

  • 您可以使用 auto var1 = std::get<0>(tup);,但明确一点更好。

  • 如果您将 auto 与引用变量一起使用,请使用 const auto &var2 = std::get<1>(tup);。 如果您未绑定到 C++11,那么 decltype(auto) 就是这样做的。

  • 将 lambda 函数传递给回调函数看起来很酷,但这与在全局范围内使用函数没有什么不同,因为它们无法捕获参数