9

I am working on a game-project using OpenCV. Now I have to make a simple GUI: a window with one button, using HighGui only.

I'm not sure but I think I'm supposed to use something like this:

cvNamedWindow( "NameWindow" , CV_WINDOW_AUTOSIZE);

Any help is much appreciated.

Miki
  • 40,887
  • 13
  • 123
  • 202
Koci Ogon
  • 103
  • 1
  • 1
  • 5
  • Are you using OpenCV with some GUI library like Qt? Or you need to do with HighGui only? I saw you mentioned "OpenCV only", but "OpenCV only" is not really meant to do more than simple debugging. Programming language? – Miki Nov 26 '15 at 11:45
  • Yes, with HighGui only. I just need a window with a few buttons, that's all. :) – Koci Ogon Nov 26 '15 at 11:50
  • Programming language? – Miki Nov 26 '15 at 11:55
  • Miki, do You think it's possible to display my every return value in my GUI, using the HighGui? For example... Is it possible to make a button which name can be changed when I press another button? I hope You understand what I mean. – Koci Ogon Nov 29 '15 at 16:15
  • So you want to create a label (or a text area) which you can refresh with some new text? Yes, you shouldn't (like for the button) but you can do it. – Miki Nov 29 '15 at 17:26
  • Yes, that's exactly what I want to create. I thought I could try with the QT Creator, but it doesn't work for me for some reason. I'll focus on the "unreal" buttons instead. – Koci Ogon Nov 29 '15 at 17:32
  • I **strongly** recommend to make Qt work, it's not that hard and you win a lot of graphics stuff for free. – Miki Nov 29 '15 at 17:33
  • Qt still doesn't work for me, so I am using HighGui. I will ask my profesor what to do with the Qt. Any idea of how to make two working buttons? :) – Koci Ogon Nov 30 '15 at 20:22
  • All right... I've just found a solution! 2 buttons work great! :) – Koci Ogon Nov 30 '15 at 20:54

4 Answers4

29

OpenCV does not provide a button, but you can easily use a colored rectangle, and check if the clicked point on the image is inside this rectangle.

Remember that OpenCV HighGui is very simple and is meant only for debugging purposes. You may want to use a full featured graphic library as Qt, or similar.

However, this is a small example that shows a (green) image, and a button on top:

enter image description here

Clicking the button will print "Clicked" on stdout:

enter image description here

Code:

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


Mat3b canvas;
string buttonText("Click me!");
string winName = "My cool GUI v0.1";

Rect button;


void callBackFunc(int event, int x, int y, int flags, void* userdata)
{
    if (event == EVENT_LBUTTONDOWN)
    {
        if (button.contains(Point(x, y)))
        {
            cout << "Clicked!" << endl;
            rectangle(canvas(button), button, Scalar(0,0,255), 2);
        }
    }
    if (event == EVENT_LBUTTONUP)
    {
        rectangle(canvas, button, Scalar(200, 200, 200), 2);
    }

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

int main() 
{
    // An image
    Mat3b img(300, 300, Vec3b(0, 255, 0));

    // Your button
    button = Rect(0,0,img.cols, 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));

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

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

    imshow(winName, canvas);
    waitKey();

    return 0;
}
Miki
  • 40,887
  • 13
  • 123
  • 202
4

You can now create buttons and other useful tools on OpenCV windows. The page below shows a couple of useful examples.

https://docs.opencv.org/master/dc/d46/group__highgui__qt.html

The gist of it is:

#include <opencv2/highgui.hpp>
void myButtonName_callback(int state, void*userData) {
    // do something
    printf("Button pressed\r\n");
}
createButton("myButtonName",myButtonName_callback,NULL,CV_PUSH_BUTTON,1);
VoteCoffee
  • 4,692
  • 1
  • 41
  • 44
  • 1
    Know about python wrapper? – dpetrini Dec 16 '20 at 18:48
  • 1
    Note: `createButton()` requires OpenCV builded with Qt support. – Jeffy Dec 02 '21 at 08:16
  • Thanks.. I was using tkinter but it was really shitty with exiting gracefully. – ArduinoBen Apr 19 '22 at 15:26
  • @dpetrini You need to have QT setup in and in your environment variables. Which python OpenCV package do you have installed? If you're just asking for code, try this: https://stackoverflow.com/a/64744175/848419 To set up QT support for python: https://doc.qt.io/qtforpython/quickstart.html – VoteCoffee Apr 25 '22 at 12:10
