Problem displaying rectangle in a callBack function

asked 2019-12-02 04:32:17 -0500

updated 2019-12-02 08:16:50 -0500

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

edit retag flag offensive close merge delete

Comments

I can only do in Python 3.

supra56 gravatar imagesupra56 ( 2019-12-02 05:09:32 -0500 )edit

Thank you, I fixed my problem, but there is still a weird behavior of the code that I do not understand(Edit 1).

Kitnos gravatar imageKitnos ( 2019-12-02 08:18:43 -0500 )edit

You need to draw another rectangle on right side. On left side you specified coordinate of x y. That is x = 0 and y = 0. And on right side is x = 75 and y = 0.So move mouse any where on left side. If the mouse in middle, I would say if x < 50 < x < 0. Then use left mouse click to save it. This is how I do hand gesture.

supra56 gravatar imagesupra56 ( 2019-12-02 10:02:01 -0500 )edit