Visual Servoing Platform  version 3.6.1 under development (2024-12-17)
vpDisplayOpenCV.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Image display.
32  */
33 
39 #include <visp3/core/vpConfig.h>
40 
41 #if defined(HAVE_OPENCV_HIGHGUI)
42 
43 #include <cmath> // std::fabs
44 #include <iostream>
45 #include <limits> // numeric_limits
46 #include <stdio.h>
47 #include <stdlib.h>
48 
49 // Display stuff
50 #include <visp3/core/vpDisplay.h>
51 #include <visp3/core/vpImageTools.h>
52 #include <visp3/core/vpIoTools.h>
53 #include <visp3/core/vpMath.h>
54 #include <visp3/gui/vpDisplayOpenCV.h>
55 
56 // debug / exception
57 #include <visp3/core/vpDisplayException.h>
58 
59 #include <opencv2/core/core.hpp>
60 #include <opencv2/highgui/highgui.hpp>
61 #include <opencv2/core/core_c.h> // for CV_FILLED versus cv::FILLED
62 
63 #if defined(HAVE_OPENCV_IMGPROC)
64 #include <opencv2/imgproc/imgproc.hpp>
65 #endif
66 
67 #ifndef CV_RGB
68 #define CV_RGB(r, g, b) cv::Scalar((b), (g), (r), 0)
69 #endif
70 
71 #ifdef VISP_HAVE_X11
72 #include <visp3/gui/vpDisplayX.h> // to get screen resolution
73 #elif defined(_WIN32)
74 #include <windows.h>
75 #endif
76 
77 BEGIN_VISP_NAMESPACE
78 
79 #ifndef DOXYGEN_SHOULD_SKIP_THIS
80 class vpDisplayOpenCV::Impl
81 {
82 private:
83  cv::Mat m_background;
84  cv::Scalar *col;
85  cv::Scalar cvcolor;
86  int font;
87  float fontScale;
88  static std::vector<std::string> m_listTitles;
89  static unsigned int m_nbWindows;
90  int fontHeight;
91  int x_move;
92  int y_move;
93  bool move;
94  int x_lbuttondown;
95  int y_lbuttondown;
96  bool lbuttondown;
97  int x_mbuttondown;
98  int y_mbuttondown;
99  bool mbuttondown;
100  int x_rbuttondown;
101  int y_rbuttondown;
102  bool rbuttondown;
103  int x_lbuttonup;
104  int y_lbuttonup;
105  bool lbuttonup;
106  int x_mbuttonup;
107  int y_mbuttonup;
108  bool mbuttonup;
109  int x_rbuttonup;
110  int y_rbuttonup;
111  bool rbuttonup;
112 
113  friend class vpDisplayOpenCV;
114 
115 public:
116  Impl() :
117  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
118  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
119  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
120  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
121  y_rbuttonup(0), rbuttonup(false)
122  { }
123 
124  virtual ~Impl()
125  {
126  if (col != nullptr) {
127  delete[] col;
128  col = nullptr;
129  }
130  }
131 
132  void getImage(vpImage<vpRGBa> &I)
133  {
134  // Should be optimized
135  vpImageConvert::convert(m_background, I);
136  }
137 
138  std::string init(const std::string &title, const int &windowXPosition, const int &windowYPosition)
139  {
140  int flags = cv::WINDOW_AUTOSIZE;
141  std::string outTitle = title;
142  if (outTitle.empty()) {
143  std::ostringstream s;
144  s << m_nbWindows++;
145  outTitle = std::string("Window ") + s.str();
146  }
147 
148  bool isInList;
149  do {
150  isInList = false;
151  size_t i = 0;
152  while (i < m_listTitles.size() && !isInList) {
153  if (m_listTitles[i] == outTitle) {
154  std::ostringstream s;
155  s << m_nbWindows++;
156  outTitle = std::string("Window ") + s.str();
157  isInList = true;
158  }
159  i++;
160  }
161  } while (isInList);
162 
163  m_listTitles.push_back(outTitle);
164 
165 
166  /* Create the window*/
167  cv::namedWindow(outTitle, flags);
168  cv::moveWindow(outTitle.c_str(), windowXPosition, windowYPosition);
169 
170  move = false;
171  lbuttondown = false;
172  mbuttondown = false;
173  rbuttondown = false;
174  lbuttonup = false;
175  mbuttonup = false;
176  rbuttonup = false;
177 
178  cv::setMouseCallback(outTitle, on_mouse, this);
179  col = new cv::Scalar[vpColor::id_unknown];
180 
181  /* Create color */
182  vpColor pcolor; // Predefined colors
183  pcolor = vpColor::lightBlue;
184  col[vpColor::id_lightBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
185  pcolor = vpColor::blue;
186  col[vpColor::id_blue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
187  pcolor = vpColor::darkBlue;
188  col[vpColor::id_darkBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
189  pcolor = vpColor::lightRed;
190  col[vpColor::id_lightRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
191  pcolor = vpColor::red;
192  col[vpColor::id_red] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
193  pcolor = vpColor::darkRed;
194  col[vpColor::id_darkRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
195  pcolor = vpColor::lightGreen;
196  col[vpColor::id_lightGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
197  pcolor = vpColor::green;
198  col[vpColor::id_green] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
199  pcolor = vpColor::darkGreen;
200  col[vpColor::id_darkGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
201  pcolor = vpColor::yellow;
202  col[vpColor::id_yellow] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
203  pcolor = vpColor::cyan;
204  col[vpColor::id_cyan] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
205  pcolor = vpColor::orange;
206  col[vpColor::id_orange] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
207  pcolor = vpColor::purple;
208  col[vpColor::id_purple] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
209  pcolor = vpColor::white;
210  col[vpColor::id_white] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
211  pcolor = vpColor::black;
212  col[vpColor::id_black] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
213  pcolor = vpColor::lightGray;
214  col[vpColor::id_lightGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
215  pcolor = vpColor::gray;
216  col[vpColor::id_gray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
217  pcolor = vpColor::darkGray;
218  col[vpColor::id_darkGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
219 
220  int thickness = 1;
221  cv::Size fontSize;
222  int baseline;
223  fontSize = cv::getTextSize("A", font, fontScale, thickness, &baseline);
224 
225  fontHeight = fontSize.height + baseline;
226  return outTitle;
227  }
228 
229  void closeDisplay(const std::string &title)
230  {
231  if (col != nullptr) {
232  delete[] col;
233  col = nullptr;
234  }
235 
236  cv::destroyWindow(title);
237  for (size_t i = 0; i < m_listTitles.size(); i++) {
238  if (title == m_listTitles[i]) {
239  m_listTitles.erase(m_listTitles.begin() + (long int)i);
240  break;
241  }
242  }
243  }
244 
245  void displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
246  const unsigned int &w, const unsigned int &h, const unsigned int &thickness, const unsigned int &scale)
247  {
248  double a = ip2.get_i() - ip1.get_i();
249  double b = ip2.get_j() - ip1.get_j();
250  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
251 
252  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
253  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
254  }
255  else {
256  a /= lg;
257  b /= lg;
258 
259  vpImagePoint ip3;
260  ip3.set_i(ip2.get_i() - w * a);
261  ip3.set_j(ip2.get_j() - w * b);
262 
263  vpImagePoint ip4;
264  ip4.set_i(ip3.get_i() - b * h);
265  ip4.set_j(ip3.get_j() + a * h);
266 
267  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
268  displayLine(ip2, ip4, color, thickness, scale);
269 
270  ip4.set_i(ip3.get_i() + b * h);
271  ip4.set_j(ip3.get_j() - a * h);
272 
273  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
274  displayLine(ip2, ip4, color, thickness, scale);
275 
276  displayLine(ip1, ip2, color, thickness, scale);
277  }
278  }
279 
280  void displayCircle(const vpImagePoint &center, const unsigned int &radius, const vpColor &color, const bool &fill,
281  const unsigned int &thickness, const unsigned int &scale)
282  {
283  int x = vpMath::round(center.get_u() / scale);
284  int y = vpMath::round(center.get_v() / scale);
285  int r = static_cast<int>(radius / scale);
286  cv::Scalar cv_color;
287  if (color.id < vpColor::id_unknown) {
288  cv_color = col[color.id];
289  }
290  else {
291  cv_color = CV_RGB(color.R, color.G, color.B);
292  }
293 
294  if (fill == false) {
295  int cv_thickness = static_cast<int>(thickness);
296  cv::circle(m_background, cv::Point(x, y), r, cv_color, cv_thickness);
297  }
298  else {
299 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
300  int filled = cv::FILLED;
301 #else
302  int filled = CV_FILLED;
303 #endif
304  double opacity = static_cast<double>(color.A) / 255.0;
305  overlay([x, y, r, cv_color, filled](cv::Mat image) { cv::circle(image, cv::Point(x, y), r, cv_color, filled); },
306  opacity);
307  }
308  }
309 
310  void displayCross(const vpImagePoint &ip, const unsigned int &size, const vpColor &color, const unsigned int &thickness, const unsigned int &scale)
311  {
312  vpImagePoint top, bottom, left, right;
313  top.set_i(ip.get_i() - size / 2);
314  top.set_j(ip.get_j());
315  bottom.set_i(ip.get_i() + size / 2);
316  bottom.set_j(ip.get_j());
317  left.set_i(ip.get_i());
318  left.set_j(ip.get_j() - size / 2);
319  right.set_i(ip.get_i());
320  right.set_j(ip.get_j() + size / 2);
321  displayLine(top, bottom, color, thickness, scale);
322  displayLine(left, right, color, thickness, scale);
323  }
324 
325  void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
326  const unsigned int &thickness, const unsigned int &scale)
327  {
328  vpImagePoint ip1_ = ip1;
329  vpImagePoint ip2_ = ip2;
330 
331  double size = 10. * scale;
332  double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
333  bool vertical_line = (int)ip2_.get_j() == (int)ip1_.get_j();
334  if (vertical_line) {
335  if (ip2_.get_i() < ip1_.get_i()) {
336  std::swap(ip1_, ip2_);
337  }
338  }
339  else if (ip2_.get_j() < ip1_.get_j()) {
340  std::swap(ip1_, ip2_);
341  }
342 
343  double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
344  double deltaj = size / length * diff_j;
345  double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
346  double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
347  double orig = ip1_.get_i() - slope * ip1_.get_j();
348 
349  if (vertical_line) {
350  for (unsigned int i = (unsigned int)ip1_.get_i(); i < ip2_.get_i(); i += (unsigned int)(2 * deltai)) {
351  double j = ip1_.get_j();
352  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j), color, thickness, scale);
353  }
354  }
355  else {
356  for (unsigned int j = (unsigned int)ip1_.get_j(); j < ip2_.get_j(); j += (unsigned int)(2 * deltaj)) {
357  double i = slope * j + orig;
358  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j + deltaj), color, thickness, scale);
359  }
360  }
361  }
362 
363  void displayImage(const vpImage<unsigned char> &I, const unsigned int &scale, const unsigned int &width, const unsigned int &height)
364  {
365  int depth = CV_8U;
366  int channels = 3;
367  cv::Size size((int)width, (int)height);
368  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)height ||
369  m_background.cols != (int)width) {
370  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
371  }
372 
373  if (scale == 1) {
374  for (unsigned int i = 0; i < height; i++) {
375  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * width);
376  for (unsigned int j = 0; j < width; j++) {
377  unsigned char val = I[i][j];
378  *(dst_24++) = val;
379  *(dst_24++) = val;
380  *(dst_24++) = val;
381  }
382  }
383  }
384  else {
385  for (unsigned int i = 0; i < height; i++) {
386  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * width);
387  for (unsigned int j = 0; j < width; j++) {
388  unsigned char val = I[i * scale][j * scale];
389  *(dst_24++) = val;
390  *(dst_24++) = val;
391  *(dst_24++) = val;
392  }
393  }
394  }
395  }
396 
397  void displayImage(const vpImage<vpRGBa> &I, const unsigned int &scale, const unsigned int &width, const unsigned int &height)
398  {
399  int depth = CV_8U;
400  int channels = 3;
401  cv::Size size((int)width, (int)height);
402  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)height ||
403  m_background.cols != (int)width) {
404  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
405  }
406 
407  if (scale == 1) {
408  for (unsigned int i = 0; i < height; i++) {
409  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * width);
410  for (unsigned int j = 0; j < width; j++) {
411  vpRGBa val = I[i][j];
412  *(dst_24++) = val.B;
413  *(dst_24++) = val.G;
414  *(dst_24++) = val.R;
415  }
416  }
417  }
418  else {
419  for (unsigned int i = 0; i < height; i++) {
420  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * width);
421  for (unsigned int j = 0; j < width; j++) {
422  vpRGBa val = I[i * scale][j * scale];
423  *(dst_24++) = val.B;
424  *(dst_24++) = val.G;
425  *(dst_24++) = val.R;
426  }
427  }
428  }
429  }
430 
431  void displayImageROI(const vpImage<unsigned char> &I, const vpImagePoint &iP, const unsigned int &w,
432  const unsigned int &h, const unsigned int &imgWidth, const unsigned int &imgHeight, const unsigned int &scale)
433  {
434  int depth = CV_8U;
435  int channels = 3;
436  cv::Size size((int)imgWidth, (int)imgHeight);
437  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)imgHeight ||
438  m_background.cols != (int)imgWidth) {
439  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
440  }
441 
442  if (scale == 1) {
443  unsigned int i_min = (unsigned int)iP.get_i();
444  unsigned int j_min = (unsigned int)iP.get_j();
445  unsigned int i_max = std::min<unsigned int>(i_min + h, imgHeight);
446  unsigned int j_max = std::min<unsigned int>(j_min + w, imgWidth);
447  for (unsigned int i = i_min; i < i_max; i++) {
448  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * imgWidth + j_min * 3);
449  for (unsigned int j = j_min; j < j_max; j++) {
450  unsigned char val = I[i][j];
451  *(dst_24++) = val;
452  *(dst_24++) = val;
453  *(dst_24++) = val;
454  }
455  }
456  }
457  else {
458  int i_min = std::max<int>((int)ceil(iP.get_i() / scale), 0);
459  int j_min = std::max<int>((int)ceil(iP.get_j() / scale), 0);
460  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / scale), (int)imgHeight);
461  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / scale), (int)imgWidth);
462  for (int i = i_min; i < i_max; i++) {
463  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * imgWidth + j_min * 3);
464  for (int j = j_min; j < j_max; j++) {
465  unsigned char val = I[i * scale][j * scale];
466  *(dst_24++) = val;
467  *(dst_24++) = val;
468  *(dst_24++) = val;
469  }
470  }
471  }
472  }
473 
474  void displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, const unsigned int &w, const unsigned int &h, const unsigned int &imgWidth, const unsigned int &imgHeight, const unsigned int &scale)
475  {
476  int depth = CV_8U;
477  int channels = 3;
478  cv::Size size((int)imgWidth, (int)imgHeight);
479  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)imgHeight ||
480  m_background.cols != (int)imgWidth) {
481  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
482  }
483 
484  if (scale == 1) {
485  unsigned int i_min = (unsigned int)iP.get_i();
486  unsigned int j_min = (unsigned int)iP.get_j();
487  unsigned int i_max = std::min<unsigned int>(i_min + h, imgHeight);
488  unsigned int j_max = std::min<unsigned int>(j_min + w, imgWidth);
489  for (unsigned int i = i_min; i < i_max; i++) {
490  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * imgWidth + j_min * 3);
491  for (unsigned int j = j_min; j < j_max; j++) {
492  vpRGBa val = I[i][j];
493  *(dst_24++) = val.B;
494  *(dst_24++) = val.G;
495  *(dst_24++) = val.R;
496  }
497  }
498  }
499  else {
500  int i_min = std::max<int>((int)ceil(iP.get_i() / scale), 0);
501  int j_min = std::max<int>((int)ceil(iP.get_j() / scale), 0);
502  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / scale), (int)imgHeight);
503  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / scale), (int)imgWidth);
504  for (int i = i_min; i < i_max; i++) {
505  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * imgWidth + j_min * 3);
506  for (int j = j_min; j < j_max; j++) {
507  vpRGBa val = I[i * scale][j * scale];
508  *(dst_24++) = val.B;
509  *(dst_24++) = val.G;
510  *(dst_24++) = val.R;
511  }
512  }
513  }
514  }
515 
516  void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, const unsigned int &thickness, const unsigned int &scale)
517  {
518  if (color.id < vpColor::id_unknown) {
519  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / scale), vpMath::round(ip1.get_v() / scale)),
520  cv::Point(vpMath::round(ip2.get_u() / scale), vpMath::round(ip2.get_v() / scale)), col[color.id],
521  (int)thickness);
522  }
523  else {
524  cvcolor = CV_RGB(color.R, color.G, color.B);
525  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / scale), vpMath::round(ip1.get_v() / scale)),
526  cv::Point(vpMath::round(ip2.get_u() / scale), vpMath::round(ip2.get_v() / scale)), cvcolor,
527  (int)thickness);
528  }
529  }
530 
531  void displayPoint(const vpImagePoint &ip, const vpColor &color, const unsigned int &thickness, const unsigned int &scale)
532  {
533  for (unsigned int i = 0; i < thickness; i++) {
534  if (color.id < vpColor::id_unknown) {
535  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / scale), vpMath::round(ip.get_v() / scale)),
536  cv::Point(vpMath::round(ip.get_u() / scale + thickness - 1), vpMath::round(ip.get_v() / scale)),
537  col[color.id], (int)thickness);
538  }
539  else {
540  cvcolor = CV_RGB(color.R, color.G, color.B);
541  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / scale), vpMath::round(ip.get_v() / scale)),
542  cv::Point(vpMath::round(ip.get_u() / scale + thickness - 1), vpMath::round(ip.get_v() / scale)),
543  cvcolor, (int)thickness);
544  }
545  }
546  }
547 
548  void displayRectangle(const vpImagePoint &topLeft, const unsigned int &w, const unsigned int &h, const vpColor &color,
549  const bool &fill, const unsigned int &thickness, const unsigned int &scale)
550  {
551  int left = vpMath::round(topLeft.get_u() / scale);
552  int top = vpMath::round(topLeft.get_v() / scale);
553  int right = vpMath::round((topLeft.get_u() + w) / scale);
554  int bottom = vpMath::round((topLeft.get_v() + h) / scale);
555  cv::Scalar cv_color;
556  if (color.id < vpColor::id_unknown) {
557  cv_color = col[color.id];
558  }
559  else {
560  cv_color = CV_RGB(color.R, color.G, color.B);
561  }
562 
563  if (fill == false) {
564  int cv_thickness = static_cast<int>(thickness);
565  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
566  }
567  else {
568 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
569  int filled = cv::FILLED;
570 #else
571  int filled = CV_FILLED;
572 #endif
573  double opacity = static_cast<double>(color.A) / 255.0;
574  overlay([left, top, right, bottom, cv_color, filled](cv::Mat image) {
575  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
576  },
577  opacity);
578  }
579  }
580 
581  void displayText(const vpImagePoint &ip, const std::string &text, const vpColor &color, const unsigned int &scale)
582  {
583  if (color.id < vpColor::id_unknown) {
584  cv::putText(m_background, text,
585  cv::Point(vpMath::round(ip.get_u() / scale), vpMath::round(ip.get_v() / scale + fontHeight)),
586  font, fontScale, col[color.id]);
587  }
588  else {
589  cvcolor = CV_RGB(color.R, color.G, color.B);
590  cv::putText(m_background, text,
591  cv::Point(vpMath::round(ip.get_u() / scale), vpMath::round(ip.get_v() / scale + fontHeight)),
592  font, fontScale, cvcolor);
593  }
594  }
595 
596  void flushDisplay(const std::string &title)
597  {
598  cv::imshow(title, m_background);
599  cv::waitKey(5);
600  }
601 
602  void flushDisplayROI(const std::string &title)
603  {
604  cv::imshow(title.c_str(), m_background);
605  cv::waitKey(5);
606  }
607 
608  bool getClick(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, const bool &blocking, const std::string &title, const unsigned int &scale)
609  {
610  flushDisplay(title);
611  bool ret = false;
612  double u, v;
613  if (blocking) {
614  lbuttondown = false;
615  mbuttondown = false;
616  rbuttondown = false;
617  }
618  do {
619  if (lbuttondown) {
620  ret = true;
621  u = (unsigned int)x_lbuttondown * scale;
622  v = (unsigned int)y_lbuttondown * scale;
623  ip.set_u(u);
624  ip.set_v(v);
625  button = vpMouseButton::button1;
626  lbuttondown = false;
627  }
628  if (mbuttondown) {
629  ret = true;
630  u = (unsigned int)x_mbuttondown * scale;
631  v = (unsigned int)y_mbuttondown * scale;
632  ip.set_u(u);
633  ip.set_v(v);
634  button = vpMouseButton::button2;
635  mbuttondown = false;
636  }
637  if (rbuttondown) {
638  ret = true;
639  u = (unsigned int)x_rbuttondown * scale;
640  v = (unsigned int)y_rbuttondown * scale;
641  ip.set_u(u);
642  ip.set_v(v);
643  button = vpMouseButton::button3;
644  rbuttondown = false;
645  }
646  if (blocking) {
647  cv::waitKey(10);
648  }
649  } while (ret == false && blocking == true);
650  return ret;
651  }
652 
653  bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, const bool &blocking, const unsigned int &scale)
654  {
655  bool ret = false;
656  double u, v;
657  if (blocking) {
658  lbuttonup = false;
659  mbuttonup = false;
660  rbuttonup = false;
661  }
662  do {
663  if (lbuttonup) {
664  ret = true;
665  u = (unsigned int)x_lbuttonup * scale;
666  v = (unsigned int)y_lbuttonup * scale;
667  ip.set_u(u);
668  ip.set_v(v);
669  button = vpMouseButton::button1;
670  lbuttonup = false;
671  }
672  if (mbuttonup) {
673  ret = true;
674  u = (unsigned int)x_mbuttonup * scale;
675  v = (unsigned int)y_mbuttonup * scale;
676  ip.set_u(u);
677  ip.set_v(v);
678  button = vpMouseButton::button2;
679  mbuttonup = false;
680  }
681  if (rbuttonup) {
682  ret = true;
683  u = (unsigned int)x_rbuttonup * scale;
684  v = (unsigned int)y_rbuttonup * scale;
685  ip.set_u(u);
686  ip.set_v(v);
687  button = vpMouseButton::button3;
688  rbuttonup = false;
689  }
690  if (blocking) {
691  cv::waitKey(10);
692  }
693  } while (ret == false && blocking == true);
694  return ret;
695  }
696 
697  bool getPointerMotionEvent(vpImagePoint &ip, const unsigned int &scale)
698  {
699  bool ret = false;
700  if (move) {
701  ret = true;
702  double u = (unsigned int)x_move / scale;
703  double v = (unsigned int)y_move / scale;
704  ip.set_u(u);
705  ip.set_v(v);
706  move = false;
707  }
708  return ret;
709  }
710 
711  void getPointerPosition(vpImagePoint &ip, const unsigned int &scale)
712  {
713  bool moved = getPointerMotionEvent(ip, scale);
714  if (!moved) {
715  double u, v;
716  u = (unsigned int)x_move / scale;
717  v = (unsigned int)y_move / scale;
718  ip.set_u(u);
719  ip.set_v(v);
720  }
721  }
722 
723  static void on_mouse(int event, int x, int y, int /*flags*/, void *display)
724  {
725  Impl *disp = static_cast<Impl *>(display);
726 
727  switch (event) {
728  case cv::EVENT_MOUSEMOVE:
729  {
730  disp->move = true;
731  disp->x_move = x;
732  disp->y_move = y;
733  break;
734  }
735  case cv::EVENT_LBUTTONDOWN:
736  {
737  disp->lbuttondown = true;
738  disp->x_lbuttondown = x;
739  disp->y_lbuttondown = y;
740  break;
741  }
742  case cv::EVENT_MBUTTONDOWN:
743  {
744  disp->mbuttondown = true;
745  disp->x_mbuttondown = x;
746  disp->y_mbuttondown = y;
747  break;
748  }
749  case cv::EVENT_RBUTTONDOWN:
750  {
751  disp->rbuttondown = true;
752  disp->x_rbuttondown = x;
753  disp->y_rbuttondown = y;
754  break;
755  }
756  case cv::EVENT_LBUTTONUP:
757  {
758  disp->lbuttonup = true;
759  disp->x_lbuttonup = x;
760  disp->y_lbuttonup = y;
761  break;
762  }
763  case cv::EVENT_MBUTTONUP:
764  {
765  disp->mbuttonup = true;
766  disp->x_mbuttonup = x;
767  disp->y_mbuttonup = y;
768  break;
769  }
770  case cv::EVENT_RBUTTONUP:
771  {
772  disp->rbuttonup = true;
773  disp->x_rbuttonup = x;
774  disp->y_rbuttonup = y;
775  break;
776  }
777 
778  default:
779  break;
780  }
781  }
782 
783  void overlay(std::function<void(cv::Mat &)> overlay_function, const double &opacity)
784  {
785  // Initialize overlay layer for transparency
786  cv::Mat overlay;
787  if (opacity < 1.0) {
788  // Deep copy
789  overlay = m_background.clone();
790  }
791  else {
792  // Shallow copy
793  overlay = m_background;
794  }
795 
796  overlay_function(overlay);
797 
798  // Blend background and overlay
799  if (opacity < 1.0) {
800  cv::addWeighted(overlay, opacity, m_background, 1.0 - opacity, 0.0, m_background);
801  }
802  }
803 };
804 
805 std::vector<std::string> vpDisplayOpenCV::Impl::m_listTitles = std::vector<std::string>();
806 unsigned int vpDisplayOpenCV::Impl::m_nbWindows = 0;
807 #endif // DOXYGEN_SHOULD_SKIP_THIS
808 
831  : vpDisplay()
832  , m_impl(new Impl())
833 {
834  setScale(scaleType, I.getWidth(), I.getHeight());
835  init(I);
836 }
837 
861 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<unsigned char> &I, int x, int y, const std::string &title,
862  vpScaleType scaleType)
863  : vpDisplay()
864  , m_impl(new Impl())
865 {
866  setScale(scaleType, I.getWidth(), I.getHeight());
867  init(I, x, y, title);
868 }
869 
889  : vpDisplay()
890  , m_impl(new Impl())
891 {
892  setScale(scaleType, I.getWidth(), I.getHeight());
893  init(I);
894 }
895 
916 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<vpRGBa> &I, int x, int y, const std::string &title, vpScaleType scaleType)
917  : vpDisplay()
918  , m_impl(new Impl())
919 {
920  setScale(scaleType, I.getWidth(), I.getHeight());
921  init(I, x, y, title);
922 }
923 
950 vpDisplayOpenCV::vpDisplayOpenCV(int x, int y, const std::string &title)
951  : vpDisplay()
952  , m_impl(new Impl())
953 {
954  m_windowXPosition = x;
955  m_windowYPosition = y;
956 
957  if (!title.empty()) {
958  m_title = title;
959  }
960  else {
961  std::ostringstream s;
962  s << vpDisplayOpenCV::Impl::m_nbWindows++;
963  m_title = std::string("Window ") + s.str();
964  }
965 
966  bool isInList;
967  do {
968  isInList = false;
969  for (size_t i = 0; i < vpDisplayOpenCV::Impl::m_listTitles.size(); i++) {
970  if (vpDisplayOpenCV::Impl::m_listTitles[i] == m_title) {
971  std::ostringstream s;
972  s << vpDisplayOpenCV::Impl::m_nbWindows++;
973  m_title = std::string("Window ") + s.str();
974  isInList = true;
975  break;
976  }
977  }
978  } while (isInList);
979 
980  vpDisplayOpenCV::Impl::m_listTitles.push_back(m_title);
981 }
982 
1007  : vpDisplay()
1008  , m_impl(new Impl())
1009 { }
1010 
1015 {
1016  closeDisplay();
1017  delete m_impl;
1018 }
1019 
1028 void vpDisplayOpenCV::init(vpImage<unsigned char> &I, int x, int y, const std::string &title)
1029 {
1030  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
1031  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
1032  }
1034  init(I.getWidth(), I.getHeight(), x, y, title);
1035  I.display = this;
1037 }
1038 
1048 void vpDisplayOpenCV::init(vpImage<vpRGBa> &I, int x, int y, const std::string &title)
1049 {
1050  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
1051  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
1052  }
1053 
1055  init(I.getWidth(), I.getHeight(), x, y, title);
1056  I.display = this;
1058 }
1059 
1070 void vpDisplayOpenCV::init(unsigned int w, unsigned int h, int x, int y, const std::string &title)
1071 {
1072  setScale(m_scaleType, w, h);
1073 
1074  this->m_width = w / m_scale;
1075  this->m_height = h / m_scale;
1076 
1077  if (x != -1) {
1078  this->m_windowXPosition = x;
1079  }
1080  if (y != -1) {
1081  this->m_windowYPosition = y;
1082  }
1083 
1084  if (m_title.empty()) {
1085  if (!title.empty()) {
1086  m_title = std::string(title);
1087  }
1088  }
1090 
1092 }
1093 
1109 void vpDisplayOpenCV::setFont(const std::string & /* font */)
1110 {
1111  // Not yet implemented
1112 }
1113 
1121 void vpDisplayOpenCV::setTitle(const std::string & /* title */)
1122 {
1123  // Not implemented
1124 }
1125 
1135 void vpDisplayOpenCV::setWindowPosition(int winx, int winy)
1136 {
1138  this->m_windowXPosition = winx;
1139  this->m_windowYPosition = winy;
1140  cv::moveWindow(this->m_title.c_str(), winx, winy);
1141  }
1142  else {
1143  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1144  }
1145 }
1146 
1159 {
1161  m_impl->displayImage(I, m_scale, m_width, m_height);
1162  }
1163  else {
1164  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1165  }
1166 }
1167 
1184  unsigned int h)
1185 {
1187  m_impl->displayImageROI(I, iP, w, h, m_width, m_height, m_scale);
1188  }
1189  else {
1190  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1191  }
1192 }
1193 
1206 {
1207 
1209  m_impl->displayImage(I, m_scale, m_width, m_height);
1210  }
1211  else {
1212  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1213  }
1214 }
1215 
1231 void vpDisplayOpenCV::displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, unsigned int w, unsigned int h)
1232 {
1234  m_impl->displayImageROI(I, iP, w, h, m_width, m_height, m_scale);
1235  }
1236  else {
1237  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1238  }
1239 }
1240 
1246 void vpDisplayOpenCV::displayImage(const unsigned char * /* I */)
1247 {
1248  // not implemented
1249 }
1250 
1259 {
1261  m_impl->closeDisplay(m_title);
1262 
1263  m_title.clear();
1264 
1266  }
1267 }
1268 
1275 {
1277  m_impl->flushDisplay(m_title);
1278  }
1279  else {
1280  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1281  }
1282 }
1283 
1289 void vpDisplayOpenCV::flushDisplayROI(const vpImagePoint & /*iP*/, const unsigned int /*width*/,
1290  const unsigned int /*height*/)
1291 {
1293  m_impl->flushDisplayROI(m_title);
1294  }
1295  else {
1296  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1297  }
1298 }
1299 
1303 void vpDisplayOpenCV::clearDisplay(const vpColor & /* color */)
1304 {
1305  // Not implemented
1306 }
1307 
1315 void vpDisplayOpenCV::displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1316  unsigned int w, unsigned int h, unsigned int thickness)
1317 {
1319  m_impl->displayArrow(ip1, ip2, color, w, h, thickness, m_scale);
1320  }
1321  else {
1322  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1323  }
1324 }
1325 
1337 void vpDisplayOpenCV::displayText(const vpImagePoint &ip, const std::string &text, const vpColor &color)
1338 {
1340  m_impl->displayText(ip, text, color, m_scale);
1341  }
1342  else {
1343  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1344  }
1345 }
1346 
1359 void vpDisplayOpenCV::displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill,
1360  unsigned int thickness)
1361 {
1363  m_impl->displayCircle(center, radius, color, fill, thickness, m_scale);
1364  }
1365  else {
1366  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1367  }
1368 }
1369 
1377 void vpDisplayOpenCV::displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color,
1378  unsigned int thickness)
1379 {
1381  m_impl->displayCross(ip, size, color, thickness, m_scale);
1382  }
1383  else {
1384  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1385  }
1386 }
1387 
1395 void vpDisplayOpenCV::displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1396  unsigned int thickness)
1397 {
1399  m_impl->displayDotLine(ip1, ip2, color, thickness, m_scale);
1400  }
1401  else {
1402  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1403  }
1404 }
1405 
1412 void vpDisplayOpenCV::displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1413  unsigned int thickness)
1414 {
1416  m_impl->displayLine(ip1, ip2, color, thickness, m_scale);
1417  }
1418  else {
1419  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1420  }
1421 }
1422 
1429 void vpDisplayOpenCV::displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
1430 {
1432  m_impl->displayPoint(ip, color, thickness, m_scale);
1433  }
1434  else {
1435  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1436  }
1437 }
1438 
1454 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, unsigned int w, unsigned int h,
1455  const vpColor &color, bool fill, unsigned int thickness)
1456 {
1458  m_impl->displayRectangle(topLeft, w, h, color, fill, thickness, m_scale);
1459  }
1460  else {
1461  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1462  }
1463 }
1478 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, const vpImagePoint &bottomRight,
1479  const vpColor &color, bool fill, unsigned int thickness)
1480 {
1482  unsigned int w = bottomRight.get_u() - topLeft.get_u() + 1;
1483  unsigned int h = bottomRight.get_v() - topLeft.get_v() + 1;
1484  displayRectangle(topLeft, w, h, color, fill, thickness);
1485  }
1486  else {
1487  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1488  }
1489 }
1490 
1504 void vpDisplayOpenCV::displayRectangle(const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
1505 {
1507  displayRectangle(rectangle.getTopLeft(), rectangle.getWidth(), rectangle.getHeight(), color, fill, thickness);
1508  }
1509  else {
1510  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1511  }
1512 }
1513 
1529 bool vpDisplayOpenCV::getClick(bool blocking)
1530 {
1531  bool ret = false;
1533  vpImagePoint ip;
1535  ret = getClick(ip, button, blocking);
1536  }
1537  else {
1538  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1539  }
1540  return ret;
1541 }
1542 
1558 bool vpDisplayOpenCV::getClick(vpImagePoint &ip, bool blocking)
1559 {
1560  bool ret = false;
1561 
1564  ret = getClick(ip, button, blocking);
1565  }
1566  else {
1567  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1568  }
1569  return ret;
1570 }
1571 
1591 {
1592  bool ret = false;
1593 
1595  ret = m_impl->getClick(ip, button, blocking, m_title, m_scale);
1596  }
1597  else {
1598  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1599  }
1600  return ret;
1601 }
1602 
1625 {
1626  bool ret = false;
1628  ret = m_impl->getClickUp(ip, button, blocking, m_scale);
1629  }
1630  else {
1631  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1632  }
1633  return ret;
1634 }
1635 
1636 /*
1637  Gets the displayed image (including the overlay plane)
1638  and returns an RGBa image.
1639 */
1641 {
1642  m_impl->getImage(I);
1643 }
1644 
1661 {
1663  int delay;
1664  flushDisplay();
1665  if (blocking)
1666  delay = 0;
1667  else
1668  delay = 10;
1669 
1670  int key_pressed = cv::waitKey(delay);
1671 
1672  if (key_pressed == -1)
1673  return false;
1674  return true;
1675  }
1676  else {
1677  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1678  }
1679  // return false; // Never reached after throw()
1680 }
1681 
1700 bool vpDisplayOpenCV::getKeyboardEvent(std::string &key, bool blocking)
1701 {
1703  int delay;
1704  flushDisplay();
1705  if (blocking)
1706  delay = 0;
1707  else
1708  delay = 10;
1709 
1710  int key_pressed = cv::waitKey(delay);
1711  if (key_pressed == -1)
1712  return false;
1713  else {
1714  // std::cout << "Key pressed: \"" << key_pressed << "\"" << std::endl;
1715  std::stringstream ss;
1716  ss << key_pressed;
1717  key = ss.str();
1718  }
1719  return true;
1720  }
1721  else {
1722  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1723  }
1724  // return false; // Never reached after throw()
1725 }
1726 
1738 {
1739  bool ret = false;
1740 
1742  ret = m_impl->getPointerMotionEvent(ip, m_scale);
1743  }
1744 
1745  else {
1746  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1747  }
1748  return ret;
1749 }
1750 
1762 {
1764  m_impl->getPointerPosition(ip, m_scale);
1765  return false;
1766  }
1767  else {
1768  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1769  }
1770 }
1771 
1776 void vpDisplayOpenCV::getScreenSize(unsigned int &w, unsigned int &h)
1777 {
1778  w = h = 0;
1779 
1780 #if defined(VISP_HAVE_X11)
1781  vpDisplayX d;
1782  d.getScreenSize(w, h);
1783 #elif defined(VISP_HAVE_XRANDR)
1784  std::string command = "xrandr | grep '*'";
1785  FILE *fpipe = (FILE *)popen(command.c_str(), "r");
1786  char line[256];
1787  while (fgets(line, sizeof(line), fpipe)) {
1788  std::string str(line);
1789  std::size_t found = str.find("Failed");
1790 
1791  if (found == std::string::npos) {
1792  std::vector<std::string> elm;
1793  elm = vpIoTools::splitChain(str, " ");
1794  for (size_t i = 0; i < elm.size(); i++) {
1795  if (!elm[i].empty()) {
1796  std::vector<std::string> resolution = vpIoTools::splitChain(elm[i], "x");
1797  if (resolution.size() == 2) {
1798  std::istringstream sswidth(resolution[0]), ssheight(resolution[1]);
1799  sswidth >> w;
1800  ssheight >> h;
1801  break;
1802  }
1803  }
1804  }
1805  }
1806  }
1807  pclose(fpipe);
1808 #elif defined(_WIN32)
1809 #if !defined(WINRT)
1810  w = GetSystemMetrics(SM_CXSCREEN);
1811  h = GetSystemMetrics(SM_CYSCREEN);
1812 #else
1813  throw(vpException(vpException::functionNotImplementedError, "The function vpDisplayOpenCV::getScreenSize() is not "
1814  "implemented on winrt"));
1815 #endif
1816 #endif
1817 }
1818 
1823 {
1824  unsigned int width, height;
1825  getScreenSize(width, height);
1826  return width;
1827 }
1828 
1833 {
1834  unsigned int width, height;
1835  getScreenSize(width, height);
1836  return height;
1837 }
1838 
1839 END_VISP_NAMESPACE
1840 
1841 #elif !defined(VISP_BUILD_SHARED_LIBS)
1842 // Work around to avoid warning: libvisp_gui.a(vpDisplayOpenCV.cpp.o) has no symbols
1843 void dummy_vpDisplayOpenCV() { };
1844 #endif
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
static const vpColor white
Definition: vpColor.h:212
vpColorIdentifier id
Definition: vpColor.h:206
static const vpColor red
Definition: vpColor.h:217
static const vpColor darkGray
Definition: vpColor.h:215
static const vpColor cyan
Definition: vpColor.h:226
static const vpColor orange
Definition: vpColor.h:227
static const vpColor darkRed
Definition: vpColor.h:218
static const vpColor blue
Definition: vpColor.h:223
static const vpColor lightGray
Definition: vpColor.h:213
static const vpColor lightBlue
Definition: vpColor.h:222
static const vpColor darkGreen
Definition: vpColor.h:221
static const vpColor darkBlue
Definition: vpColor.h:224
static const vpColor purple
Definition: vpColor.h:228
static const vpColor lightGreen
Definition: vpColor.h:219
static const vpColor yellow
Definition: vpColor.h:225
@ id_lightBlue
Definition: vpColor.h:184
@ id_yellow
Definition: vpColor.h:190
@ id_darkGray
Definition: vpColor.h:170
@ id_green
Definition: vpColor.h:180
@ id_darkRed
Definition: vpColor.h:176
@ id_lightGray
Definition: vpColor.h:166
@ id_red
Definition: vpColor.h:174
@ id_lightRed
Definition: vpColor.h:172
@ id_white
Definition: vpColor.h:164
@ id_black
Definition: vpColor.h:162
@ id_blue
Definition: vpColor.h:186
@ id_darkGreen
Definition: vpColor.h:182
@ id_gray
Definition: vpColor.h:168
@ id_lightGreen
Definition: vpColor.h:178
@ id_purple
Definition: vpColor.h:196
@ id_orange
Definition: vpColor.h:194
@ id_cyan
Definition: vpColor.h:192
@ id_darkBlue
Definition: vpColor.h:188
@ id_unknown
Definition: vpColor.h:199
static const vpColor lightRed
Definition: vpColor.h:216
static const vpColor black
Definition: vpColor.h:211
static const vpColor green
Definition: vpColor.h:220
static const vpColor gray
Definition: vpColor.h:214
Error that can be emitted by the vpDisplay class and its derivatives.
@ notInitializedError
Display not initialized.
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1) VP_OVERRIDE
void flushDisplayROI(const vpImagePoint &iP, unsigned int width, unsigned int height) VP_OVERRIDE
virtual ~vpDisplayOpenCV() VP_OVERRIDE
bool getKeyboardEvent(bool blocking=true) VP_OVERRIDE
void displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1) VP_OVERRIDE
void setFont(const std::string &font) VP_OVERRIDE
void getImage(vpImage< vpRGBa > &I) VP_OVERRIDE
Get the window pixmap and put it in vpRGBa image.
void flushDisplay() VP_OVERRIDE
void getScreenSize(unsigned int &width, unsigned int &height) VP_OVERRIDE
void clearDisplay(const vpColor &color=vpColor::white) VP_OVERRIDE
bool getPointerMotionEvent(vpImagePoint &ip) VP_OVERRIDE
void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1) VP_OVERRIDE
void displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1) VP_OVERRIDE
unsigned int getScreenWidth() VP_OVERRIDE
void setTitle(const std::string &title) VP_OVERRIDE
void setWindowPosition(int winx, int winy) VP_OVERRIDE
void displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1) VP_OVERRIDE
void closeDisplay() VP_OVERRIDE
void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1) VP_OVERRIDE
void displayImage(const vpImage< unsigned char > &I) VP_OVERRIDE
bool getPointerPosition(vpImagePoint &ip) VP_OVERRIDE
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="") VP_OVERRIDE
void displayText(const vpImagePoint &ip, const std::string &text, const vpColor &color=vpColor::green) VP_OVERRIDE
bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking=true) VP_OVERRIDE
bool getClick(bool blocking=true) VP_OVERRIDE
void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1) VP_OVERRIDE
unsigned int getScreenHeight() VP_OVERRIDE
void displayImageROI(const vpImage< unsigned char > &I, const vpImagePoint &iP, unsigned int width, unsigned int height) VP_OVERRIDE
void getScreenSize(unsigned int &width, unsigned int &height) VP_OVERRIDE
Class that defines generic functionalities for display.
Definition: vpDisplay.h:178
unsigned int m_height
Definition: vpDisplay.h:930
vpScaleType m_scaleType
Definition: vpDisplay.h:933
unsigned int m_width
Definition: vpDisplay.h:929
static void display(const vpImage< unsigned char > &I)
int m_windowXPosition
display position
Definition: vpDisplay.h:926
std::string m_title
Definition: vpDisplay.h:931
int m_windowYPosition
display position
Definition: vpDisplay.h:928
unsigned int m_scale
Definition: vpDisplay.h:932
bool m_displayHasBeenInitialized
display has been initialized
Definition: vpDisplay.h:924
void setScale(vpScaleType scaleType, unsigned int width, unsigned int height)
Definition: vpDisplay.cpp:262
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ functionNotImplementedError
Function not implemented.
Definition: vpException.h:66
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
void set_j(double jj)
Definition: vpImagePoint.h:309
double get_j() const
Definition: vpImagePoint.h:125
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_i(double ii)
Definition: vpImagePoint.h:298
double get_u() const
Definition: vpImagePoint.h:136
void set_u(double u)
Definition: vpImagePoint.h:335
void set_v(double v)
Definition: vpImagePoint.h:346
double get_i() const
Definition: vpImagePoint.h:114
double get_v() const
Definition: vpImagePoint.h:147
unsigned int getWidth() const
Definition: vpImage.h:242
unsigned int getHeight() const
Definition: vpImage.h:181
vpDisplay * display
Definition: vpImage.h:136
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1661
static double sqr(double x)
Definition: vpMath.h:203
static int round(double x)
Definition: vpMath.h:410
Definition: vpRGBa.h:65
unsigned char B
Blue component.
Definition: vpRGBa.h:169
unsigned char R
Red component.
Definition: vpRGBa.h:167
unsigned char G
Green component.
Definition: vpRGBa.h:168
unsigned char A
Additionnal component.
Definition: vpRGBa.h:170
Defines a rectangle in the plane.
Definition: vpRect.h:79
double getWidth() const
Definition: vpRect.h:227
vpImagePoint getTopLeft() const
Definition: vpRect.h:199
double getHeight() const
Definition: vpRect.h:166