0

you are aware that openCV is not a GUI library, but an image processing lib?

it ships with highgui: http://docs.opencv.org/2.4/modules/highgui/doc/highgui.html

for those cases where you really have no other options, but need to create a window for displaying stuff.

While OpenCV was designed for use in full-scale applications and can be used within functionally rich UI frameworks (such as Qt*, WinForms*, or Cocoa*) or without any UI at all, sometimes there it is required to try functionality quickly and visualize the results. This is what the HighGUI module has been designed for.

see OpenCV and creating GUIs

edit: "this doesn't answer the question": -> more help..

you can't.

or that is, if you know your underlying window manager, you can. i.e. if you'r on windows, you could get the window handle, and dynamically add more controls.. if not, you need to know what platform you'r on, and how to do it in that.

I wouldn't dare to try and put this in a simple answer

Community
  • 1
  • 1
Henrik
  • 2,180
  • 16
  • 29
  • 1
    This doesn't provide an answer to the question. – Miki Nov 26 '15 at 11:56
  • ps. I'd say using winAPI or other libs would be cheating, since the question clearly states "using openCV only" – Henrik Nov 26 '15 at 12:10
  • 2
    Check my answer, you can do a button with HighGui only. Yeah, not a _cool nice looking_ button (you need Qt or similar for that), but it works. – Miki Nov 26 '15 at 12:28
  • 1
    @Miki while that is in fact not a button, but a clickable area in the image,with a callback, it solves the problem, and for all practical purposes is a button. I love it :) – Henrik Nov 26 '15 at 13:17
0

@Miki, why I cannot use my buttons alternately? How to fix it? I mean I want to use them at the same time.

EDIT: I fixed it myself. No need of help. :)

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


Mat3b canvas;
string buttonText("Nacisnij guzik!");
string buttonText2("Nacisnij guzik NR2!");
string winName = "PokerGui";
int a = 0;//mozna pozniej usunac, potrzebne tylko czy button reaguje jak nalezy

Rect button, button2;



void callBackFunc(int event, int x, int y, int flags, void* userdata)
{
    if (event == EVENT_LBUTTONDOWN)
    {
        if (button.contains(Point(x, y)))//ponizej to co ma sie wykonac po nacisnieciu klawisza
        {
            a = a + 7;
            cout << "Nacisnales guzik!\n" << endl;
            printf("liczba = %i\n", a);
            rectangle(canvas(button), button, Scalar(0, 0, 255), 2);

        }
        else if (button2.contains(Point(x, y)))//ponizej to co ma sie wykonac po nacisnieciu klawisza
        {
            //a = a + 7;
            cout << "Nacisnales guzik NR2!\n" << endl;
            //printf("liczba = %i\n", a);
            rectangle(canvas(button2), button, Scalar(0, 0, 255), 2);
        }
    }
    //if (event == EVENT_LBUTTONUP)
    //{
    //rectangle(canvas, button, Scalar(200, 200, 200), 2);
    //}

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

void callBackFunc2(int event, int x, int y, int flags, void* userdata)
{
    if (event == EVENT_LBUTTONDOWN)
    {
        if (button2.contains(Point(x, y)))//ponizej to co ma sie wykonac po nacisnieciu klawisza
        {
            //a = a + 7;
            cout << "Nacisnales guzik NR2!\n" << endl;
            //printf("liczba = %i\n", a);
            rectangle(canvas(button2), button, Scalar(0, 0, 255), 2);

        }
    }
    //if (event == EVENT_LBUTTONUP)
    //{
    //rectangle(canvas, button, Scalar(200, 200, 200), 2);
    //}

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

int main()
{
    // An image
    Mat3b img(300, 300, Vec3b(0, 255, 0));

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

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

    // Draw the button
    canvas(button) = Vec3b(200, 200, 200);
    canvas(button2) = 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));
    putText(canvas(button2), buttonText2, Point(button.width*0.25, button.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)));

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

    imshow(winName, canvas);
    waitKey();

    return 0;
}
Koci Ogon
  • 103
  • 1
  • 1
  • 5