1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Image display.
33  *
34  * Authors:
35  * Christophe Collewet
36  * Eric Marchand
37  *
38  *****************************************************************************/
39 
40 #ifndef vpDisplayOpenCV_h
41 #define vpDisplayOpenCV_h
42 
43 #include <visp3/core/vpConfig.h>
44 #if defined(VISP_HAVE_OPENCV)
45 
46 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
47 #include <functional>
48 #endif
49 
50 #include <visp3/core/vpDisplay.h>
51 #include <visp3/core/vpImage.h>
52 #include <visp3/core/vpImageConvert.h>
53 
54 #if VISP_HAVE_OPENCV_VERSION >= 0x020101
55 #include <opencv2/core/core.hpp>
56 #include <opencv2/highgui/highgui.hpp>
57 #else
58 #include <cv.h>
59 #include <cxcore.h>
60 #include <highgui.h>
61 #endif
62 
63 /*!
64   \file vpDisplayOpenCV.h
65   \brief Define the OpenCV console to display images.
66 */
67 
68 /*!
69 
70   \class vpDisplayOpenCV
71 
72   \ingroup group_gui_display
73 
74   \brief The vpDisplayOpenCV allows to display image using the OpenCV library.
75   Thus to enable this class OpenCV should be installed. Installation
76   instructions are provided here https://visp.inria.fr/3rd_opencv.
77 
78   \warning Since ViSP 3.3.1 or higher we introduce the alpha channel support for color
79   transparency. This new feature is only supported yet using vpDisplayOpenCV. See vpColor
80   header documentation and displayOpenCV.cpp example for usage displaying filled
81   transparent circles and rectangles.
82 
83   The example below shows how to display an image with this video device.
84   \code
85 #include <visp3/core/vpImagePoint.h>
86 #include <visp3/gui/vpDisplayOpenCV.h>
87 #include <visp3/io/vpImageIo.h>
88 
89 int main()
90 {
91 #if defined(VISP_HAVE_OPENCV)
92   vpImage<unsigned char> I; // Grey level image
93 
94   // Read an image in PGM P5 format
95   vpImageIo::read(I, "/local/soft/ViSP/ViSP-images/Klimt/Klimt.pgm");
96 
97   vpDisplayOpenCV d;
98 
99   // Initialize the display with the image I. Display and image are
100   // now link together.
101   d.init(I);
102 
103   // Specify the window location
104   vpDisplay::setWindowPosition(I, 400, 100);
105 
106   // Set the display window title
107   vpDisplay::setTitle(I, "My OpenCV display");
108 
109   // Set the display background with image I content
110   vpDisplay::display(I);
111 
112   // Draw a red rectangle in the display overlay (foreground)
113   vpDisplay::displayRectangle(I, 10, 10, 100, 20, vpColor::red, true);
114 
115   // Draw a red rectangle in the display overlay (foreground)
116   vpImagePoint topLeftCorner;
117   topLeftCorner.set_i(10);
118   topLeftCorner.set_j(50);
119   vpDisplay::displayRectangle(I, topLeftCorner, 100, 20, vpColor::green, true);
120 
121   // Flush the foreground and background display
122   vpDisplay::flush(I);
123 
124   // Get non blocking keyboard events
125   std::cout << "Check keyboard events..." << std::endl;
126   char key[10];
127   bool ret;
128   for (int i=0; i< 200; i++) {
129     bool ret = vpDisplay::getKeyboardEvent(I, key, false);
130     if (ret)
131       std::cout << "keyboard event: key: " << "\"" << key << "\"" << std::endl;
132    vpTime::wait(40);
133   }
134 
135   // Get a blocking keyboard event
136   std::cout << "Wait for a keyboard event..." << std::endl;
137   ret = vpDisplay::getKeyboardEvent(I, key, true);
138   std::cout << "keyboard event: " << ret << std::endl;
139   if (ret)
140     std::cout << "key: " << "\"" << key << "\"" << std::endl;
141 
142   // Wait for a click in the display window
143   std::cout << "Wait for a button click..." << std::endl;
144   vpDisplay::getClick(I);
145 #endif
146 }
147   \endcode
148 */
149 
150 class VISP_EXPORT vpDisplayOpenCV : public vpDisplay
151 {
152 private:
153 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
154   //! true if OpenCV display is ready to use
155   IplImage *m_background;
156   CvScalar *col;
157   CvScalar cvcolor;
158   CvFont *font;
159 #else
160   cv::Mat m_background;
161   cv::Scalar *col;
162   cv::Scalar cvcolor;
163   int font;
164   float fontScale;
165 #endif
166   static std::vector<std::string> m_listTitles;
167   static unsigned int m_nbWindows;
168   int fontHeight;
169   int x_move;
170   int y_move;
171   bool move;
172   int x_lbuttondown;
173   int y_lbuttondown;
174   bool lbuttondown;
175   int x_mbuttondown;
176   int y_mbuttondown;
177   bool mbuttondown;
178   int x_rbuttondown;
179   int y_rbuttondown;
180   bool rbuttondown;
181   int x_lbuttonup;
182   int y_lbuttonup;
183   bool lbuttonup;
184   int x_mbuttonup;
185   int y_mbuttonup;
186   bool mbuttonup;
187   int x_rbuttonup;
188   int y_rbuttonup;
189   bool rbuttonup;
190 
191   // private:
192   //#ifndef DOXYGEN_SHOULD_SKIP_THIS
193   //  vpDisplayOpenCV(const vpDisplayOpenCV &)
194   //    : vpDisplay(),
195   //    #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
196   //      background(NULL), col(NULL), cvcolor(), font(NULL),
197   //    #else
198   //      background(), col(NULL), cvcolor(), font(cv::FONT_HERSHEY_PLAIN),
199   //      fontScale(0.8f),
200   //    #endif
201   //      fontHeight(10), x_move(0), y_move(0) , move(false),
202   //      x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
203   //      x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false),
204   //      x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
205   //      x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false),
206   //      x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false),
207   //      x_rbuttonup(0), y_rbuttonup(0), rbuttonup(false)
208   //  {
209   //    throw vpException(vpException::functionNotImplementedError, "Not
210   //    implemented!");
211   //  }
212   //  vpDisplayOpenCV &operator=(const vpDisplayOpenCV &){
213   //    throw vpException(vpException::functionNotImplementedError, "Not
214   //    implemented!"); return *this;
215   //  }
216   //#endif
217 
218 public:
219   vpDisplayOpenCV();
220   vpDisplayOpenCV(int winx, int winy, const std::string &title = "");
221   vpDisplayOpenCV(vpImage<unsigned char> &I, vpScaleType type);
222   vpDisplayOpenCV(vpImage<unsigned char> &I, int winx = -1, int winy = -1, const std::string &title = "",
223                   vpScaleType type = SCALE_DEFAULT);
224   vpDisplayOpenCV(vpImage<vpRGBa> &I, vpScaleType type);
225   vpDisplayOpenCV(vpImage<vpRGBa> &I, int winx = -1, int winy = -1, const std::string &title = "",
226                   vpScaleType type = SCALE_DEFAULT);
227 
228   virtual ~vpDisplayOpenCV();
229 
230   void getImage(vpImage<vpRGBa> &I);
231   unsigned int getScreenHeight();
232   void getScreenSize(unsigned int &width, unsigned int &height);
233   unsigned int getScreenWidth();
234 
235   void init(vpImage<unsigned char> &I, int winx = -1, int winy = -1, const std::string &title = "");
236   void init(vpImage<vpRGBa> &I, int winx = -1, int winy = -1, const std::string &title = "");
237   void init(unsigned int width, unsigned int height, int winx = -1, int winy = -1, const std::string &title = "");
238 
239 protected:
240   void setFont(const std::string &font);
241   void setTitle(const std::string &title);
242   void setWindowPosition(int winx, int winy);
243 
244   void clearDisplay(const vpColor &color = vpColor::white);
245 
246   void closeDisplay();
247 
248   void displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color = vpColor::white,
249                     unsigned int w = 4, unsigned int h = 2, unsigned int thickness = 1);
250 
251   void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color = vpColor::green);
252 
253   void displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill = false,
254                      unsigned int thickness = 1);
255   void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness = 1);
256   void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
257                       unsigned int thickness = 1);
258 
259   void displayImage(const vpImage<unsigned char> &I);
260   void displayImage(const vpImage<vpRGBa> &I);
261   void displayImage(const unsigned char *I);
262 
263   void displayImageROI(const vpImage<unsigned char> &I, const vpImagePoint &iP, unsigned int width,
264                        unsigned int height);
265   void displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, unsigned int width,
266                        unsigned int height);
267 
268   void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness = 1);
269   void displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness = 1);
270 
271   void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color,
272                         bool fill = false, unsigned int thickness = 1);
273   void displayRectangle(const vpImagePoint &topLeft, const vpImagePoint &bottomRight, const vpColor &color,
274                         bool fill = false, unsigned int thickness = 1);
275   void displayRectangle(const vpRect &rectangle, const vpColor &color, bool fill = false, unsigned int thickness = 1);
276 
277   void flushDisplay();
278   void flushDisplayROI(const vpImagePoint &iP, unsigned int width, unsigned int height);
279 
280   bool getClick(bool blocking = true);
281   bool getClick(vpImagePoint &ip, bool blocking = true);
282   bool getClick(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking = true);
283   bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking = true);
284 
285   bool getKeyboardEvent(bool blocking = true);
286   bool getKeyboardEvent(std::string &key, bool blocking = true);
287   bool getPointerMotionEvent(vpImagePoint &ip);
288   bool getPointerPosition(vpImagePoint &ip);
289 
290   static void on_mouse(int event, int x, int y, int flags, void *param);
291 
292 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
293   void overlay(std::function<void(cv::Mat&)> overlay_function, double opacity);
294 #endif
295 };
296 
297 #endif
298 #endif
299