简体   繁体   中英

How to use cv::createButton prototype in OpenCV

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

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.

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".

Can someone help me, please?

Thanks.

We still don't know what doesn't work means to you, but I'll provide some information on how to use the callback and what userdata is.

As the signature suggests, void* userdata is 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 .

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

For this purpose, I define a custom data type and declare a variable of this type on main() . The custom type has an int member to store the state received 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() ).

#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;
}

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM