Is it possible to also update other windows when a trackbar on a certain window is changed?

Assume I have two windows: Blurring window and Cannying window.

Blurring window has one trackbar to change the kernel size.
Cannying window depends on the blurred Mat object.
If I change the trackbar on the Blurring window, the blurred Mat object changes, as a result it must also change the image displayed on Cannying window.

Is it possible to orchestrate these two windows?

yes.

program sketch:

import cv2 as cv

blur_radius = 0

def draw():
    # option:
    #blur_radius = cv.getTrackbarPos("blur_strength", "blur")
    # then you won't need the global `blur_radius` and assignment in the callback below

    blur = ... do blur using blur_radius ...
    cv.imshow("blur", blur)
    ... do canny ...
    ... imshow the canny result ...
    # absolutely NO waitKey here

def trackbar_callback(pos): # and maybe userdata, see docs
    # using getTrackbarPos (above), these two lines need to be removed:
    global blur_radius
    blur_radius = pos
    # always:
    draw()

if __name__ == '__main__':
    cv.namedWindow("blur")
    cv.namedWindow("canny")

    cv.createTrackbar("blur_strength", "blur", ..., onChange=trackbar_callback)

    draw() # first call to show *something*

    # main loop does nothing but waitKey
    # waitKey does all event and callback processing
    while True:
        key = cv.waitKey(1000)
        if key == -1:
            continue # it was a timeout
        elif key in (13, 27): # ENTER, ESC
            break
        else:
            print("key code", key)

cv.destroyAllWindows()

for this simple case, you could pass the trackbar position into the draw() call… but that’s not extensible.

when you add more control elements, the state of those values needs to be kept somewhere. if you don’t, you would have to query the positions of all trackbars in the draw() call (see the “option”).

I am not familiar with python but c++. Now I am trying to understand this code. :slight_smile:
Thank you very much.

By the way, please increase the width of the HTML element containing this posts. The code box is too narrow, as a result I have to scroll horizontally. It is unpleasant.
Attempting to enlarge the width with CTRL+Mouse Scroll does not help because the font size becomes too gigantic.

Only for sharing if you want to see the code in C++.

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
const string wndInput = "Input";
const string wndGrayed = "Grayed";
const string wndBlurred = "Blurred";
const string wndCannied = "Cannied";
const string tbKSize = "KSize";
const string tbThd1 = "Threshold1";
const string tbThd2 = "Threshold2";
const int KSIZE_MAX = 200;
const int THD1_MAX = 200;
const int THD2_MAX = 200;
const string path = "../resources/test.png";
Mat input = imread(path);
Mat grayed;
Mat blurred;
Mat cannied;
void Refresh()
{
    int kSize = getTrackbarPos(tbKSize, wndBlurred);
    int thd1 = getTrackbarPos(tbThd1, wndCannied);
    int thd2 = getTrackbarPos(tbThd2, wndCannied);
    if (kSize % 2 != 0)
        // size must be odd integers.
        GaussianBlur(input, blurred, cv::Size(kSize, kSize), 3, 0);
    Canny(blurred, cannied, thd1, thd2);
    imshow(wndBlurred, blurred);
    imshow(wndCannied, cannied);
}
void onThd1(int, void *)
{
    Refresh();
}
void onThd2(int, void *)
{
    Refresh();
}
void onKSize(int, void *)
{
    Refresh();
}
int main()
{
    namedWindow(wndInput);
    namedWindow(wndGrayed);
    namedWindow(wndBlurred);
    namedWindow(wndCannied);
    cvtColor(input, grayed, cv::COLOR_BGR2GRAY);
    int kSize = 71;
    int thd1 = 50;
    int thd2 = 100;
    createTrackbar(tbKSize, wndBlurred, &kSize, KSIZE_MAX, onKSize);
    createTrackbar(tbThd1, wndCannied, &thd1, THD1_MAX, onThd1);
    createTrackbar(tbThd2, wndCannied, &thd2, THD2_MAX, onThd2);
    Refresh();
    imshow(wndInput, input);
    imshow(wndGrayed, grayed);
    waitKey();
    cout << "===== END =====" << endl;
    return 0;
}
1 Like