7

Is it possible to create some sliders and make one callback for all of them?

I am creating a window, in which i would like to set about 10 parameters. It would be much better to have 1 callback function for all of them instead of 10 functions.

currently i create trackbar like this:

cvCreateTrackbar("Var1","Window",&global_var1, 250, changing_var1);
cvCreateTrackbar("Var2","Window",&global_var2, 250, changing_var2);

and then

void changing_var1(int pos) {
    global_var1 = pos;
}    

void changing_var2(int pos) {
    global_var2 = pos;
}

Is it possible to create one callback that would be albe to change all parameters according to which parameter i want to change?

ASR
  • 1,801
  • 5
  • 25
  • 33
user1762979
  • 71
  • 1
  • 4
  • 1
    there is no need for assigning global variables with values. the function already put the value in global_var1, that is why it takes pointer. – shanif Apr 03 '13 at 14:14

2 Answers2

4

Yes you should be able to do this (at least with the C++ interface). You will want to utilize the optional userData field. Below is a small example of how you can accomplish this:

#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

struct ColorThresholdData
{
    int redHigh;
    int redLow;
};

enum ColorThresholdType
{
    RED_HIGH,
    RED_LOW
};

void fooCallback(int value, void* colorThreshold);

struct ColorThresholdData data;
int main(int argc, char** argv)
{
    ...
    createTrackbar("red high", windowName, NULL, 255, fooCallback, new ColorThresholdType(RED_HIGH));
    createTrackbar("red low", windowName, NULL, 255, fooCallback, new ColorThresholdType(RED_LOW));
    ...
}

void fooCallback(int value, void* colorThreshold)
{
    ColorThresholdType* ct = reinterpret_cast<ColorThresholdType*>(colorThreshold);
    switch(*ct)
    {
    case RED_HIGH:
        cout << "Got RED_HIGH value" << endl;
        data.redHigh = value;
        break;
    case RED_LOW:
        cout << "Got RED_LOW value" << endl;
        data.redLow = value;
        break;
    }
}

Hope that is what you were looking for :)

mevatron
  • 13,911
  • 4
  • 55
  • 72
0

I'm testing using one callback for three trackbars, without using userData field. It seems to work.

Look at my code (the parts related to trackbars, but enough copy-paste-compile, so others can easily test it):

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;

// global variables for trackbars: initial and max positions
const int alpha_sl_max = 1000;
int alpha_sl = 500;
const int beta_sl_max = 500;
int beta_sl = 250;
const int gamma_sl_max = 1000;
int gamma_sl = 500;
double alpha, beta, gamma; // I will convert slider value to something useful

// Control window (to show trackbars and text) and text options
Mat img_ctrl; // blank image where I will print the text
int ctrl_w = 640, ctrl_h = 150;
int font = FONT_HERSHEY_SIMPLEX;
int txt_size = 1;
Scalar txt_color = (0, 0, 255);
int txt_thick = 2;
int linetype = LINE_AA;
#define TXT_CONFIG font, txt_size, txt_color, txt_thick, linetype

// same callback from three trackbars
static void on_trackbar(int, void*) {
    alpha = (double)alpha_sl / 500.0;
    beta = (double)beta_sl - 250;
    gamma = pow(((double)gamma_sl / 500.0), 4);
    img_ctrl = Mat::zeros(ctrl_h, ctrl_w, CV_8U);

    putText(img_ctrl, std::to_string(alpha), Point(10, 30), TXT_CONFIG);
    putText(img_ctrl, std::to_string(beta), Point(10, 60), TXT_CONFIG);
    putText(img_ctrl, std::to_string(gamma), Point(10, 90), TXT_CONFIG);
    imshow("Controls", img_ctrl);
}

int main() {
    // Create trackbars and window
    namedWindow("Controls"); // Create Window
    resizeWindow("Controls", ctrl_w, ctrl_h);
    createTrackbar("Alpha", "Controls", &alpha_sl, alpha_sl_max, on_trackbar);
    createTrackbar("Beta", "Controls", &beta_sl, beta_sl_max, on_trackbar);
    createTrackbar("Gamma", "Controls", &gamma_sl, gamma_sl_max, on_trackbar);

    // call first time, to show image (view callback function)
    on_trackbar(alpha_sl, 0);

    waitKey();
    return 0;
}
Gustavo Kaneto
  • 643
  • 7
  • 17