Visual Servoing Platform  version 3.6.1 under development (2024-12-03)
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 *****************************************************************************/
34 
40 #include <visp3/core/vpConfig.h>
41 
42 #if defined(HAVE_OPENCV_HIGHGUI)
43 
44 #include <cmath> // std::fabs
45 #include <iostream>
46 #include <limits> // numeric_limits
47 #include <stdio.h>
48 #include <stdlib.h>
49 
50 // Display stuff
51 #include <visp3/core/vpDisplay.h>
52 #include <visp3/core/vpImageTools.h>
53 #include <visp3/core/vpIoTools.h>
54 #include <visp3/core/vpMath.h>
55 #include <visp3/gui/vpDisplayOpenCV.h>
56 
57 // debug / exception
58 #include <visp3/core/vpDisplayException.h>
59 
60 #include <opencv2/core/core_c.h> // for CV_FILLED versus cv::FILLED
61 
62 #if defined(HAVE_OPENCV_IMGPROC)
63 #include <opencv2/imgproc/imgproc.hpp>
64 #endif
65 
66 #ifndef CV_RGB
67 #define CV_RGB(r, g, b) cv::Scalar((b), (g), (r), 0)
68 #endif
69 
70 #ifdef VISP_HAVE_X11
71 #include <visp3/gui/vpDisplayX.h> // to get screen resolution
72 #elif defined(_WIN32)
73 #include <windows.h>
74 #endif
75 
76 BEGIN_VISP_NAMESPACE
77 
78 std::vector<std::string> vpDisplayOpenCV::m_listTitles = std::vector<std::string>();
79 unsigned int vpDisplayOpenCV::m_nbWindows = 0;
80 
103  : vpDisplay(),
104  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
105  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
106  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
107  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
108  y_rbuttonup(0), rbuttonup(false)
109 {
110  setScale(scaleType, I.getWidth(), I.getHeight());
111  init(I);
112 }
113 
137 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<unsigned char> &I, int x, int y, const std::string &title,
138  vpScaleType scaleType)
139  : vpDisplay(),
140  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
141  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
142  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
143  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
144  y_rbuttonup(0), rbuttonup(false)
145 {
146  setScale(scaleType, I.getWidth(), I.getHeight());
147  init(I, x, y, title);
148 }
149 
169  :
170  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
171  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
172  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
173  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
174  y_rbuttonup(0), rbuttonup(false)
175 {
176  setScale(scaleType, I.getWidth(), I.getHeight());
177  init(I);
178 }
179 
200 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<vpRGBa> &I, int x, int y, const std::string &title, vpScaleType scaleType)
201  :
202  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
203  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
204  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
205  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
206  y_rbuttonup(0), rbuttonup(false)
207 {
208  setScale(scaleType, I.getWidth(), I.getHeight());
209  init(I, x, y, title);
210 }
211 
238 vpDisplayOpenCV::vpDisplayOpenCV(int x, int y, const std::string &title)
239  :
240  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
241  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
242  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
243  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
244  y_rbuttonup(0), rbuttonup(false)
245 {
246  m_windowXPosition = x;
247  m_windowYPosition = y;
248 
249  if (!title.empty()) {
250  m_title = title;
251  }
252  else {
253  std::ostringstream s;
254  s << m_nbWindows++;
255  m_title = std::string("Window ") + s.str();
256  }
257 
258  bool isInList;
259  do {
260  isInList = false;
261  for (size_t i = 0; i < m_listTitles.size(); i++) {
262  if (m_listTitles[i] == m_title) {
263  std::ostringstream s;
264  s << m_nbWindows++;
265  m_title = std::string("Window ") + s.str();
266  isInList = true;
267  break;
268  }
269  }
270  } while (isInList);
271 
272  m_listTitles.push_back(m_title);
273 }
274 
299  :
300  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
301  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
302  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
303  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
304  y_rbuttonup(0), rbuttonup(false)
305 { }
306 
311 {
312  closeDisplay();
313 }
314 
323 void vpDisplayOpenCV::init(vpImage<unsigned char> &I, int x, int y, const std::string &title)
324 {
325  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
326  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
327  }
329  init(I.getWidth(), I.getHeight(), x, y, title);
330  I.display = this;
332 }
333 
343 void vpDisplayOpenCV::init(vpImage<vpRGBa> &I, int x, int y, const std::string &title)
344 {
345  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
346  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
347  }
348 
350  init(I.getWidth(), I.getHeight(), x, y, title);
351  I.display = this;
353 }
354 
365 void vpDisplayOpenCV::init(unsigned int w, unsigned int h, int x, int y, const std::string &title)
366 {
367  setScale(m_scaleType, w, h);
368 
369  this->m_width = w / m_scale;
370  this->m_height = h / m_scale;
371 
372  if (x != -1) {
373  this->m_windowXPosition = x;
374  }
375  if (y != -1) {
376  this->m_windowYPosition = y;
377  }
378  int flags = cv::WINDOW_AUTOSIZE;
379 
380  if (m_title.empty()) {
381  if (!title.empty()) {
382  m_title = std::string(title);
383  }
384  else {
385 
386  std::ostringstream s;
387  s << m_nbWindows++;
388  m_title = std::string("Window ") + s.str();
389  }
390 
391  bool isInList;
392  do {
393  isInList = false;
394  for (size_t i = 0; i < m_listTitles.size(); i++) {
395  if (m_listTitles[i] == m_title) {
396  std::ostringstream s;
397  s << m_nbWindows++;
398  m_title = std::string("Window ") + s.str();
399  isInList = true;
400  break;
401  }
402  }
403  } while (isInList);
404 
405  m_listTitles.push_back(m_title);
406  }
407 
408  /* Create the window*/
409  cv::namedWindow(this->m_title, flags);
410  cv::moveWindow(this->m_title.c_str(), this->m_windowXPosition, this->m_windowYPosition);
411 
412  move = false;
413  lbuttondown = false;
414  mbuttondown = false;
415  rbuttondown = false;
416  lbuttonup = false;
417  mbuttonup = false;
418  rbuttonup = false;
419 
420  cv::setMouseCallback(this->m_title, on_mouse, this);
421  col = new cv::Scalar[vpColor::id_unknown];
422 
423  /* Create color */
424  vpColor pcolor; // Predefined colors
425  pcolor = vpColor::lightBlue;
426  col[vpColor::id_lightBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
427  pcolor = vpColor::blue;
428  col[vpColor::id_blue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
429  pcolor = vpColor::darkBlue;
430  col[vpColor::id_darkBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
431  pcolor = vpColor::lightRed;
432  col[vpColor::id_lightRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
433  pcolor = vpColor::red;
434  col[vpColor::id_red] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
435  pcolor = vpColor::darkRed;
436  col[vpColor::id_darkRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
437  pcolor = vpColor::lightGreen;
438  col[vpColor::id_lightGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
439  pcolor = vpColor::green;
440  col[vpColor::id_green] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
441  pcolor = vpColor::darkGreen;
442  col[vpColor::id_darkGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
443  pcolor = vpColor::yellow;
444  col[vpColor::id_yellow] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
445  pcolor = vpColor::cyan;
446  col[vpColor::id_cyan] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
447  pcolor = vpColor::orange;
448  col[vpColor::id_orange] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
449  pcolor = vpColor::purple;
450  col[vpColor::id_purple] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
451  pcolor = vpColor::white;
452  col[vpColor::id_white] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
453  pcolor = vpColor::black;
454  col[vpColor::id_black] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
455  pcolor = vpColor::lightGray;
456  col[vpColor::id_lightGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
457  pcolor = vpColor::gray;
458  col[vpColor::id_gray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
459  pcolor = vpColor::darkGray;
460  col[vpColor::id_darkGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
461 
462  int thickness = 1;
463  cv::Size fontSize;
464  int baseline;
465  fontSize = cv::getTextSize("A", font, fontScale, thickness, &baseline);
466 
467  fontHeight = fontSize.height + baseline;
469 }
470 
486 void vpDisplayOpenCV::setFont(const std::string & /* font */)
487 {
488  // Not yet implemented
489 }
490 
498 void vpDisplayOpenCV::setTitle(const std::string & /* title */)
499 {
500  // Not implemented
501 }
502 
512 void vpDisplayOpenCV::setWindowPosition(int winx, int winy)
513 {
515  this->m_windowXPosition = winx;
516  this->m_windowYPosition = winy;
517  cv::moveWindow(this->m_title.c_str(), winx, winy);
518  }
519  else {
520  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
521  }
522 }
535 {
537  int depth = CV_8U;
538  int channels = 3;
539  cv::Size size((int)m_width, (int)m_height);
540  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
541  m_background.cols != (int)m_width) {
542  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
543  }
544 
545  if (m_scale == 1) {
546  for (unsigned int i = 0; i < m_height; i++) {
547  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
548  for (unsigned int j = 0; j < m_width; j++) {
549  unsigned char val = I[i][j];
550  *(dst_24++) = val;
551  *(dst_24++) = val;
552  *(dst_24++) = val;
553  }
554  }
555  }
556  else {
557  for (unsigned int i = 0; i < m_height; i++) {
558  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
559  for (unsigned int j = 0; j < m_width; j++) {
560  unsigned char val = I[i * m_scale][j * m_scale];
561  *(dst_24++) = val;
562  *(dst_24++) = val;
563  *(dst_24++) = val;
564  }
565  }
566  }
567  }
568  else {
569  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
570  }
571 }
572 
589  unsigned int h)
590 {
592  int depth = CV_8U;
593  int channels = 3;
594  cv::Size size((int)m_width, (int)m_height);
595  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
596  m_background.cols != (int)m_width) {
597  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
598  }
599 
600  if (m_scale == 1) {
601  unsigned int i_min = (unsigned int)iP.get_i();
602  unsigned int j_min = (unsigned int)iP.get_j();
603  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
604  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
605  for (unsigned int i = i_min; i < i_max; i++) {
606  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
607  for (unsigned int j = j_min; j < j_max; j++) {
608  unsigned char val = I[i][j];
609  *(dst_24++) = val;
610  *(dst_24++) = val;
611  *(dst_24++) = val;
612  }
613  }
614  }
615  else {
616  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
617  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
618  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
619  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
620  for (int i = i_min; i < i_max; i++) {
621  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
622  for (int j = j_min; j < j_max; j++) {
623  unsigned char val = I[i * m_scale][j * m_scale];
624  *(dst_24++) = val;
625  *(dst_24++) = val;
626  *(dst_24++) = val;
627  }
628  }
629  }
630  }
631  else {
632  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
633  }
634 }
635 
648 {
649 
651  int depth = CV_8U;
652  int channels = 3;
653  cv::Size size((int)this->m_width, (int)this->m_height);
654  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
655  m_background.cols != (int)m_width) {
656  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
657  }
658 
659  if (m_scale == 1) {
660  for (unsigned int i = 0; i < m_height; i++) {
661  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
662  for (unsigned int j = 0; j < m_width; j++) {
663  vpRGBa val = I[i][j];
664  *(dst_24++) = val.B;
665  *(dst_24++) = val.G;
666  *(dst_24++) = val.R;
667  }
668  }
669  }
670  else {
671  for (unsigned int i = 0; i < m_height; i++) {
672  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
673  for (unsigned int j = 0; j < m_width; j++) {
674  vpRGBa val = I[i * m_scale][j * m_scale];
675  *(dst_24++) = val.B;
676  *(dst_24++) = val.G;
677  *(dst_24++) = val.R;
678  }
679  }
680  }
681  }
682  else {
683  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
684  }
685 }
686 
702 void vpDisplayOpenCV::displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, unsigned int w, unsigned int h)
703 {
705  int depth = CV_8U;
706  int channels = 3;
707  cv::Size size((int)this->m_width, (int)this->m_height);
708  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
709  m_background.cols != (int)m_width) {
710  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
711  }
712 
713  if (m_scale == 1) {
714  unsigned int i_min = (unsigned int)iP.get_i();
715  unsigned int j_min = (unsigned int)iP.get_j();
716  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
717  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
718  for (unsigned int i = i_min; i < i_max; i++) {
719  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
720  for (unsigned int j = j_min; j < j_max; j++) {
721  vpRGBa val = I[i][j];
722  *(dst_24++) = val.B;
723  *(dst_24++) = val.G;
724  *(dst_24++) = val.R;
725  }
726  }
727  }
728  else {
729  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
730  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
731  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
732  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
733  for (int i = i_min; i < i_max; i++) {
734  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
735  for (int j = j_min; j < j_max; j++) {
736  vpRGBa val = I[i * m_scale][j * m_scale];
737  *(dst_24++) = val.B;
738  *(dst_24++) = val.G;
739  *(dst_24++) = val.R;
740  }
741  }
742  }
743  }
744  else {
745  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
746  }
747 }
748 
754 void vpDisplayOpenCV::displayImage(const unsigned char * /* I */)
755 {
756  // not implemented
757 }
758 
767 {
768  if (col != nullptr) {
769  delete[] col;
770  col = nullptr;
771  }
773  cv::destroyWindow(this->m_title);
774  for (size_t i = 0; i < m_listTitles.size(); i++) {
775  if (m_title == m_listTitles[i]) {
776  m_listTitles.erase(m_listTitles.begin() + (long int)i);
777  break;
778  }
779  }
780 
781  m_title.clear();
782 
784  }
785 }
786 
793 {
795  cv::imshow(this->m_title, m_background);
796  cv::waitKey(5);
797  }
798  else {
799  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
800  }
801 }
802 
808 void vpDisplayOpenCV::flushDisplayROI(const vpImagePoint & /*iP*/, const unsigned int /*width*/,
809  const unsigned int /*height*/)
810 {
812  cv::imshow(this->m_title.c_str(), m_background);
813  cv::waitKey(5);
814  }
815  else {
816  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
817  }
818 }
819 
823 void vpDisplayOpenCV::clearDisplay(const vpColor & /* color */)
824 {
825  // Not implemented
826 }
827 
835 void vpDisplayOpenCV::displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
836  unsigned int w, unsigned int h, unsigned int thickness)
837 {
839  double a = ip2.get_i() - ip1.get_i();
840  double b = ip2.get_j() - ip1.get_j();
841  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
842 
843  // if ((a==0)&&(b==0))
844  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
845  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
846  // DisplayCrossLarge(i1,j1,3,col) ;
847  }
848  else {
849  a /= lg;
850  b /= lg;
851 
852  vpImagePoint ip3;
853  ip3.set_i(ip2.get_i() - w * a);
854  ip3.set_j(ip2.get_j() - w * b);
855 
856  vpImagePoint ip4;
857  ip4.set_i(ip3.get_i() - b * h);
858  ip4.set_j(ip3.get_j() + a * h);
859 
860  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
861  displayLine(ip2, ip4, color, thickness);
862 
863  ip4.set_i(ip3.get_i() + b * h);
864  ip4.set_j(ip3.get_j() - a * h);
865 
866  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
867  displayLine(ip2, ip4, color, thickness);
868 
869  displayLine(ip1, ip2, color, thickness);
870  }
871  }
872  else {
873  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
874  }
875 }
876 
888 void vpDisplayOpenCV::displayText(const vpImagePoint &ip, const std::string &text, const vpColor &color)
889 {
891  if (color.id < vpColor::id_unknown) {
892  cv::putText(m_background, text,
893  cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)),
894  font, fontScale, col[color.id]);
895  }
896  else {
897  cvcolor = CV_RGB(color.R, color.G, color.B);
898  cv::putText(m_background, text,
899  cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)),
900  font, fontScale, cvcolor);
901  }
902  }
903  else {
904  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
905  }
906 }
919 void vpDisplayOpenCV::displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill,
920  unsigned int thickness)
921 {
923  int x = vpMath::round(center.get_u() / m_scale);
924  int y = vpMath::round(center.get_v() / m_scale);
925  int r = static_cast<int>(radius / m_scale);
926  cv::Scalar cv_color;
927  if (color.id < vpColor::id_unknown) {
928  cv_color = col[color.id];
929  }
930  else {
931  cv_color = CV_RGB(color.R, color.G, color.B);
932  }
933 
934  if (fill == false) {
935  int cv_thickness = static_cast<int>(thickness);
936  cv::circle(m_background, cv::Point(x, y), r, cv_color, cv_thickness);
937  }
938  else {
939 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
940  int filled = cv::FILLED;
941 #else
942  int filled = CV_FILLED;
943 #endif
944  double opacity = static_cast<double>(color.A) / 255.0;
945  overlay([x, y, r, cv_color, filled](cv::Mat image) { cv::circle(image, cv::Point(x, y), r, cv_color, filled); },
946  opacity);
947  }
948  }
949  else {
950  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
951  }
952 }
953 
961 void vpDisplayOpenCV::displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color,
962  unsigned int thickness)
963 {
965  vpImagePoint top, bottom, left, right;
966  top.set_i(ip.get_i() - size / 2);
967  top.set_j(ip.get_j());
968  bottom.set_i(ip.get_i() + size / 2);
969  bottom.set_j(ip.get_j());
970  left.set_i(ip.get_i());
971  left.set_j(ip.get_j() - size / 2);
972  right.set_i(ip.get_i());
973  right.set_j(ip.get_j() + size / 2);
974  displayLine(top, bottom, color, thickness);
975  displayLine(left, right, color, thickness);
976  }
977  else {
978  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
979  }
980 }
981 
989 void vpDisplayOpenCV::displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
990  unsigned int thickness)
991 {
993  vpImagePoint ip1_ = ip1;
994  vpImagePoint ip2_ = ip2;
995 
996  double size = 10. * m_scale;
997  double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
998  bool vertical_line = (int)ip2_.get_j() == (int)ip1_.get_j();
999  if (vertical_line) {
1000  if (ip2_.get_i() < ip1_.get_i()) {
1001  std::swap(ip1_, ip2_);
1002  }
1003  }
1004  else if (ip2_.get_j() < ip1_.get_j()) {
1005  std::swap(ip1_, ip2_);
1006  }
1007 
1008  double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
1009  double deltaj = size / length * diff_j;
1010  double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
1011  double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
1012  double orig = ip1_.get_i() - slope * ip1_.get_j();
1013 
1014  if (vertical_line) {
1015  for (unsigned int i = (unsigned int)ip1_.get_i(); i < ip2_.get_i(); i += (unsigned int)(2 * deltai)) {
1016  double j = ip1_.get_j();
1017  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j), color, thickness);
1018  }
1019  }
1020  else {
1021  for (unsigned int j = (unsigned int)ip1_.get_j(); j < ip2_.get_j(); j += (unsigned int)(2 * deltaj)) {
1022  double i = slope * j + orig;
1023  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j + deltaj), color, thickness);
1024  }
1025  }
1026  }
1027  else {
1028  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1029  }
1030 }
1031 
1038 void vpDisplayOpenCV::displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1039  unsigned int thickness)
1040 {
1042  if (color.id < vpColor::id_unknown) {
1043  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1044  cv::Point(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), col[color.id],
1045  (int)thickness);
1046  }
1047  else {
1048  cvcolor = CV_RGB(color.R, color.G, color.B);
1049  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1050  cv::Point(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), cvcolor,
1051  (int)thickness);
1052  }
1053  }
1054  else {
1055  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1056  }
1057 }
1058 
1065 void vpDisplayOpenCV::displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
1066 {
1068  for (unsigned int i = 0; i < thickness; i++) {
1069  if (color.id < vpColor::id_unknown) {
1070  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1071  cv::Point(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1072  col[color.id], (int)thickness);
1073  }
1074  else {
1075  cvcolor = CV_RGB(color.R, color.G, color.B);
1076  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1077  cv::Point(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1078  cvcolor, (int)thickness);
1079  }
1080  }
1081  }
1082  else {
1083  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1084  }
1085 }
1086 
1102 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, unsigned int w, unsigned int h,
1103  const vpColor &color, bool fill, unsigned int thickness)
1104 {
1106  int left = vpMath::round(topLeft.get_u() / m_scale);
1107  int top = vpMath::round(topLeft.get_v() / m_scale);
1108  int right = vpMath::round((topLeft.get_u() + w) / m_scale);
1109  int bottom = vpMath::round((topLeft.get_v() + h) / m_scale);
1110  cv::Scalar cv_color;
1111  if (color.id < vpColor::id_unknown) {
1112  cv_color = col[color.id];
1113  }
1114  else {
1115  cv_color = CV_RGB(color.R, color.G, color.B);
1116  }
1117 
1118  if (fill == false) {
1119  int cv_thickness = static_cast<int>(thickness);
1120  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1121  }
1122  else {
1123 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1124  int filled = cv::FILLED;
1125 #else
1126  int filled = CV_FILLED;
1127 #endif
1128  double opacity = static_cast<double>(color.A) / 255.0;
1129  overlay([left, top, right, bottom, cv_color, filled](cv::Mat image) {
1130  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1131  },
1132  opacity);
1133  }
1134  }
1135  else {
1136  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1137  }
1138 }
1153 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, const vpImagePoint &bottomRight,
1154  const vpColor &color, bool fill, unsigned int thickness)
1155 {
1157  int left = vpMath::round(topLeft.get_u() / m_scale);
1158  int top = vpMath::round(topLeft.get_v() / m_scale);
1159  int right = vpMath::round(bottomRight.get_u() / m_scale);
1160  int bottom = vpMath::round(bottomRight.get_v() / m_scale);
1161  cv::Scalar cv_color;
1162  if (color.id < vpColor::id_unknown) {
1163  cv_color = col[color.id];
1164  }
1165  else {
1166  cv_color = CV_RGB(color.R, color.G, color.B);
1167  }
1168 
1169  if (fill == false) {
1170  int cv_thickness = static_cast<int>(thickness);
1171  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1172  }
1173  else {
1174 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1175  int filled = cv::FILLED;
1176 #else
1177  int filled = CV_FILLED;
1178 #endif
1179  double opacity = static_cast<double>(color.A) / 255.0;
1180  overlay([left, top, right, bottom, cv_color, filled](cv::Mat image) {
1181  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1182  },
1183  opacity);
1184  }
1185  }
1186  else {
1187  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1188  }
1189 }
1190 
1204 void vpDisplayOpenCV::displayRectangle(const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
1205 {
1207  int left = vpMath::round(rectangle.getLeft() / m_scale);
1208  int top = vpMath::round(rectangle.getTop() / m_scale);
1209  int right = vpMath::round(rectangle.getRight() / m_scale);
1210  int bottom = vpMath::round(rectangle.getBottom() / m_scale);
1211  cv::Scalar cv_color;
1212  if (color.id < vpColor::id_unknown) {
1213  cv_color = col[color.id];
1214  }
1215  else {
1216  cv_color = CV_RGB(color.R, color.G, color.B);
1217  }
1218 
1219  if (fill == false) {
1220  int cv_thickness = static_cast<int>(thickness);
1221  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1222  }
1223  else {
1224 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1225  int filled = cv::FILLED;
1226 #else
1227  int filled = CV_FILLED;
1228 #endif
1229  double opacity = static_cast<double>(color.A) / 255.0;
1230  overlay([left, top, right, bottom, cv_color, filled](cv::Mat image) {
1231  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1232  },
1233  opacity);
1234  }
1235  }
1236  else {
1237  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1238  }
1239 }
1240 
1256 bool vpDisplayOpenCV::getClick(bool blocking)
1257 {
1258  bool ret = false;
1260  flushDisplay();
1261  if (blocking) {
1262  lbuttondown = false;
1263  mbuttondown = false;
1264  rbuttondown = false;
1265  }
1266  do {
1267  if (lbuttondown) {
1268  ret = true;
1269  lbuttondown = false;
1270  }
1271  if (mbuttondown) {
1272  ret = true;
1273  mbuttondown = false;
1274  }
1275  if (rbuttondown) {
1276  ret = true;
1277  rbuttondown = false;
1278  }
1279  if (blocking) {
1280  cv::waitKey(10);
1281  }
1282  } while (ret == false && blocking == true);
1283  }
1284  else {
1285  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1286  }
1287  return ret;
1288 }
1289 
1305 bool vpDisplayOpenCV::getClick(vpImagePoint &ip, bool blocking)
1306 {
1307  bool ret = false;
1308 
1310  flushDisplay();
1311 
1312  double u, v;
1313 
1314  if (blocking) {
1315  lbuttondown = false;
1316  mbuttondown = false;
1317  rbuttondown = false;
1318  }
1319  do {
1320  if (lbuttondown) {
1321  ret = true;
1322  u = (unsigned int)x_lbuttondown * m_scale;
1323  v = (unsigned int)y_lbuttondown * m_scale;
1324  ip.set_u(u);
1325  ip.set_v(v);
1326  lbuttondown = false;
1327  }
1328  if (mbuttondown) {
1329  ret = true;
1330  u = (unsigned int)x_mbuttondown * m_scale;
1331  v = (unsigned int)y_mbuttondown * m_scale;
1332  ip.set_u(u);
1333  ip.set_v(v);
1334  mbuttondown = false;
1335  }
1336  if (rbuttondown) {
1337  ret = true;
1338  u = (unsigned int)x_rbuttondown * m_scale;
1339  v = (unsigned int)y_rbuttondown * m_scale;
1340  ip.set_u(u);
1341  ip.set_v(v);
1342  rbuttondown = false;
1343  }
1344  if (blocking) {
1345  cv::waitKey(10);
1346  }
1347  } while (ret == false && blocking == true);
1348  }
1349  else {
1350  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1351  }
1352  return ret;
1353 }
1354 
1374 {
1375  bool ret = false;
1376 
1378  // flushDisplay() ;
1379  double u, v;
1380  if (blocking) {
1381  lbuttondown = false;
1382  mbuttondown = false;
1383  rbuttondown = false;
1384  }
1385  do {
1386  if (lbuttondown) {
1387  ret = true;
1388  u = (unsigned int)x_lbuttondown * m_scale;
1389  v = (unsigned int)y_lbuttondown * m_scale;
1390  ip.set_u(u);
1391  ip.set_v(v);
1392  button = vpMouseButton::button1;
1393  lbuttondown = false;
1394  }
1395  if (mbuttondown) {
1396  ret = true;
1397  u = (unsigned int)x_mbuttondown * m_scale;
1398  v = (unsigned int)y_mbuttondown * m_scale;
1399  ip.set_u(u);
1400  ip.set_v(v);
1401  button = vpMouseButton::button2;
1402  mbuttondown = false;
1403  }
1404  if (rbuttondown) {
1405  ret = true;
1406  u = (unsigned int)x_rbuttondown * m_scale;
1407  v = (unsigned int)y_rbuttondown * m_scale;
1408  ip.set_u(u);
1409  ip.set_v(v);
1410  button = vpMouseButton::button3;
1411  rbuttondown = false;
1412  }
1413  if (blocking) {
1414  cv::waitKey(10);
1415  }
1416  } while (ret == false && blocking == true);
1417  }
1418  else {
1419  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1420  }
1421  return ret;
1422 }
1423 
1446 {
1447  bool ret = false;
1449  // flushDisplay() ;
1450  double u, v;
1451  if (blocking) {
1452  lbuttonup = false;
1453  mbuttonup = false;
1454  rbuttonup = false;
1455  }
1456  do {
1457  if (lbuttonup) {
1458  ret = true;
1459  u = (unsigned int)x_lbuttonup * m_scale;
1460  v = (unsigned int)y_lbuttonup * m_scale;
1461  ip.set_u(u);
1462  ip.set_v(v);
1463  button = vpMouseButton::button1;
1464  lbuttonup = false;
1465  }
1466  if (mbuttonup) {
1467  ret = true;
1468  u = (unsigned int)x_mbuttonup * m_scale;
1469  v = (unsigned int)y_mbuttonup * m_scale;
1470  ip.set_u(u);
1471  ip.set_v(v);
1472  button = vpMouseButton::button2;
1473  mbuttonup = false;
1474  }
1475  if (rbuttonup) {
1476  ret = true;
1477  u = (unsigned int)x_rbuttonup * m_scale;
1478  v = (unsigned int)y_rbuttonup * m_scale;
1479  ip.set_u(u);
1480  ip.set_v(v);
1481  button = vpMouseButton::button3;
1482  rbuttonup = false;
1483  }
1484  if (blocking) {
1485  cv::waitKey(10);
1486  }
1487  } while (ret == false && blocking == true);
1488  }
1489  else {
1490  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1491  }
1492  return ret;
1493 }
1494 
1495 /*
1496  Gets the displayed image (including the overlay plane)
1497  and returns an RGBa image.
1498 */
1500 {
1501  vpImageConvert::convert(m_background, I);
1502  // should certainly be optimized.
1503 }
1504 
1505 void vpDisplayOpenCV::on_mouse(int event, int x, int y, int /*flags*/, void *display)
1506 {
1507  vpDisplayOpenCV *disp = static_cast<vpDisplayOpenCV *>(display);
1508  switch (event) {
1509  case cv::EVENT_MOUSEMOVE:
1510  {
1511  disp->move = true;
1512  disp->x_move = x;
1513  disp->y_move = y;
1514  break;
1515  }
1516  case cv::EVENT_LBUTTONDOWN:
1517  {
1518  disp->lbuttondown = true;
1519  disp->x_lbuttondown = x;
1520  disp->y_lbuttondown = y;
1521  break;
1522  }
1523  case cv::EVENT_MBUTTONDOWN:
1524  {
1525  disp->mbuttondown = true;
1526  disp->x_mbuttondown = x;
1527  disp->y_mbuttondown = y;
1528  break;
1529  }
1530  case cv::EVENT_RBUTTONDOWN:
1531  {
1532  disp->rbuttondown = true;
1533  disp->x_rbuttondown = x;
1534  disp->y_rbuttondown = y;
1535  break;
1536  }
1537  case cv::EVENT_LBUTTONUP:
1538  {
1539  disp->lbuttonup = true;
1540  disp->x_lbuttonup = x;
1541  disp->y_lbuttonup = y;
1542  break;
1543  }
1544  case cv::EVENT_MBUTTONUP:
1545  {
1546  disp->mbuttonup = true;
1547  disp->x_mbuttonup = x;
1548  disp->y_mbuttonup = y;
1549  break;
1550  }
1551  case cv::EVENT_RBUTTONUP:
1552  {
1553  disp->rbuttonup = true;
1554  disp->x_rbuttonup = x;
1555  disp->y_rbuttonup = y;
1556  break;
1557  }
1558 
1559  default:
1560  break;
1561  }
1562 }
1563 
1580 {
1582  int delay;
1583  flushDisplay();
1584  if (blocking)
1585  delay = 0;
1586  else
1587  delay = 10;
1588 
1589  int key_pressed = cv::waitKey(delay);
1590 
1591  if (key_pressed == -1)
1592  return false;
1593  return true;
1594  }
1595  else {
1596  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1597  }
1598  // return false; // Never reached after throw()
1599 }
1618 bool vpDisplayOpenCV::getKeyboardEvent(std::string &key, bool blocking)
1619 {
1621  int delay;
1622  flushDisplay();
1623  if (blocking)
1624  delay = 0;
1625  else
1626  delay = 10;
1627 
1628  int key_pressed = cv::waitKey(delay);
1629  if (key_pressed == -1)
1630  return false;
1631  else {
1632  // std::cout << "Key pressed: \"" << key_pressed << "\"" << std::endl;
1633  std::stringstream ss;
1634  ss << key_pressed;
1635  key = ss.str();
1636  }
1637  return true;
1638  }
1639  else {
1640  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1641  }
1642  // return false; // Never reached after throw()
1643 }
1644 
1656 {
1657  bool ret = false;
1658 
1660  // flushDisplay() ;
1661  if (move) {
1662  ret = true;
1663  double u = (unsigned int)x_move / m_scale;
1664  double v = (unsigned int)y_move / m_scale;
1665  ip.set_u(u);
1666  ip.set_v(v);
1667  move = false;
1668  }
1669  }
1670 
1671  else {
1672  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1673  }
1674  return ret;
1675 }
1676 
1688 {
1690  bool moved = getPointerMotionEvent(ip);
1691  if (!moved) {
1692  double u, v;
1693  u = (unsigned int)x_move / m_scale;
1694  v = (unsigned int)y_move / m_scale;
1695  ip.set_u(u);
1696  ip.set_v(v);
1697  }
1698  return false;
1699  }
1700  else {
1701  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1702  }
1703 }
1704 
1709 void vpDisplayOpenCV::getScreenSize(unsigned int &w, unsigned int &h)
1710 {
1711  w = h = 0;
1712 
1713 #if defined(VISP_HAVE_X11)
1714  vpDisplayX d;
1715  d.getScreenSize(w, h);
1716 #elif defined(VISP_HAVE_XRANDR)
1717  std::string command = "xrandr | grep '*'";
1718  FILE *fpipe = (FILE *)popen(command.c_str(), "r");
1719  char line[256];
1720  while (fgets(line, sizeof(line), fpipe)) {
1721  std::string str(line);
1722  std::size_t found = str.find("Failed");
1723 
1724  if (found == std::string::npos) {
1725  std::vector<std::string> elm;
1726  elm = vpIoTools::splitChain(str, " ");
1727  for (size_t i = 0; i < elm.size(); i++) {
1728  if (!elm[i].empty()) {
1729  std::vector<std::string> resolution = vpIoTools::splitChain(elm[i], "x");
1730  if (resolution.size() == 2) {
1731  std::istringstream sswidth(resolution[0]), ssheight(resolution[1]);
1732  sswidth >> w;
1733  ssheight >> h;
1734  break;
1735  }
1736  }
1737  }
1738  }
1739  }
1740  pclose(fpipe);
1741 #elif defined(_WIN32)
1742 #if !defined(WINRT)
1743  w = GetSystemMetrics(SM_CXSCREEN);
1744  h = GetSystemMetrics(SM_CYSCREEN);
1745 #else
1746  throw(vpException(vpException::functionNotImplementedError, "The function vpDisplayOpenCV::getScreenSize() is not "
1747  "implemented on winrt"));
1748 #endif
1749 #endif
1750 }
1751 
1756 {
1757  unsigned int width, height;
1758  getScreenSize(width, height);
1759  return width;
1760 }
1761 
1766 {
1767  unsigned int width, height;
1768  getScreenSize(width, height);
1769  return height;
1770 }
1771 
1777 void vpDisplayOpenCV::overlay(std::function<void(cv::Mat &)> overlay_function, double opacity)
1778 {
1779  // Initialize overlay layer for transparency
1780  cv::Mat overlay;
1781  if (opacity < 1.0) {
1782  // Deep copy
1783  overlay = m_background.clone();
1784  }
1785  else {
1786  // Shallow copy
1787  overlay = m_background;
1788  }
1789 
1790  overlay_function(overlay);
1791 
1792  // Blend background and overlay
1793  if (opacity < 1.0) {
1794  cv::addWeighted(overlay, opacity, m_background, 1.0 - opacity, 0.0, m_background);
1795  }
1796 }
1797 
1798 END_VISP_NAMESPACE
1799 
1800 #elif !defined(VISP_BUILD_SHARED_LIBS)
1801 // Work around to avoid warning: libvisp_gui.a(vpDisplayOpenCV.cpp.o) has no symbols
1802 void dummy_vpDisplayOpenCV() { };
1803 #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 overlay(std::function< void(cv::Mat &)> overlay_function, double opacity)
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
static void on_mouse(int event, int x, int y, int flags, void *param)
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 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