Trackbars to isolate a color in an image are not working as expected

This code is suppose to isolate a particular color in an image.

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

const int max_value_H = 360 / 2;
const int max_value = 255;
const String window_detection_name = "Object Detection";
int low_H = 0, low_S = 0, low_V = 0;
int high_H = max_value_H, high_S = max_value, high_V = max_value;
static void on_low_H_thresh_trackbar(int, void*)
{
    low_H = min(high_H - 1, low_H);
    setTrackbarPos("Low H", window_detection_name, low_H);
}
static void on_high_H_thresh_trackbar(int, void*)
{
    high_H = max(high_H, low_H + 1);
    setTrackbarPos("High H", window_detection_name, high_H);
}
static void on_low_S_thresh_trackbar(int, void*)
{
    low_S = min(high_S - 1, low_S);
    setTrackbarPos("Low S", window_detection_name, low_S);
}
static void on_high_S_thresh_trackbar(int, void*)
{
    high_S = max(high_S, low_S + 1);
    setTrackbarPos("High S", window_detection_name, high_S);
}
static void on_low_V_thresh_trackbar(int, void*)
{
    low_V = min(high_V - 1, low_V);
    setTrackbarPos("Low V", window_detection_name, low_V);
}
static void on_high_V_thresh_trackbar(int, void*)
{
    high_V = max(high_V, low_V + 1);
    setTrackbarPos("High V", window_detection_name, high_V);
}
static void donothing(int, void*){ }
int main()
{
    Mat result, frame, frame_HSV;
    Mat frame_threshold;
    frame = imread("D:/mmm.bmp");
    namedWindow(window_detection_name);
    createTrackbar("Low H", window_detection_name, &low_H, max_value_H, on_low_H_thresh_trackbar);
    createTrackbar("High H", window_detection_name, &high_H, max_value_H, on_high_H_thresh_trackbar);
    createTrackbar("Low S", window_detection_name, &low_S, max_value, on_low_S_thresh_trackbar);
    createTrackbar("High S", window_detection_name, &high_S, max_value, on_high_S_thresh_trackbar);
    createTrackbar("Low V", window_detection_name, &low_V, max_value, on_low_V_thresh_trackbar);
    createTrackbar("High V", window_detection_name, &high_V, max_value, on_high_V_thresh_trackbar);
    while (true) {
        cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
        inRange(frame_HSV, Scalar(low_H, low_S, low_V), Scalar(high_H, high_S, high_V), frame_threshold);
        bitwise_and(frame, frame, result, frame_threshold);
        imshow(window_detection_name, result);
        waitKey(1);
    }
    return 0;
}

However it does not change the image, no matter how much I move the trackbars.
If I change the imshow(window_detection_name, result); to imshow(window_detection_name, frame_threshold); it works more or less. But I want the actual image, not the black and white mask.

That means this bitwise operator is not working properly.

bitwise_and(frame, frame, result, frame_threshold);

If I remove all the trackbars and update the parameters manually in inrange function, everything works fine. Thus the problem is formed when I use trackbars with bitwise_and.

I picked most of the code from official tutorial.
https://docs.opencv.org/3.4/da/d97/tutorial_threshold_inRange.html

I have tried using the getTrackbarPos. It has the exact same issue.

#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;

const int max_value_H = 360 / 2;
const int max_value = 255;
const String window_detection_name = "Object Detection";
int low_H = 0, low_S = 0, low_V = 0;
int high_H = max_value_H, high_S = max_value, high_V = max_value;
void donothing(int, void*){}
int main()
{
    Mat result, frame, frame_HSV;
    Mat frame_threshold;
    frame = imread("D:/mmm.bmp");
    namedWindow(window_detection_name);
    createTrackbar("Low H", window_detection_name, &low_H, max_value_H, donothing);
    createTrackbar("High H", window_detection_name, &high_H, max_value_H, donothing);
    createTrackbar("Low S", window_detection_name, &low_S, max_value, donothing);
    createTrackbar("High S", window_detection_name, &high_S, max_value, donothing);
    createTrackbar("Low V", window_detection_name, &low_V, max_value, donothing);
    createTrackbar("High V", window_detection_name, &high_V, max_value, donothing);
    while (true) {
        cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
        low_H =  getTrackbarPos("Low H", window_detection_name);
        low_S = getTrackbarPos("Low S", window_detection_name);
        low_V = getTrackbarPos("Low V", window_detection_name);
        high_H = getTrackbarPos("High H", window_detection_name);
        high_S = getTrackbarPos("High S", window_detection_name);
        high_V = getTrackbarPos("High V", window_detection_name);
        inRange(frame_HSV, Scalar(low_H, low_S, low_V), Scalar(high_H, high_S, high_V), frame_threshold);
        bitwise_and(frame, frame,  result, frame_threshold);
        imshow(window_detection_name, result);
        waitKey(1);
    }
    return 0;
}

Any help is appreciated.

since you use waitKey(1) anyway, you can remove all the callbacks.

why do you set in the callback? that could constitute a feedback loop.

createTrackbar with a pointer argument has been deprecated. while that still works, you can keep the code as is. in the future, the recommended way is to create with nullptr, and then call getTrackbarPos wherever you need the current value.

Perhaps update it in the tutorial for thresholding? Sorry cant post links in reply. Link is in the post.

why do you set in the callback? that could constitute a feedback loop.

Well, I am following the official tutorial.

oh, right, you have some calculations in those callbacks. I guess that’s a sensible thing to do then.

sorry, I’m not set up to replicate C++ code right now. the “equivalent” python code might exhibit the same issue you are asking about, or it might not.

perhaps someone else will have a look.