Ask Your Question

Revision history [back]

Problem displaying rectangle in a callBack function

Hello,

I am trying to create a window with Opencv that display a video stream and above a rectangle (gray rectangle), where the user can create images of type 1 or type 2, when he click on the gray rectangle.

When the user click "Save image type 1!" a red rectangle (First image) appear and disappear (works fine). But the rectangle "Save image type 2!" display the red rectangle (second image) with weird dimension and I can't figure out how to fix it. I think the dimensions of the button2 are good and I don't know why it's not working.

image description

image description

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;


Mat3b canvas;
Mat3b canvas2;
string buttonText("Save image type 1!");
string buttonText2("Save image type 2!");
string winName = "DB creation";
Mat img1;
Rect button;
Rect button2;
int count_image1 = 0;
int count_image2 = 0;


void callBackFunc(int event, int x, int y, int flags, void* userdata)
{
    if (event == EVENT_LBUTTONDOWN)
    {
        if (button.contains(Point(x, y)))
        {
            cout << "Save image of type 1" << endl;
            rectangle(canvas(button), button, Scalar(0, 0, 255), 2);
            imwrite("image_type1_"   + std::to_string(count_image1)  + ".png", img1);
            count_image1++;
        }
        if (button2.contains(Point(x, y)))
        {
            cout << "Save image of type 2" << endl;
            rectangle(canvas(button2), button2, Scalar(0, 0, 255), 2);
            imwrite("image_type2_" + std::to_string(count_image2) + ".png", img1);
            count_image2++;
        }
    }
    if (event == EVENT_LBUTTONUP)
    {
        if (button.contains(Point(x, y)))
        rectangle(canvas, button, Scalar(200, 200, 200), 2);
        if (button2.contains(Point(x, y)))
            rectangle(canvas, button2, Scalar(200, 200, 200), 2);   
    }

    imshow(winName, canvas);
    waitKey(1);
}

int main()
{
    Mat img;
    VideoCapture cap(0); //caméra par défault

    for (;;)
    {
        cap >> img; // get a new frame from camera      
        while (img.empty()) {
            std::cout << "Frame vide" << std::endl;
            continue;
        }
        img1 = img;
        //cout << "Resolution" << img.size() << endl;        

        // Your button
        button =  Rect(0, 0, img.cols/2, 50);
        button2 = Rect(img.cols / 2, 0, img.cols/2, 50);

        // The canvas
        canvas = Mat3b(img.rows + button.height, img.cols, Vec3b(0, 0, 0));

        // Draw the button
        canvas(button) = Vec3b(200, 200, 200);
        putText(canvas(button), buttonText, Point(button.width*0.35, button.height*0.7), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 0));

        canvas(button2) = Vec3b(200, 200, 200);
        putText(canvas(button2), buttonText2, Point(button2.width*0.35, button2.height*0.7), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 0));

        // Draw the image
        img.copyTo(canvas(Rect(0, button.height, img.cols, img.rows)));
        //img.copyTo(canvas(Rect(0, button2.height, img.cols, img.rows)));

        // Setup callback function
        namedWindow(winName);
        setMouseCallback(winName, callBackFunc);

        imshow(winName, canvas);
        waitKey(1);
    }

    return 0;
}

I need your help and thank you

Problem displaying rectangle in a callBack function

Hello,

I am trying to create a window with Opencv that display a video stream and above a rectangle (gray rectangle), where the user can create images of type 1 or type 2, when he click on the gray rectangle.

When the user click "Save image type 1!" a red rectangle (First image) appear and disappear (works fine). But the rectangle "Save image type 2!" display the red rectangle (second image) with weird dimension and I can't figure out how to fix it. I think the dimensions of the button2 are good and I don't know why it's not working.

image description

image description

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;


Mat3b canvas;
Mat3b canvas2;
string buttonText("Save image type 1!");
string buttonText2("Save image type 2!");
string winName = "DB creation";
Mat img1;
Rect button;
Rect button2;
int count_image1 = 0;
int count_image2 = 0;


void callBackFunc(int event, int x, int y, int flags, void* userdata)
{
    if (event == EVENT_LBUTTONDOWN)
    {
        if (button.contains(Point(x, y)))
        {
            cout << "Save image of type 1" << endl;
            rectangle(canvas(button), button, Scalar(0, 0, 255), 2);
            imwrite("image_type1_"   + std::to_string(count_image1)  + ".png", img1);
            count_image1++;
        }
        if (button2.contains(Point(x, y)))
        {
            cout << "Save image of type 2" << endl;
            rectangle(canvas(button2), button2, Scalar(0, 0, 255), 2);
            imwrite("image_type2_" + std::to_string(count_image2) + ".png", img1);
            count_image2++;
        }
    }
    if (event == EVENT_LBUTTONUP)
    {
        if (button.contains(Point(x, y)))
        rectangle(canvas, button, Scalar(200, 200, 200), 2);
        if (button2.contains(Point(x, y)))
            rectangle(canvas, button2, Scalar(200, 200, 200), 2);   
    }

    imshow(winName, canvas);
    waitKey(1);
}

int main()
{
    Mat img;
    VideoCapture cap(0); //caméra par défault

    for (;;)
    {
        cap >> img; // get a new frame from camera      
        while (img.empty()) {
            std::cout << "Frame vide" << std::endl;
            continue;
        }
        img1 = img;
        //cout << "Resolution" << img.size() << endl;        

        // Your button
        button =  Rect(0, 0, img.cols/2, 50);
        button2 = Rect(img.cols / 2, 0, img.cols/2, 50);

        // The canvas
        canvas = Mat3b(img.rows + button.height, img.cols, Vec3b(0, 0, 0));

        // Draw the button
        canvas(button) = Vec3b(200, 200, 200);
        putText(canvas(button), buttonText, Point(button.width*0.35, button.height*0.7), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 0));

        canvas(button2) = Vec3b(200, 200, 200);
        putText(canvas(button2), buttonText2, Point(button2.width*0.35, button2.height*0.7), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 0));

        // Draw the image
        img.copyTo(canvas(Rect(0, button.height, img.cols, img.rows)));
        //img.copyTo(canvas(Rect(0, button2.height, img.cols, img.rows)));

        // Setup callback function
        namedWindow(winName);
        setMouseCallback(winName, callBackFunc);

        imshow(winName, canvas);
        waitKey(1);
    }

    return 0;
}

Edit 1 :

I fixed my problem by editing

if (button.contains(Point(x, y)))
        rectangle(canvas, button, Scalar(0, 0, 255), 2);

 if (button2.contains(Point(x, y)))
 rectangle(canvas, button2, Scalar(0, 0, 255), 2);

But I can't figure out why the event EVENT_LBUTTONUP is triggered when I clicked the second button and not the first.

I need your help and thank you