Introduction
In this tutorial you will learn how to display basic drawings with ViSP either on Unix-like systems (including OSX, Fedora, Ubuntu, Debian, ...) or on Windows.
Note that all the material (source code and images) described in this tutorial is part of ViSP source code (in tutorial/image
folder) and could be found in https://github.com/lagadic/visp/tree/master/tutorial/image.
Load and display an image
ViSP gui module provides Graphical User Interfaces capabilities. To this end you may use several optional third-party libraries which are: X11, GDI, OpenCV, GTK, Direct3D. In the next example, we will use the first 3rd party that is available from the previous list.
The following example also available in tutorial-viewer.cpp shows how to read and display an image.
#include <visp3/core/vpConfig.h>
#include <visp3/gui/vpDisplayD3D.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayGTK.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/io/vpImageIo.h>
int main(int argc, char **argv)
{
#ifdef ENABLE_VISP_NAMESPACE
#endif
if (argc != 2) {
printf("Usage: %s <image name.[pgm,ppm,jpeg,png,tiff,bmp,ras,jp2]>\n", argv[0]);
return EXIT_FAILURE;
}
try {
}
catch (...) {
std::cout << "Cannot read image \"" << argv[1] << "\"" << std::endl;
return EXIT_FAILURE;
}
try {
#if defined(VISP_HAVE_X11)
#elif defined(VISP_HAVE_GDI)
#elif defined(HAVE_OPENCV_HIGHGUI)
#elif defined(VISP_HAVE_GTK)
#elif defined(VISP_HAVE_D3D9)
#else
std::cout << "No image viewer is available..." << std::endl;
#endif
std::cout << "A click to quit..." << std::endl;
}
std::cout << "Catch an exception: " << e << std::endl;
}
}
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
static void flush(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Once build, if you run the corresponding binary loading monkey.png
image:
$ cd $VISP_WS/
visp-build/tutorial/image
$ ./tutorial-viewer monkey.png
It will open a window containing monkey.png
image:
Here is the detailed explanation of the source, line by line :
#include <visp3/gui/vpDisplayD3D.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayGTK.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
Include all the headers for image viewers. The two first one are for Windows systems. They require that Direct 3D or the Graphical Device Interface (GDI) coming with the installation of Visual Studio are available. The third one needs GTK that is cross-platform. The fourth is for unix-like systems and requires that libX11 is available. The last one is also cross-platform and requires that OpenCV is available.
#include <visp3/io/vpImageIo.h>
Include the header that allows to read/write PGM, PPM, PNG and JPEG images from the disk using vpImageIo class.
Create an instance of a color image where each pixel is coded in RGBa.
try {
}
catch (...) {
std::cout << "Cannot read image \"" << argv[1] << "\"" << std::endl;
return EXIT_FAILURE;
}
The image I
is initialized by reading an image file from the disk. If the image format is not supported we throw an exception.
#if defined(VISP_HAVE_X11)
#elif defined(VISP_HAVE_GDI)
#elif defined(HAVE_OPENCV_HIGHGUI)
#elif defined(VISP_HAVE_GTK)
#elif defined(VISP_HAVE_D3D9)
#else
std::cout << "No image viewer is available..." << std::endl;
#endif
Create an instance of an image display window for image I
. The first viewer that is available is used. Here we create the link between the image I
and the display d
. Note that an image can only have one display.
The title of the display is then set to "My image"
.
First we display the content of the image I
, then we flush the display to render the image.
Here we handle mouse events. We are waiting for a blocking mouse click to end the program.
Display basic drawings in window overlay
There are a lot of examples in ViSP that show how to display drawings in window overlay. There is testDisplays.cpp that gives an overview.
If you run the corresponding binary:
$ cd $VISP_WS/
visp-build/modules/gui
$ ./testDisplays
it will open a window like the following:
Display a point in overlay
As shown in tutorial-draw-point.cpp which source code is given below we use vpDisplay::displayPoint() function to draw a point in the overlay of a windows that displays a 3840 by 2160 grey image that has all the pixels set to 128 gray level.
#include <visp3/core/vpConfig.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayX.h>
int main()
{
#ifdef ENABLE_VISP_NAMESPACE
#endif
try {
#if defined(VISP_HAVE_X11)
#elif defined(VISP_HAVE_GDI)
#endif
std::cout << "A click to quit..." << std::endl;
}
std::cout <<
"Catch an exception: " << e.
getMessage() << std::endl;
}
}
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
const char * getMessage() const
unsigned int getWidth() const
unsigned int getHeight() const
Here we draw a point at the center of a grey image with red color and thickness 2.
Display a line between 2 points in overlay
As given in tutorial-draw-line.cpp we use vpDisplay::displayLine() function to draw a line segment on the screen.
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
Here we draw a red coloured line segment with the specified initial and final coordinates and thickness 10.
Display a circle in overlay
As given in tutorial-image-display-scaled-auto.cpp we use vpDisplay::displayCircle() function to draw a circle on the screen.
static void displayCircle(const vpImage< unsigned char > &I, const vpImageCircle &circle, const vpColor &color, bool fill=false, unsigned int thickness=1)
Here we draw a red coloured filled circle at the center with radius of 200.
Display a rectangle in overlay
As given in tutorial-draw-rectangle.cpp we use vpDisplay::displayRectangle() function to draw a rectangle on the screen.
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
Here we draw a red coloured filled rectangle with specified top-left coordinates and width and height.
Display a cross in overlay
As given in tutorial-draw-cross.cpp we use vpDisplay::displayCross() function to draw a rectangle on the screen.
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
Here we draw a red coloured cross on the center with speicfied size and thickness 2.
Display text in window overlay
As given in tutorial-draw-text.cpp we use vpDisplay::displayText() function to add text in the window overlay.
static const vpColor yellow
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Here Hello world
is displayed in the middle of the image.
Export and save the content of a window as an image
As given in tutorial-export-image.cpp which source code is given below, we use vpDisplay::getImage() function to export the image with the whole drawings in overlay. Then we use vpImageIo::write() to save the image in png format.
#include <visp3/core/vpConfig.h>
#include <visp3/gui/vpDisplayD3D.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayGTK.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/io/vpImageIo.h>
int main()
{
#ifdef ENABLE_VISP_NAMESPACE
#endif
#if defined(VISP_HAVE_X11)
#elif defined(VISP_HAVE_GTK)
#elif defined(VISP_HAVE_GDI)
#elif defined(VISP_HAVE_D3D9)
#elif defined(HAVE_OPENCV_HIGHGUI)
#endif
#ifdef VISP_HAVE_DISPLAY
#endif
std::cout << "Save image in overlay.ppm" << std::endl;
std::string ofilename("overlay.png");
std::cout << "A click to quit..." << std::endl;
#ifdef VISP_HAVE_DISPLAY
delete d;
#endif
}
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="") VP_OVERRIDE
Class that defines generic functionalities for display.
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Handle keyboard events in a window
As given in tutorial-event-keyboard.cpp which code is given below, we use vpDisplay::getKeyboardEvent() function to get the value of the key pressed.
#include <visp3/core/vpConfig.h>
#include <visp3/gui/vpDisplayD3D.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayGTK.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
int main()
{
#ifdef ENABLE_VISP_NAMESPACE
#endif
#if defined(VISP_HAVE_X11)
#elif defined(VISP_HAVE_GTK)
#elif defined(VISP_HAVE_GDI)
#elif defined(VISP_HAVE_D3D9)
#elif defined(HAVE_OPENCV_HIGHGUI)
#else
std::cout << "Sorry, no video device is available" << std::endl;
return EXIT_FAILURE;
#endif
#ifdef VISP_HAVE_DISPLAY
#endif
std::cout << "Waiting a keyboard event..." << std::endl;
std::cout << "A keyboard event was detected" << std::endl;
int cpt_event = 0;
char key[10];
std::cout << "Enter a non blocking keyboard event detection loop..." << std::endl;
do {
if (event) {
std::cout << "Key detected: " << key << std::endl;
cpt_event++;
}
} while (cpt_event < 5);
#ifdef VISP_HAVE_DISPLAY
delete d;
#endif
}
static bool getKeyboardEvent(const vpImage< unsigned char > &I, bool blocking=true)
VISP_EXPORT int wait(double t0, double t)
Next tutorial
You are now ready to see how to continue with Tutorial: How to modify an image to insert basic drawings.