C++ 如何在 OpenCV 中使用 cv::createButton 原型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6084511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:27:47  来源:igfitidea点击:

How to use cv::createButton prototype in OpenCV

c++copencv

提问by Marcus Barnet

I'd like to understand how to use cv::createButton which is defined in OpenCV documentation:

我想了解如何使用 OpenCV 文档中定义的 cv::createButton :

http://opencv.jp/opencv-2svn_org/cpp/highgui_qt_new_functions.html#cv-createbutton

http://opencv.jp/opencv-2svn_org/cpp/highgui_qt_new_functions.html#cv-createbutton

It says that the prototype is:

它说原型是:

createButton(const string& button_name CV_DEFAULT(NULL), ButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL), int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0)

but i don't know how to define the function ButtonCallback in order to trap the button event.

但我不知道如何定义函数 ButtonCallback 以捕获按钮事件。

I do:

我愿意:

cvCreateButton("button6", callbackButton2, pointer, CV_PUSH_BUTTON, 0);

to declare the button and

声明按钮和

void callbackButton2(int state, void *pointer){

    printf("ok");

}

but it doesn't work.

但它不起作用。

I don't know the meaning of the third parameter "void* userdata".

我不知道第三个参数“void * userdata”的含义。

Can someone help me, please?

有人能帮助我吗?

Thanks.

谢谢。

回答by karlphillip

We still don't know what doesn't workmeans to you, but I'll provide some information on how to use the callbackand what userdatais.

我们仍然不知道有什么不工作对你意味着什么,但我会提供关于如何使用一些信息的回调,什么用户数据是。

As the signature suggests, void* userdatais a parameter that you can use to send/receive data to the callback. This is purely optional, so if you don't have any use for it just pass NULL.

正如签名所暗示的那样,void* userdata是一个可用于向回调发送/接收数据的参数。这纯粹是可选的,所以如果你对它没有任何用处,只需 pass NULL

On the example below I'll be using userdatato retrieve data from the callback. You might have noticed that the callback receives a stateinformation from OpenCV. I'm interested in storing this value and making it available to main().

在下面的示例中,我将使用userdata从回调中检索数据。您可能已经注意到回调state从 OpenCV接收信息。我有兴趣存储此值并将其提供给main().

For this purpose, I define a custom data type and declare a variable of this type on main(). The custom type has an intmember to store the statereceived by our callback and a mutex that we are going to use to protect the custom type from being read/written simultaneously by the 2 threads (callback and main()).

为此,我定义了一个自定义数据类型并在 上声明了一个这种类型的变量main()。自定义类型有一个int成员来存储state我们的回调接收到的信息和一个互斥锁,我们将使用它来保护自定义类型不被 2 个线程(回调和main())同时读/写。

#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <pthread.h>
#include <string.h>

using namespace cv;

typedef struct custom_data
{
    int state;
    pthread_mutex_t mtx;
} custom_data_t;


void my_button_cb(int state, void* userdata)
{
    std::cout << "@my_button_cb" << std::endl;   

    // convert userdata to the right type
    custom_data_t* ptr = (custom_data_t*)userdata;
    if (!ptr)
    {
        std::cout << "@my_button_cb userdata is empty" << std::endl;
        return;
    }

    // lock mutex to protect data from being modified by the
    // main() thread
    pthread_mutex_lock(&ptr->mtx);

    ptr->state = state;

    // unlock mutex
    pthread_mutex_unlock(&ptr->mtx);
}    

int main()
{
    // declare and initialize our userdata
    custom_data_t my_data = { 0 };

    createButton("dummy_button", my_button_cb, &my_data, CV_PUSH_BUTTON, 0);

    // For testing purposes, go ahead and click the button to activate
    // our callback.

    // waiting for key press <enter> on the console to continue the execution
    getchar(); 

    // At this point the button exists, and our callback was called 
    // (if you clicked the button). In a real application, the button is 
    // probably going to be pressed again, and again, so we need to protect 
    // our data from being modified while we are accessing it. 
    pthread_mutex_lock(&my_data.mtx);

    std::cout << "The state retrieved by the callback is: " << my_data.state << std::endl;

    // unlock mutex    
    pthread_mutex_unlock(&my_data.mtx);

    return 0;
}

回答by Sander De Dycker

The reason it didn't work, is because the cvCreateButtonimplementation had a bug which caused button clicks to be ignored :

它不起作用的原因是因为cvCreateButton实现有一个错误,导致按钮点击被忽略:

https://code.ros.org/trac/opencv/ticket/786

https://code.ros.org/trac/opencv/ticket/786

This is now fixed in trunk, so a button click should now be working fine again if you use trunk. It should eventually make its way into an official release.

这现在已在主干中修复,因此如果您使用主干,单击按钮现在应该可以正常工作了。它最终应该进入正式版本。