How to change the numeric label of an OpenCV Trackbar to the actual value passed to GaussianBlur?

I have a trackbar with a domain from 0 (always zero) to TICKS (see my code below). This domain is mapped by PosToActual to produce a range from a to b.

When users slide the trackbar, I want the shown label to be the value of range rather than the value of domain. How to do so?

enter image description here

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

using namespace std;
using namespace cv;

const string wndOriginal = "Original";
const string wndBlurred = "Blurred";
const string tbKSize = "KSize";

const string path = "../resources/gollum.jpg";

Mat original = imread(path);
Mat blurred;

const int TICKS = 30;
int a = 3;
int b = 31;

template <typename T>
T PosToActual(T min, T max, int pos)
{
    return (T)(min + (double)(max - min) * pos / TICKS);
}

// Refresh is intentionally extracted from onKSize
// so it can be invoked  by  other trackbars in my  real scenario.
void Refresh()
{
    int pos = getTrackbarPos(tbKSize, wndBlurred);

    int localKSize = PosToActual<int>(a, b, pos);
    if (localKSize % 2 != 0)
        GaussianBlur(original, blurred, cv::Size(localKSize, localKSize), 3, 0);

    imshow(wndBlurred, blurred);
}

void onKSize(int, void *)
{
    Refresh();
}

int main()
{
    namedWindow(wndOriginal, WINDOW_AUTOSIZE);
    namedWindow(wndBlurred, WINDOW_AUTOSIZE);

    createTrackbar(tbKSize, wndBlurred, &a, TICKS, onKSize);

    Refresh();
    imshow(wndOriginal, original);

    waitKey();
    return 0;
}

impossible.

OpenCV’s GUI module is designed to be simple and have clear limits. you require more than it’s designed to do.

you need a GUI library.

best workaround while staying within OpenCV: putText whatever messages onto the picture you show.

1 Like

Only for sharing. Thank you!

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

using namespace std;
using namespace cv;

const string wndOriginal = "Original";
const string wndBlurred = "Blurred";
const string tbKSize = "KSize";

const string path = "../resources/gollum.jpg";

Mat original = imread(path);
Mat blurred;

const int TICKS = 10;
const int MIN = 1;
const int MAX = MIN + 2 * TICKS; // always odd

// Refresh is intentionally extracted from onKSize
// so it can be invoked  by  other trackbars in my  real scenario.
void Refresh()
{
    int pos = getTrackbarPos(tbKSize, wndBlurred);

    int kSize = MIN + (MAX - MIN) * pos / TICKS;

    GaussianBlur(original, blurred, cv::Size(kSize, kSize), 3, 0);
    putText(blurred, "KSize: " + to_string(kSize), Point(0, 25), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
    imshow(wndBlurred, blurred);
}

void onKSize(int, void *)
{
    Refresh();
}

int main()
{
    namedWindow(wndOriginal, WINDOW_AUTOSIZE);
    namedWindow(wndBlurred, WINDOW_GUI_EXPANDED);

    createTrackbar(tbKSize, wndBlurred, nullptr, TICKS, onKSize);

    Refresh();
    imshow(wndOriginal, original);

    waitKey();

    return 0;
}