Visual Servoing Platform  version 3.6.1 under development (2024-06-19)
vpDisplayOpenCV.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 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 https://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 *****************************************************************************/
35 
41 #include <visp3/core/vpConfig.h>
42 
43 #if defined(HAVE_OPENCV_HIGHGUI)
44 
45 #include <cmath> // std::fabs
46 #include <iostream>
47 #include <limits> // numeric_limits
48 #include <stdio.h>
49 #include <stdlib.h>
50 
51 // Display stuff
52 #include <visp3/core/vpDisplay.h>
53 #include <visp3/core/vpImageTools.h>
54 #include <visp3/core/vpIoTools.h>
55 #include <visp3/core/vpMath.h>
56 #include <visp3/gui/vpDisplayOpenCV.h>
57 
58 // debug / exception
59 #include <visp3/core/vpDebug.h>
60 #include <visp3/core/vpDisplayException.h>
61 
62 #include <opencv2/core/core_c.h> // for CV_FILLED versus cv::FILLED
63 
64 #if defined(HAVE_OPENCV_IMGPROC)
65 #include <opencv2/imgproc/imgproc.hpp>
66 #endif
67 
68 #ifndef CV_RGB
69 #define CV_RGB(r, g, b) cv::Scalar((b), (g), (r), 0)
70 #endif
71 
72 #ifdef VISP_HAVE_X11
73 #include <visp3/gui/vpDisplayX.h> // to get screen resolution
74 #elif defined(_WIN32)
75 #include <windows.h>
76 #endif
77 
79 
80 std::vector<std::string> vpDisplayOpenCV::m_listTitles = std::vector<std::string>();
81 unsigned int vpDisplayOpenCV::m_nbWindows = 0;
82 
105  : vpDisplay(),
106  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
107  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
108  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
109  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
110  y_rbuttonup(0), rbuttonup(false)
111 {
112  setScale(scaleType, I.getWidth(), I.getHeight());
113  init(I);
114 }
115 
139 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<unsigned char> &I, int x, int y, const std::string &title,
140  vpScaleType scaleType)
141  : vpDisplay(),
142  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
143  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
144  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
145  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
146  y_rbuttonup(0), rbuttonup(false)
147 {
148  setScale(scaleType, I.getWidth(), I.getHeight());
149  init(I, x, y, title);
150 }
151 
171  :
172  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
173  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
174  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
175  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
176  y_rbuttonup(0), rbuttonup(false)
177 {
178  setScale(scaleType, I.getWidth(), I.getHeight());
179  init(I);
180 }
181 
202 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<vpRGBa> &I, int x, int y, const std::string &title, vpScaleType scaleType)
203  :
204  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
205  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
206  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
207  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
208  y_rbuttonup(0), rbuttonup(false)
209 {
210  setScale(scaleType, I.getWidth(), I.getHeight());
211  init(I, x, y, title);
212 }
213 
236 vpDisplayOpenCV::vpDisplayOpenCV(int x, int y, const std::string &title)
237  :
238  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
239  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
240  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
241  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
242  y_rbuttonup(0), rbuttonup(false)
243 {
244  m_windowXPosition = x;
245  m_windowYPosition = y;
246 
247  if (!title.empty()) {
248  m_title = title;
249  }
250  else {
251  std::ostringstream s;
252  s << m_nbWindows++;
253  m_title = std::string("Window ") + s.str();
254  }
255 
256  bool isInList;
257  do {
258  isInList = false;
259  for (size_t i = 0; i < m_listTitles.size(); i++) {
260  if (m_listTitles[i] == m_title) {
261  std::ostringstream s;
262  s << m_nbWindows++;
263  m_title = std::string("Window ") + s.str();
264  isInList = true;
265  break;
266  }
267  }
268  } while (isInList);
269 
270  m_listTitles.push_back(m_title);
271 }
272 
293  :
294  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
295  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
296  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
297  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
298  y_rbuttonup(0), rbuttonup(false)
299 { }
300 
305 {
306  closeDisplay();
307 }
308 
317 void vpDisplayOpenCV::init(vpImage<unsigned char> &I, int x, int y, const std::string &title)
318 {
319  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
320  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
321  }
323  init(I.getWidth(), I.getHeight(), x, y, title);
324  I.display = this;
326 }
327 
337 void vpDisplayOpenCV::init(vpImage<vpRGBa> &I, int x, int y, const std::string &title)
338 {
339  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
340  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
341  }
342 
344  init(I.getWidth(), I.getHeight(), x, y, title);
345  I.display = this;
347 }
348 
359 void vpDisplayOpenCV::init(unsigned int w, unsigned int h, int x, int y, const std::string &title)
360 {
361  setScale(m_scaleType, w, h);
362 
363  this->m_width = w / m_scale;
364  this->m_height = h / m_scale;
365 
366  if (x != -1) {
367  this->m_windowXPosition = x;
368  }
369  if (y != -1) {
370  this->m_windowYPosition = y;
371  }
372  int flags = cv::WINDOW_AUTOSIZE;
373 
374  if (m_title.empty()) {
375  if (!title.empty()) {
376  m_title = std::string(title);
377  }
378  else {
379 
380  std::ostringstream s;
381  s << m_nbWindows++;
382  m_title = std::string("Window ") + s.str();
383  }
384 
385  bool isInList;
386  do {
387  isInList = false;
388  for (size_t i = 0; i < m_listTitles.size(); i++) {
389  if (m_listTitles[i] == m_title) {
390  std::ostringstream s;
391  s << m_nbWindows++;
392  m_title = std::string("Window ") + s.str();
393  isInList = true;
394  break;
395  }
396  }
397  } while (isInList);
398 
399  m_listTitles.push_back(m_title);
400  }
401 
402  /* Create the window*/
403  cv::namedWindow(this->m_title, flags);
404  cv::moveWindow(this->m_title.c_str(), this->m_windowXPosition, this->m_windowYPosition);
405 
406  move = false;
407  lbuttondown = false;
408  mbuttondown = false;
409  rbuttondown = false;
410  lbuttonup = false;
411  mbuttonup = false;
412  rbuttonup = false;
413 
414  cv::setMouseCallback(this->m_title, on_mouse, this);
415  col = new cv::Scalar[vpColor::id_unknown];
416 
417  /* Create color */
418  vpColor pcolor; // Predefined colors
419  pcolor = vpColor::lightBlue;
420  col[vpColor::id_lightBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
421  pcolor = vpColor::blue;
422  col[vpColor::id_blue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
423  pcolor = vpColor::darkBlue;
424  col[vpColor::id_darkBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
425  pcolor = vpColor::lightRed;
426  col[vpColor::id_lightRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
427  pcolor = vpColor::red;
428  col[vpColor::id_red] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
429  pcolor = vpColor::darkRed;
430  col[vpColor::id_darkRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
431  pcolor = vpColor::lightGreen;
432  col[vpColor::id_lightGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
433  pcolor = vpColor::green;
434  col[vpColor::id_green] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
435  pcolor = vpColor::darkGreen;
436  col[vpColor::id_darkGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
437  pcolor = vpColor::yellow;
438  col[vpColor::id_yellow] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
439  pcolor = vpColor::cyan;
440  col[vpColor::id_cyan] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
441  pcolor = vpColor::orange;
442  col[vpColor::id_orange] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
443  pcolor = vpColor::purple;
444  col[vpColor::id_purple] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
445  pcolor = vpColor::white;
446  col[vpColor::id_white] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
447  pcolor = vpColor::black;
448  col[vpColor::id_black] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
449  pcolor = vpColor::lightGray;
450  col[vpColor::id_lightGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
451  pcolor = vpColor::gray;
452  col[vpColor::id_gray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
453  pcolor = vpColor::darkGray;
454  col[vpColor::id_darkGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
455 
456  int thickness = 1;
457  cv::Size fontSize;
458  int baseline;
459  fontSize = cv::getTextSize("A", font, fontScale, thickness, &baseline);
460 
461  fontHeight = fontSize.height + baseline;
463 }
464 
480 void vpDisplayOpenCV::setFont(const std::string & /* font */) { vpERROR_TRACE("Not yet implemented"); }
481 
489 void vpDisplayOpenCV::setTitle(const std::string & /* title */)
490 {
491  // static bool warn_displayed = false;
492  // if (! warn_displayed) {
493  // vpTRACE("Not implemented");
494  // warn_displayed = true;
495  // }
496 }
497 
507 void vpDisplayOpenCV::setWindowPosition(int winx, int winy)
508 {
510  this->m_windowXPosition = winx;
511  this->m_windowYPosition = winy;
512  cv::moveWindow(this->m_title.c_str(), winx, winy);
513  }
514  else {
515  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
516  }
517 }
530 {
532  int depth = CV_8U;
533  int channels = 3;
534  cv::Size size((int)m_width, (int)m_height);
535  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
536  m_background.cols != (int)m_width) {
537  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
538  }
539 
540  if (m_scale == 1) {
541  for (unsigned int i = 0; i < m_height; i++) {
542  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
543  for (unsigned int j = 0; j < m_width; j++) {
544  unsigned char val = I[i][j];
545  *(dst_24++) = val;
546  *(dst_24++) = val;
547  *(dst_24++) = val;
548  }
549  }
550  }
551  else {
552  for (unsigned int i = 0; i < m_height; i++) {
553  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
554  for (unsigned int j = 0; j < m_width; j++) {
555  unsigned char val = I[i * m_scale][j * m_scale];
556  *(dst_24++) = val;
557  *(dst_24++) = val;
558  *(dst_24++) = val;
559  }
560  }
561  }
562  }
563  else {
564  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
565  }
566 }
567 
584  unsigned int h)
585 {
587  int depth = CV_8U;
588  int channels = 3;
589  cv::Size size((int)m_width, (int)m_height);
590  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
591  m_background.cols != (int)m_width) {
592  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
593  }
594 
595  if (m_scale == 1) {
596  unsigned int i_min = (unsigned int)iP.get_i();
597  unsigned int j_min = (unsigned int)iP.get_j();
598  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
599  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
600  for (unsigned int i = i_min; i < i_max; i++) {
601  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
602  for (unsigned int j = j_min; j < j_max; j++) {
603  unsigned char val = I[i][j];
604  *(dst_24++) = val;
605  *(dst_24++) = val;
606  *(dst_24++) = val;
607  }
608  }
609  }
610  else {
611  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
612  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
613  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
614  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
615  for (int i = i_min; i < i_max; i++) {
616  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
617  for (int j = j_min; j < j_max; j++) {
618  unsigned char val = I[i * m_scale][j * m_scale];
619  *(dst_24++) = val;
620  *(dst_24++) = val;
621  *(dst_24++) = val;
622  }
623  }
624  }
625  }
626  else {
627  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
628  }
629 }
630 
643 {
644 
646  int depth = CV_8U;
647  int channels = 3;
648  cv::Size size((int)this->m_width, (int)this->m_height);
649  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
650  m_background.cols != (int)m_width) {
651  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
652  }
653 
654  if (m_scale == 1) {
655  for (unsigned int i = 0; i < m_height; i++) {
656  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
657  for (unsigned int j = 0; j < m_width; j++) {
658  vpRGBa val = I[i][j];
659  *(dst_24++) = val.B;
660  *(dst_24++) = val.G;
661  *(dst_24++) = val.R;
662  }
663  }
664  }
665  else {
666  for (unsigned int i = 0; i < m_height; i++) {
667  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
668  for (unsigned int j = 0; j < m_width; j++) {
669  vpRGBa val = I[i * m_scale][j * m_scale];
670  *(dst_24++) = val.B;
671  *(dst_24++) = val.G;
672  *(dst_24++) = val.R;
673  }
674  }
675  }
676  }
677  else {
678  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
679  }
680 }
681 
697 void vpDisplayOpenCV::displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, unsigned int w, unsigned int h)
698 {
700  int depth = CV_8U;
701  int channels = 3;
702  cv::Size size((int)this->m_width, (int)this->m_height);
703  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
704  m_background.cols != (int)m_width) {
705  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
706  }
707 
708  if (m_scale == 1) {
709  unsigned int i_min = (unsigned int)iP.get_i();
710  unsigned int j_min = (unsigned int)iP.get_j();
711  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
712  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
713  for (unsigned int i = i_min; i < i_max; i++) {
714  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
715  for (unsigned int j = j_min; j < j_max; j++) {
716  vpRGBa val = I[i][j];
717  *(dst_24++) = val.B;
718  *(dst_24++) = val.G;
719  *(dst_24++) = val.R;
720  }
721  }
722  }
723  else {
724  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
725  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
726  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
727  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
728  for (int i = i_min; i < i_max; i++) {
729  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
730  for (int j = j_min; j < j_max; j++) {
731  vpRGBa val = I[i * m_scale][j * m_scale];
732  *(dst_24++) = val.B;
733  *(dst_24++) = val.G;
734  *(dst_24++) = val.R;
735  }
736  }
737  }
738  }
739  else {
740  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
741  }
742 }
743 
749 void vpDisplayOpenCV::displayImage(const unsigned char * /* I */) { vpTRACE(" not implemented "); }
750 
759 {
760  if (col != nullptr) {
761  delete[] col;
762  col = nullptr;
763  }
765  cv::destroyWindow(this->m_title);
766  for (size_t i = 0; i < m_listTitles.size(); i++) {
767  if (m_title == m_listTitles[i]) {
768  m_listTitles.erase(m_listTitles.begin() + (long int)i);
769  break;
770  }
771  }
772 
773  m_title.clear();
774 
776  }
777 }
778 
785 {
787  cv::imshow(this->m_title, m_background);
788  cv::waitKey(5);
789  }
790  else {
791  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
792  }
793 }
794 
800 void vpDisplayOpenCV::flushDisplayROI(const vpImagePoint & /*iP*/, const unsigned int /*width*/,
801  const unsigned int /*height*/)
802 {
804  cv::imshow(this->m_title.c_str(), m_background);
805  cv::waitKey(5);
806  }
807  else {
808  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
809  }
810 }
811 
815 void vpDisplayOpenCV::clearDisplay(const vpColor & /* color */)
816 {
817  static bool warn_displayed = false;
818  if (!warn_displayed) {
819  vpTRACE("Not implemented");
820  warn_displayed = true;
821  }
822 }
823 
831 void vpDisplayOpenCV::displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
832  unsigned int w, unsigned int h, unsigned int thickness)
833 {
835  double a = ip2.get_i() - ip1.get_i();
836  double b = ip2.get_j() - ip1.get_j();
837  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
838 
839  // if ((a==0)&&(b==0))
840  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
841  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
842  // DisplayCrossLarge(i1,j1,3,col) ;
843  }
844  else {
845  a /= lg;
846  b /= lg;
847 
848  vpImagePoint ip3;
849  ip3.set_i(ip2.get_i() - w * a);
850  ip3.set_j(ip2.get_j() - w * b);
851 
852  vpImagePoint ip4;
853  ip4.set_i(ip3.get_i() - b * h);
854  ip4.set_j(ip3.get_j() + a * h);
855 
856  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
857  displayLine(ip2, ip4, color, thickness);
858 
859  ip4.set_i(ip3.get_i() + b * h);
860  ip4.set_j(ip3.get_j() - a * h);
861 
862  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
863  displayLine(ip2, ip4, color, thickness);
864 
865  displayLine(ip1, ip2, color, thickness);
866  }
867  }
868  else {
869  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
870  }
871 }
872 
884 void vpDisplayOpenCV::displayText(const vpImagePoint &ip, const std::string &text, const vpColor &color)
885 {
887  if (color.id < vpColor::id_unknown) {
888  cv::putText(m_background, text,
889  cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)),
890  font, fontScale, col[color.id]);
891  }
892  else {
893  cvcolor = CV_RGB(color.R, color.G, color.B);
894  cv::putText(m_background, text,
895  cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)),
896  font, fontScale, cvcolor);
897  }
898  }
899  else {
900  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
901  }
902 }
915 void vpDisplayOpenCV::displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill,
916  unsigned int thickness)
917 {
919  int x = vpMath::round(center.get_u() / m_scale);
920  int y = vpMath::round(center.get_v() / m_scale);
921  int r = static_cast<int>(radius / m_scale);
922  cv::Scalar cv_color;
923  if (color.id < vpColor::id_unknown) {
924  cv_color = col[color.id];
925  }
926  else {
927  cv_color = CV_RGB(color.R, color.G, color.B);
928  }
929 
930  if (fill == false) {
931  int cv_thickness = static_cast<int>(thickness);
932  cv::circle(m_background, cv::Point(x, y), r, cv_color, cv_thickness);
933  }
934  else {
935 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
936  int filled = cv::FILLED;
937 #else
938  int filled = CV_FILLED;
939 #endif
940  double opacity = static_cast<double>(color.A) / 255.0;
941  overlay([x, y, r, cv_color, filled](cv::Mat image) { cv::circle(image, cv::Point(x, y), r, cv_color, filled); },
942  opacity);
943  }
944  }
945  else {
946  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
947  }
948 }
949 
957 void vpDisplayOpenCV::displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color,
958  unsigned int thickness)
959 {
961  vpImagePoint top, bottom, left, right;
962  top.set_i(ip.get_i() - size / 2);
963  top.set_j(ip.get_j());
964  bottom.set_i(ip.get_i() + size / 2);
965  bottom.set_j(ip.get_j());
966  left.set_i(ip.get_i());
967  left.set_j(ip.get_j() - size / 2);
968  right.set_i(ip.get_i());
969  right.set_j(ip.get_j() + size / 2);
970  displayLine(top, bottom, color, thickness);
971  displayLine(left, right, color, thickness);
972  }
973  else {
974  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
975  }
976 }
977 
985 void vpDisplayOpenCV::displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
986  unsigned int thickness)
987 {
989  vpImagePoint ip1_ = ip1;
990  vpImagePoint ip2_ = ip2;
991 
992  double size = 10. * m_scale;
993  double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
994  bool vertical_line = (int)ip2_.get_j() == (int)ip1_.get_j();
995  if (vertical_line) {
996  if (ip2_.get_i() < ip1_.get_i()) {
997  std::swap(ip1_, ip2_);
998  }
999  }
1000  else if (ip2_.get_j() < ip1_.get_j()) {
1001  std::swap(ip1_, ip2_);
1002  }
1003 
1004  double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
1005  double deltaj = size / length * diff_j;
1006  double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
1007  double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
1008  double orig = ip1_.get_i() - slope * ip1_.get_j();
1009 
1010  if (vertical_line) {
1011  for (unsigned int i = (unsigned int)ip1_.get_i(); i < ip2_.get_i(); i += (unsigned int)(2 * deltai)) {
1012  double j = ip1_.get_j();
1013  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j), color, thickness);
1014  }
1015  }
1016  else {
1017  for (unsigned int j = (unsigned int)ip1_.get_j(); j < ip2_.get_j(); j += (unsigned int)(2 * deltaj)) {
1018  double i = slope * j + orig;
1019  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j + deltaj), color, thickness);
1020  }
1021  }
1022  }
1023  else {
1024  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1025  }
1026 }
1027 
1034 void vpDisplayOpenCV::displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1035  unsigned int thickness)
1036 {
1038  if (color.id < vpColor::id_unknown) {
1039  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1040  cv::Point(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), col[color.id],
1041  (int)thickness);
1042  }
1043  else {
1044  cvcolor = CV_RGB(color.R, color.G, color.B);
1045  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1046  cv::Point(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), cvcolor,
1047  (int)thickness);
1048  }
1049  }
1050  else {
1051  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1052  }
1053 }
1054 
1061 void vpDisplayOpenCV::displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
1062 {
1064  for (unsigned int i = 0; i < thickness; i++) {
1065  if (color.id < vpColor::id_unknown) {
1066  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1067  cv::Point(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1068  col[color.id], (int)thickness);
1069  }
1070  else {
1071  cvcolor = CV_RGB(color.R, color.G, color.B);
1072  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1073  cv::Point(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1074  cvcolor, (int)thickness);
1075  }
1076  }
1077  }
1078  else {
1079  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1080  }
1081 }
1082 
1098 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, unsigned int w, unsigned int h,
1099  const vpColor &color, bool fill, unsigned int thickness)
1100 {
1102  int left = vpMath::round(topLeft.get_u() / m_scale);
1103  int top = vpMath::round(topLeft.get_v() / m_scale);
1104  int right = vpMath::round((topLeft.get_u() + w) / m_scale);
1105  int bottom = vpMath::round((topLeft.get_v() + h) / m_scale);
1106  cv::Scalar cv_color;
1107  if (color.id < vpColor::id_unknown) {
1108  cv_color = col[color.id];
1109  }
1110  else {
1111  cv_color = CV_RGB(color.R, color.G, color.B);
1112  }
1113 
1114  if (fill == false) {
1115  int cv_thickness = static_cast<int>(thickness);
1116  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1117  }
1118  else {
1119 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1120  int filled = cv::FILLED;
1121 #else
1122  int filled = CV_FILLED;
1123 #endif
1124  double opacity = static_cast<double>(color.A) / 255.0;
1125  overlay([left, top, right, bottom, cv_color, filled](cv::Mat image) {
1126  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1127  },
1128  opacity);
1129  }
1130  }
1131  else {
1132  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1133  }
1134 }
1149 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, const vpImagePoint &bottomRight,
1150  const vpColor &color, bool fill, unsigned int thickness)
1151 {
1153  int left = vpMath::round(topLeft.get_u() / m_scale);
1154  int top = vpMath::round(topLeft.get_v() / m_scale);
1155  int right = vpMath::round(bottomRight.get_u() / m_scale);
1156  int bottom = vpMath::round(bottomRight.get_v() / m_scale);
1157  cv::Scalar cv_color;
1158  if (color.id < vpColor::id_unknown) {
1159  cv_color = col[color.id];
1160  }
1161  else {
1162  cv_color = CV_RGB(color.R, color.G, color.B);
1163  }
1164 
1165  if (fill == false) {
1166  int cv_thickness = static_cast<int>(thickness);
1167  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1168  }
1169  else {
1170 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1171  int filled = cv::FILLED;
1172 #else
1173  int filled = CV_FILLED;
1174 #endif
1175  double opacity = static_cast<double>(color.A) / 255.0;
1176  overlay([left, top, right, bottom, cv_color, filled](cv::Mat image) {
1177  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1178  },
1179  opacity);
1180  }
1181  }
1182  else {
1183  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1184  }
1185 }
1186 
1200 void vpDisplayOpenCV::displayRectangle(const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
1201 {
1203  int left = vpMath::round(rectangle.getLeft() / m_scale);
1204  int top = vpMath::round(rectangle.getTop() / m_scale);
1205  int right = vpMath::round(rectangle.getRight() / m_scale);
1206  int bottom = vpMath::round(rectangle.getBottom() / m_scale);
1207  cv::Scalar cv_color;
1208  if (color.id < vpColor::id_unknown) {
1209  cv_color = col[color.id];
1210  }
1211  else {
1212  cv_color = CV_RGB(color.R, color.G, color.B);
1213  }
1214 
1215  if (fill == false) {
1216  int cv_thickness = static_cast<int>(thickness);
1217  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1218  }
1219  else {
1220 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1221  int filled = cv::FILLED;
1222 #else
1223  int filled = CV_FILLED;
1224 #endif
1225  double opacity = static_cast<double>(color.A) / 255.0;
1226  overlay([left, top, right, bottom, cv_color, filled](cv::Mat image) {
1227  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1228  },
1229  opacity);
1230  }
1231  }
1232  else {
1233  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1234  }
1235 }
1236 
1252 bool vpDisplayOpenCV::getClick(bool blocking)
1253 {
1254  bool ret = false;
1256  flushDisplay();
1257  if (blocking) {
1258  lbuttondown = false;
1259  mbuttondown = false;
1260  rbuttondown = false;
1261  }
1262  do {
1263  if (lbuttondown) {
1264  ret = true;
1265  lbuttondown = false;
1266  }
1267  if (mbuttondown) {
1268  ret = true;
1269  mbuttondown = false;
1270  }
1271  if (rbuttondown) {
1272  ret = true;
1273  rbuttondown = false;
1274  }
1275  if (blocking) {
1276  cv::waitKey(10);
1277  }
1278  } while (ret == false && blocking == true);
1279  }
1280  else {
1281  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1282  }
1283  return ret;
1284 }
1285 
1301 bool vpDisplayOpenCV::getClick(vpImagePoint &ip, bool blocking)
1302 {
1303  bool ret = false;
1304 
1306  flushDisplay();
1307 
1308  double u, v;
1309 
1310  if (blocking) {
1311  lbuttondown = false;
1312  mbuttondown = false;
1313  rbuttondown = false;
1314  }
1315  do {
1316  if (lbuttondown) {
1317  ret = true;
1318  u = (unsigned int)x_lbuttondown * m_scale;
1319  v = (unsigned int)y_lbuttondown * m_scale;
1320  ip.set_u(u);
1321  ip.set_v(v);
1322  lbuttondown = false;
1323  }
1324  if (mbuttondown) {
1325  ret = true;
1326  u = (unsigned int)x_mbuttondown * m_scale;
1327  v = (unsigned int)y_mbuttondown * m_scale;
1328  ip.set_u(u);
1329  ip.set_v(v);
1330  mbuttondown = false;
1331  }
1332  if (rbuttondown) {
1333  ret = true;
1334  u = (unsigned int)x_rbuttondown * m_scale;
1335  v = (unsigned int)y_rbuttondown * m_scale;
1336  ip.set_u(u);
1337  ip.set_v(v);
1338  rbuttondown = false;
1339  }
1340  if (blocking) {
1341  cv::waitKey(10);
1342  }
1343  } while (ret == false && blocking == true);
1344  }
1345  else {
1346  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1347  }
1348  return ret;
1349 }
1350 
1370 {
1371  bool ret = false;
1372 
1374  // flushDisplay() ;
1375  double u, v;
1376  if (blocking) {
1377  lbuttondown = false;
1378  mbuttondown = false;
1379  rbuttondown = false;
1380  }
1381  do {
1382  if (lbuttondown) {
1383  ret = true;
1384  u = (unsigned int)x_lbuttondown * m_scale;
1385  v = (unsigned int)y_lbuttondown * m_scale;
1386  ip.set_u(u);
1387  ip.set_v(v);
1388  button = vpMouseButton::button1;
1389  lbuttondown = false;
1390  }
1391  if (mbuttondown) {
1392  ret = true;
1393  u = (unsigned int)x_mbuttondown * m_scale;
1394  v = (unsigned int)y_mbuttondown * m_scale;
1395  ip.set_u(u);
1396  ip.set_v(v);
1397  button = vpMouseButton::button2;
1398  mbuttondown = false;
1399  }
1400  if (rbuttondown) {
1401  ret = true;
1402  u = (unsigned int)x_rbuttondown * m_scale;
1403  v = (unsigned int)y_rbuttondown * m_scale;
1404  ip.set_u(u);
1405  ip.set_v(v);
1406  button = vpMouseButton::button3;
1407  rbuttondown = false;
1408  }
1409  if (blocking) {
1410  cv::waitKey(10);
1411  }
1412  } while (ret == false && blocking == true);
1413  }
1414  else {
1415  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1416  }
1417  return ret;
1418 }
1419 
1442 {
1443  bool ret = false;
1445  // flushDisplay() ;
1446  double u, v;
1447  if (blocking) {
1448  lbuttonup = false;
1449  mbuttonup = false;
1450  rbuttonup = false;
1451  }
1452  do {
1453  if (lbuttonup) {
1454  ret = true;
1455  u = (unsigned int)x_lbuttonup * m_scale;
1456  v = (unsigned int)y_lbuttonup * m_scale;
1457  ip.set_u(u);
1458  ip.set_v(v);
1459  button = vpMouseButton::button1;
1460  lbuttonup = false;
1461  }
1462  if (mbuttonup) {
1463  ret = true;
1464  u = (unsigned int)x_mbuttonup * m_scale;
1465  v = (unsigned int)y_mbuttonup * m_scale;
1466  ip.set_u(u);
1467  ip.set_v(v);
1468  button = vpMouseButton::button2;
1469  mbuttonup = false;
1470  }
1471  if (rbuttonup) {
1472  ret = true;
1473  u = (unsigned int)x_rbuttonup * m_scale;
1474  v = (unsigned int)y_rbuttonup * m_scale;
1475  ip.set_u(u);
1476  ip.set_v(v);
1477  button = vpMouseButton::button3;
1478  rbuttonup = false;
1479  }
1480  if (blocking) {
1481  cv::waitKey(10);
1482  }
1483  } while (ret == false && blocking == true);
1484  }
1485  else {
1486  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1487  }
1488  return ret;
1489 }
1490 
1491 /*
1492  Gets the displayed image (including the overlay plane)
1493  and returns an RGBa image.
1494 */
1496 {
1497  vpImageConvert::convert(m_background, I);
1498  // should certainly be optimized.
1499 }
1500 
1501 void vpDisplayOpenCV::on_mouse(int event, int x, int y, int /*flags*/, void *display)
1502 {
1503  vpDisplayOpenCV *disp = static_cast<vpDisplayOpenCV *>(display);
1504  switch (event) {
1505  case cv::EVENT_MOUSEMOVE:
1506  {
1507  disp->move = true;
1508  disp->x_move = x;
1509  disp->y_move = y;
1510  break;
1511  }
1512  case cv::EVENT_LBUTTONDOWN:
1513  {
1514  disp->lbuttondown = true;
1515  disp->x_lbuttondown = x;
1516  disp->y_lbuttondown = y;
1517  break;
1518  }
1519  case cv::EVENT_MBUTTONDOWN:
1520  {
1521  disp->mbuttondown = true;
1522  disp->x_mbuttondown = x;
1523  disp->y_mbuttondown = y;
1524  break;
1525  }
1526  case cv::EVENT_RBUTTONDOWN:
1527  {
1528  disp->rbuttondown = true;
1529  disp->x_rbuttondown = x;
1530  disp->y_rbuttondown = y;
1531  break;
1532  }
1533  case cv::EVENT_LBUTTONUP:
1534  {
1535  disp->lbuttonup = true;
1536  disp->x_lbuttonup = x;
1537  disp->y_lbuttonup = y;
1538  break;
1539  }
1540  case cv::EVENT_MBUTTONUP:
1541  {
1542  disp->mbuttonup = true;
1543  disp->x_mbuttonup = x;
1544  disp->y_mbuttonup = y;
1545  break;
1546  }
1547  case cv::EVENT_RBUTTONUP:
1548  {
1549  disp->rbuttonup = true;
1550  disp->x_rbuttonup = x;
1551  disp->y_rbuttonup = y;
1552  break;
1553  }
1554 
1555  default:
1556  break;
1557  }
1558 }
1559 
1576 {
1578  int delay;
1579  flushDisplay();
1580  if (blocking)
1581  delay = 0;
1582  else
1583  delay = 10;
1584 
1585  int key_pressed = cv::waitKey(delay);
1586 
1587  if (key_pressed == -1)
1588  return false;
1589  return true;
1590  }
1591  else {
1592  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1593  }
1594  // return false; // Never reached after throw()
1595 }
1614 bool vpDisplayOpenCV::getKeyboardEvent(std::string &key, bool blocking)
1615 {
1617  int delay;
1618  flushDisplay();
1619  if (blocking)
1620  delay = 0;
1621  else
1622  delay = 10;
1623 
1624  int key_pressed = cv::waitKey(delay);
1625  if (key_pressed == -1)
1626  return false;
1627  else {
1628  // std::cout << "Key pressed: \"" << key_pressed << "\"" << std::endl;
1629  std::stringstream ss;
1630  ss << key_pressed;
1631  key = ss.str();
1632  }
1633  return true;
1634  }
1635  else {
1636  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1637  }
1638  // return false; // Never reached after throw()
1639 }
1640 
1652 {
1653  bool ret = false;
1654 
1656  // flushDisplay() ;
1657  if (move) {
1658  ret = true;
1659  double u = (unsigned int)x_move / m_scale;
1660  double v = (unsigned int)y_move / m_scale;
1661  ip.set_u(u);
1662  ip.set_v(v);
1663  move = false;
1664  }
1665  }
1666 
1667  else {
1668  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1669  }
1670  return ret;
1671 }
1672 
1684 {
1686  bool moved = getPointerMotionEvent(ip);
1687  if (!moved) {
1688  double u, v;
1689  u = (unsigned int)x_move / m_scale;
1690  v = (unsigned int)y_move / m_scale;
1691  ip.set_u(u);
1692  ip.set_v(v);
1693  }
1694  return false;
1695  }
1696  else {
1697  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1698  }
1699 }
1700 
1705 void vpDisplayOpenCV::getScreenSize(unsigned int &w, unsigned int &h)
1706 {
1707  w = h = 0;
1708 
1709 #if defined(VISP_HAVE_X11)
1710  vpDisplayX d;
1711  d.getScreenSize(w, h);
1712 #elif defined(VISP_HAVE_XRANDR)
1713  std::string command = "xrandr | grep '*'";
1714  FILE *fpipe = (FILE *)popen(command.c_str(), "r");
1715  char line[256];
1716  while (fgets(line, sizeof(line), fpipe)) {
1717  std::string str(line);
1718  std::size_t found = str.find("Failed");
1719 
1720  if (found == std::string::npos) {
1721  std::vector<std::string> elm;
1722  elm = vpIoTools::splitChain(str, " ");
1723  for (size_t i = 0; i < elm.size(); i++) {
1724  if (!elm[i].empty()) {
1725  std::vector<std::string> resolution = vpIoTools::splitChain(elm[i], "x");
1726  if (resolution.size() == 2) {
1727  std::istringstream sswidth(resolution[0]), ssheight(resolution[1]);
1728  sswidth >> w;
1729  ssheight >> h;
1730  break;
1731  }
1732  }
1733  }
1734  }
1735  }
1736  pclose(fpipe);
1737 #elif defined(_WIN32)
1738 #if !defined(WINRT)
1739  w = GetSystemMetrics(SM_CXSCREEN);
1740  h = GetSystemMetrics(SM_CYSCREEN);
1741 #else
1742  throw(vpException(vpException::functionNotImplementedError, "The function vpDisplayOpenCV::getScreenSize() is not "
1743  "implemented on winrt"));
1744 #endif
1745 #endif
1746 }
1747 
1752 {
1753  unsigned int width, height;
1754  getScreenSize(width, height);
1755  return width;
1756 }
1757 
1762 {
1763  unsigned int width, height;
1764  getScreenSize(width, height);
1765  return height;
1766 }
1767 
1773 void vpDisplayOpenCV::overlay(std::function<void(cv::Mat &)> overlay_function, double opacity)
1774 {
1775  // Initialize overlay layer for transparency
1776  cv::Mat overlay;
1777  if (opacity < 1.0) {
1778  // Deep copy
1779  overlay = m_background.clone();
1780  }
1781  else {
1782  // Shallow copy
1783  overlay = m_background;
1784  }
1785 
1786  overlay_function(overlay);
1787 
1788  // Blend background and overlay
1789  if (opacity < 1.0) {
1790  cv::addWeighted(overlay, opacity, m_background, 1.0 - opacity, 0.0, m_background);
1791  }
1792 }
1793 
1795 
1796 #elif !defined(VISP_BUILD_SHARED_LIBS)
1797 // Work around to avoid warning: libvisp_gui.a(vpDisplayOpenCV.cpp.o) has no symbols
1798 void dummy_vpDisplayOpenCV() { };
1799 #endif
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:153
static const vpColor white
Definition: vpColor.h:208
vpColorIdentifier id
Definition: vpColor.h:202
static const vpColor red
Definition: vpColor.h:213
static const vpColor darkGray
Definition: vpColor.h:211
static const vpColor cyan
Definition: vpColor.h:222
static const vpColor orange
Definition: vpColor.h:223
static const vpColor darkRed
Definition: vpColor.h:214
static const vpColor blue
Definition: vpColor.h:219
static const vpColor lightGray
Definition: vpColor.h:209
static const vpColor lightBlue
Definition: vpColor.h:218
static const vpColor darkGreen
Definition: vpColor.h:217
static const vpColor darkBlue
Definition: vpColor.h:220
static const vpColor purple
Definition: vpColor.h:224
static const vpColor lightGreen
Definition: vpColor.h:215
static const vpColor yellow
Definition: vpColor.h:221
@ id_lightBlue
Definition: vpColor.h:180
@ id_yellow
Definition: vpColor.h:186
@ id_darkGray
Definition: vpColor.h:166
@ id_green
Definition: vpColor.h:176
@ id_darkRed
Definition: vpColor.h:172
@ id_lightGray
Definition: vpColor.h:162
@ id_red
Definition: vpColor.h:170
@ id_lightRed
Definition: vpColor.h:168
@ id_white
Definition: vpColor.h:160
@ id_black
Definition: vpColor.h:158
@ id_blue
Definition: vpColor.h:182
@ id_darkGreen
Definition: vpColor.h:178
@ id_gray
Definition: vpColor.h:164
@ id_lightGreen
Definition: vpColor.h:174
@ id_purple
Definition: vpColor.h:192
@ id_orange
Definition: vpColor.h:190
@ id_cyan
Definition: vpColor.h:188
@ id_darkBlue
Definition: vpColor.h:184
@ id_unknown
Definition: vpColor.h:195
static const vpColor lightRed
Definition: vpColor.h:212
static const vpColor black
Definition: vpColor.h:207
static const vpColor green
Definition: vpColor.h:216
static const vpColor gray
Definition: vpColor.h:210
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 setTitle(const std::string &title) 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
void overlay(std::function< void(cv::Mat &)> overlay_function, double opacity)
void flushDisplayROI(const vpImagePoint &iP, unsigned int width, unsigned int height) vp_override
unsigned int getScreenHeight() vp_override
void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1) vp_override
void displayImage(const vpImage< unsigned char > &I) vp_override
bool getKeyboardEvent(bool blocking=true) vp_override
void closeDisplay() vp_override
void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1) vp_override
void setFont(const std::string &font) 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
virtual ~vpDisplayOpenCV() vp_override
unsigned int getScreenWidth() vp_override
void getScreenSize(unsigned int &width, unsigned int &height) vp_override
void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1) vp_override
void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1) vp_override
static void on_mouse(int event, int x, int y, int flags, void *param)
bool getClick(bool blocking=true) vp_override
void displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1) vp_override
bool getPointerMotionEvent(vpImagePoint &ip) vp_override
void setWindowPosition(int winx, int winy) vp_override
void displayImageROI(const vpImage< unsigned char > &I, const vpImagePoint &iP, unsigned int width, unsigned int height) vp_override
bool getPointerPosition(vpImagePoint &ip) vp_override
void getImage(vpImage< vpRGBa > &I) vp_override
Get the window pixmap and put it in vpRGBa image.
bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking=true) vp_override
void displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1) vp_override
void clearDisplay(const vpColor &color=vpColor::white) vp_override
void flushDisplay() vp_override
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:131
void getScreenSize(unsigned int &width, unsigned int &height) vp_override
Class that defines generic functionalities for display.
Definition: vpDisplay.h:174
unsigned int m_height
Definition: vpDisplay.h:922
vpScaleType m_scaleType
Definition: vpDisplay.h:925
unsigned int m_width
Definition: vpDisplay.h:921
static void display(const vpImage< unsigned char > &I)
int m_windowXPosition
display position
Definition: vpDisplay.h:918
std::string m_title
Definition: vpDisplay.h:923
int m_windowYPosition
display position
Definition: vpDisplay.h:920
unsigned int m_scale
Definition: vpDisplay.h:924
bool m_displayHasBeenInitialized
display has been initialized
Definition: vpDisplay.h:916
void setScale(vpScaleType scaleType, unsigned int width, unsigned int height)
Definition: vpDisplay.cpp:255
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:305
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:294
double get_u() const
Definition: vpImagePoint.h:136
void set_u(double u)
Definition: vpImagePoint.h:331
void set_v(double v)
Definition: vpImagePoint.h:342
double get_i() const
Definition: vpImagePoint.h:114
double get_v() const
Definition: vpImagePoint.h:147
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:185
vpDisplay * display
Definition: vpImage.h:141
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:2440
static double sqr(double x)
Definition: vpMath.h:203
static int round(double x)
Definition: vpMath.h:407
Definition: vpRGBa.h:63
unsigned char B
Blue component.
Definition: vpRGBa.h:141
unsigned char R
Red component.
Definition: vpRGBa.h:139
unsigned char G
Green component.
Definition: vpRGBa.h:140
unsigned char A
Additionnal component.
Definition: vpRGBa.h:142
Defines a rectangle in the plane.
Definition: vpRect.h:79
double getLeft() const
Definition: vpRect.h:173
double getRight() const
Definition: vpRect.h:179
double getBottom() const
Definition: vpRect.h:97
double getTop() const
Definition: vpRect.h:192
#define vpTRACE
Definition: vpDebug.h:408
#define vpERROR_TRACE
Definition: vpDebug.h:385