opencv / opencv

Open Source Computer Vision Library
https://opencv.org
Apache License 2.0
76.67k stars 55.65k forks source link

Can not set trackBarPos, if two trackbar in the same window #25537

Closed RichardZeenChen closed 1 month ago

RichardZeenChen commented 1 month ago

System Information

OpenCV version: 4.8.0 Operating System / Platform: Win 10 Compiler & compiler version: vs2019 vc16

Detailed description

When you uncomment code setTrackbarPos("kernel", "dst", 3);, the program will report an error during runtime


#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void gaussianBlurCall(int pos, void* userdata) {
    Mat* img = static_cast<Mat*>(userdata);
    int k = getTrackbarPos("kernel", "dst");
    if (k % 2 == 0) {
        k = k - 1;
    }
    int sigma = getTrackbarPos("sigma", "dst");
    Mat dst;
    GaussianBlur(*img, dst, Size(k, k), sigma);
    imshow("dst", dst);
}

int main(int argc, char** argv)
{
    Mat src = imread("blur.tif");
    namedWindow("dst", WINDOW_NORMAL);

    createTrackbar("kernel", "dst", nullptr, 21, gaussianBlurCall, &src);
    setTrackbarMin("kernel", "dst", 1);
    //setTrackbarPos("kernel", "dst", 3);

    createTrackbar("sigma", "dst", nullptr, 10, gaussianBlurCall, &src);
    setTrackbarMin("sigma", "dst", 1);
    //setTrackbarPos("sigma", "dst", 7);
    waitKey();

    return 0;
}

### Steps to reproduce

```cpp
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void gaussianBlurCall(int pos, void* userdata) {
    Mat* img = static_cast<Mat*>(userdata);
    int k = getTrackbarPos("kernel", "dst");
    if (k % 2 == 0) {
        k = k - 1;
    }
    int sigma = getTrackbarPos("sigma", "dst");
    Mat dst;
    GaussianBlur(*img, dst, Size(k, k), sigma);
    imshow("dst", dst);
}

int main(int argc, char** argv)
{
    Mat src = imread("blur.tif");
    namedWindow("dst", WINDOW_NORMAL);

    createTrackbar("kernel", "dst", nullptr, 21, gaussianBlurCall, &src);
    setTrackbarMin("kernel", "dst", 1);
    //setTrackbarPos("kernel", "dst", 3); //you can not uncomment this code

    createTrackbar("sigma", "dst", nullptr, 10, gaussianBlurCall, &src);
    setTrackbarMin("sigma", "dst", 1);
    //setTrackbarPos("sigma", "dst", 7); //you can not uncomment this code
    waitKey();

    return 0;
}

### Issue submission checklist

- [X] I report the issue, it's not a question
- [X] I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- [ ] I updated to the latest OpenCV version and the issue is still there
- [ ] There is reproducer code and related data files (videos, images, onnx, etc)
LaurentBerger commented 1 month ago

There is no exception if img is not empty.

Mat src = imread("blur.tif");
if (src.empty())
{
    cout << "Check image file path";
    return 0;
}

Did you checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution? NO

RichardZeenChen commented 1 month ago

I am sure that src is not empty. When I comment code setTrackbarPos("kernel", "dst", 3); and setTrackbarPos("sigma", "dst", 7);, the program will run successfully. However, I can not set trackbar pos, when two or more trackbar in the same window.

LaurentBerger commented 1 month ago

Try this sample https://docs.opencv.org/4.x/d3/dc1/tutorial_basic_linear_transform.html https://github.com/opencv/opencv/blob/4.x/samples/cpp/tutorial_code/ImgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.cpp

asmorkalov commented 1 month ago

@RichardZeenChen Does the sample work well for you?

RichardZeenChen commented 1 month ago

The program work well, only if you do not set the trackbarPos. Can not set trackBarPos, if two trackbar in the same window. Hower, the code work well if only one trackbar in the window.

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void gaussianBlurCall(int pos, void* userdata) {
    Mat* img = static_cast<Mat*>(userdata);
    int k = getTrackbarPos("kernel", "dst");
    if (k % 2 == 0) {
        k = k - 1;
    }
    int sigma = getTrackbarPos("sigma", "dst");
    Mat dst;
    GaussianBlur(*img, dst, Size(k, k), sigma);
    imshow("dst", dst);
}

int main(int argc, char** argv)
{
    Mat src = imread("blur.tif");
    namedWindow("dst", WINDOW_NORMAL);

    createTrackbar("kernel", "dst", nullptr, 21, gaussianBlurCall, &src);
    setTrackbarMin("kernel", "dst", 1);
    setTrackbarPos("kernel", "dst", 3); //can not set pos

    createTrackbar("sigma", "dst", nullptr, 10, gaussianBlurCall, &src);
    setTrackbarMin("sigma", "dst", 1);
    setTrackbarPos("sigma", "dst", 7); //can not set pos
    waitKey();

    return 0;
}
anshulchou-123 commented 1 month ago

@RichardZeenChen when we call the first setTrackbarPos("kernel", "dst", 3); interanlly it call the gaussianBlurCall which tries to get the value of "sigma" trackbar even before we created it using createTrackbar("sigma", "dst", nullptr, 10, gaussianBlurCall, &src); hence causing it to crash.

alexlyulkov commented 1 month ago

Agree with @anshulchou-123. The provided code runs getTrackbarPos("sigma"...) before createTrackbar("sigma"...) which causes the crash. The code works fine if you run setTrackbarPos after creating both the trackbars.