Visual Servoing Platform  version 3.6.1 under development (2024-02-13)
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 
78 std::vector<std::string> vpDisplayOpenCV::m_listTitles = std::vector<std::string>();
79 unsigned int vpDisplayOpenCV::m_nbWindows = 0;
80 
103  : vpDisplay(),
104 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
105  m_background(nullptr), col(nullptr), cvcolor(), font(nullptr),
106 #else
107  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
108 #endif
109  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
110  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
111  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
112  y_rbuttonup(0), rbuttonup(false)
113 {
114  setScale(scaleType, I.getWidth(), I.getHeight());
115  init(I);
116 }
117 
141 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<unsigned char> &I, int x, int y, const std::string &title,
142  vpScaleType scaleType)
143  : vpDisplay(),
144 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
145  m_background(nullptr), col(nullptr), cvcolor(), font(nullptr),
146 #else
147  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
148 #endif
149  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
150  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
151  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
152  y_rbuttonup(0), rbuttonup(false)
153 {
154  setScale(scaleType, I.getWidth(), I.getHeight());
155  init(I, x, y, title);
156 }
157 
177  :
178 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
179  m_background(nullptr), col(nullptr), cvcolor(), font(nullptr),
180 #else
181  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
182 #endif
183  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
184  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
185  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
186  y_rbuttonup(0), rbuttonup(false)
187 {
188  setScale(scaleType, I.getWidth(), I.getHeight());
189  init(I);
190 }
191 
212 vpDisplayOpenCV::vpDisplayOpenCV(vpImage<vpRGBa> &I, int x, int y, const std::string &title, vpScaleType scaleType)
213  :
214 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
215  m_background(nullptr), col(nullptr), cvcolor(), font(nullptr),
216 #else
217  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
218 #endif
219  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
220  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
221  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
222  y_rbuttonup(0), rbuttonup(false)
223 {
224  setScale(scaleType, I.getWidth(), I.getHeight());
225  init(I, x, y, title);
226 }
227 
250 vpDisplayOpenCV::vpDisplayOpenCV(int x, int y, const std::string &title)
251  :
252 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
253  m_background(nullptr), col(nullptr), cvcolor(), font(nullptr),
254 #else
255  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
256 #endif
257  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
258  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
259  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
260  y_rbuttonup(0), rbuttonup(false)
261 {
262  m_windowXPosition = x;
263  m_windowYPosition = y;
264 
265  if (!title.empty()) {
266  m_title = title;
267  }
268  else {
269  std::ostringstream s;
270  s << m_nbWindows++;
271  m_title = std::string("Window ") + s.str();
272  }
273 
274  bool isInList;
275  do {
276  isInList = false;
277  for (size_t i = 0; i < m_listTitles.size(); i++) {
278  if (m_listTitles[i] == m_title) {
279  std::ostringstream s;
280  s << m_nbWindows++;
281  m_title = std::string("Window ") + s.str();
282  isInList = true;
283  break;
284  }
285  }
286  } while (isInList);
287 
288  m_listTitles.push_back(m_title);
289 }
290 
311  :
312 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
313  m_background(nullptr), col(nullptr), cvcolor(), font(nullptr),
314 #else
315  m_background(), col(nullptr), cvcolor(), font(cv::FONT_HERSHEY_PLAIN), fontScale(0.8f),
316 #endif
317  fontHeight(10), x_move(0), y_move(0), move(false), x_lbuttondown(0), y_lbuttondown(0), lbuttondown(false),
318  x_mbuttondown(0), y_mbuttondown(0), mbuttondown(false), x_rbuttondown(0), y_rbuttondown(0), rbuttondown(false),
319  x_lbuttonup(0), y_lbuttonup(0), lbuttonup(false), x_mbuttonup(0), y_mbuttonup(0), mbuttonup(false), x_rbuttonup(0),
320  y_rbuttonup(0), rbuttonup(false)
321 { }
322 
327 {
328  closeDisplay();
329 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
330  cvReleaseImage(&m_background);
331 #endif
332 }
333 
342 void vpDisplayOpenCV::init(vpImage<unsigned char> &I, int x, int y, const std::string &title)
343 {
344  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
345  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
346  }
348  init(I.getWidth(), I.getHeight(), x, y, title);
349  I.display = this;
351 }
352 
362 void vpDisplayOpenCV::init(vpImage<vpRGBa> &I, int x, int y, const std::string &title)
363 {
364  if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
365  throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
366  }
367 
369  init(I.getWidth(), I.getHeight(), x, y, title);
370  I.display = this;
372 }
373 
384 void vpDisplayOpenCV::init(unsigned int w, unsigned int h, int x, int y, const std::string &title)
385 {
386  setScale(m_scaleType, w, h);
387 
388  this->m_width = w / m_scale;
389  this->m_height = h / m_scale;
390 
391  if (x != -1)
392  this->m_windowXPosition = x;
393  if (y != -1)
394  this->m_windowYPosition = y;
395 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
396  int flags = CV_WINDOW_AUTOSIZE;
397 #else
398  int flags = cv::WINDOW_AUTOSIZE;
399 #endif
400 
401  if (m_title.empty()) {
402  if (!title.empty()) {
403  m_title = std::string(title);
404  }
405  else {
406 
407  std::ostringstream s;
408  s << m_nbWindows++;
409  m_title = std::string("Window ") + s.str();
410  }
411 
412  bool isInList;
413  do {
414  isInList = false;
415  for (size_t i = 0; i < m_listTitles.size(); i++) {
416  if (m_listTitles[i] == m_title) {
417  std::ostringstream s;
418  s << m_nbWindows++;
419  m_title = std::string("Window ") + s.str();
420  isInList = true;
421  break;
422  }
423  }
424  } while (isInList);
425 
426  m_listTitles.push_back(m_title);
427  }
428 
429 /* Create the window*/
430 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
431  if (cvNamedWindow(this->m_title.c_str(), flags) < 0) {
432  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV was not built with a display device"));
433  }
434 #else
435  cv::namedWindow(this->m_title, flags);
436 #endif
437 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
438  cvMoveWindow(this->m_title.c_str(), this->m_windowXPosition, this->m_windowYPosition);
439 #else
440  cv::moveWindow(this->m_title.c_str(), this->m_windowXPosition, this->m_windowYPosition);
441 #endif
442  move = false;
443  lbuttondown = false;
444  mbuttondown = false;
445  rbuttondown = false;
446  lbuttonup = false;
447  mbuttonup = false;
448  rbuttonup = false;
449 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
450  cvSetMouseCallback(this->m_title.c_str(), on_mouse, this);
451  col = new CvScalar[vpColor::id_unknown];
452 #else
453  cv::setMouseCallback(this->m_title, on_mouse, this);
454  col = new cv::Scalar[vpColor::id_unknown];
455 #endif
456 
457  /* Create color */
458  vpColor pcolor; // Predefined colors
459  pcolor = vpColor::lightBlue;
460  col[vpColor::id_lightBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
461  pcolor = vpColor::blue;
462  col[vpColor::id_blue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
463  pcolor = vpColor::darkBlue;
464  col[vpColor::id_darkBlue] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
465  pcolor = vpColor::lightRed;
466  col[vpColor::id_lightRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
467  pcolor = vpColor::red;
468  col[vpColor::id_red] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
469  pcolor = vpColor::darkRed;
470  col[vpColor::id_darkRed] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
471  pcolor = vpColor::lightGreen;
472  col[vpColor::id_lightGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
473  pcolor = vpColor::green;
474  col[vpColor::id_green] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
475  pcolor = vpColor::darkGreen;
476  col[vpColor::id_darkGreen] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
477  pcolor = vpColor::yellow;
478  col[vpColor::id_yellow] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
479  pcolor = vpColor::cyan;
480  col[vpColor::id_cyan] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
481  pcolor = vpColor::orange;
482  col[vpColor::id_orange] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
483  pcolor = vpColor::purple;
484  col[vpColor::id_purple] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
485  pcolor = vpColor::white;
486  col[vpColor::id_white] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
487  pcolor = vpColor::black;
488  col[vpColor::id_black] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
489  pcolor = vpColor::lightGray;
490  col[vpColor::id_lightGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
491  pcolor = vpColor::gray;
492  col[vpColor::id_gray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
493  pcolor = vpColor::darkGray;
494  col[vpColor::id_darkGray] = CV_RGB(pcolor.R, pcolor.G, pcolor.B);
495 
496 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
497  font = new CvFont;
498  cvInitFont(font, CV_FONT_HERSHEY_PLAIN, 0.70f, 0.70f);
499  CvSize fontSize;
500  int baseline;
501  cvGetTextSize("A", font, &fontSize, &baseline);
502 #else
503  int thickness = 1;
504  cv::Size fontSize;
505  int baseline;
506  fontSize = cv::getTextSize("A", font, fontScale, thickness, &baseline);
507 #endif
508 
509  fontHeight = fontSize.height + baseline;
511 }
512 
528 void vpDisplayOpenCV::setFont(const std::string & /* font */) { vpERROR_TRACE("Not yet implemented"); }
529 
537 void vpDisplayOpenCV::setTitle(const std::string & /* title */)
538 {
539  // static bool warn_displayed = false;
540  // if (! warn_displayed) {
541  // vpTRACE("Not implemented");
542  // warn_displayed = true;
543  // }
544 }
545 
555 void vpDisplayOpenCV::setWindowPosition(int winx, int winy)
556 {
558  this->m_windowXPosition = winx;
559  this->m_windowYPosition = winy;
560 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
561  cvMoveWindow(this->m_title.c_str(), winx, winy);
562 #else
563  cv::moveWindow(this->m_title.c_str(), winx, winy);
564 #endif
565  }
566  else {
567  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
568  }
569 }
582 {
584 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
585  int depth = 8;
586  int channels = 3;
587  CvSize size = cvSize((int)this->m_width, (int)this->m_height);
588  if (m_background != nullptr) {
589  if (m_background->nChannels != channels || m_background->depth != depth ||
590  m_background->height != (int)m_height || m_background->width != (int)m_width) {
591  if (m_background->nChannels != 0)
592  cvReleaseImage(&m_background);
593  m_background = cvCreateImage(size, depth, channels);
594  }
595  }
596  else {
597  m_background = cvCreateImage(size, depth, channels);
598  }
599 
600  if (m_scale == 1) {
601  for (unsigned int i = 0; i < m_height; i++) {
602  unsigned char *dst_24 = (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep);
603  for (unsigned int j = 0; j < m_width; j++) {
604  unsigned char val = I[i][j];
605  *(dst_24++) = val;
606  *(dst_24++) = val;
607  *(dst_24++) = val;
608  }
609  }
610  }
611  else {
612  for (unsigned int i = 0; i < m_height; i++) {
613  unsigned char *dst_24 = (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep);
614  for (unsigned int j = 0; j < m_width; j++) {
615  unsigned char val = I[i * m_scale][j * m_scale];
616  *(dst_24++) = val;
617  *(dst_24++) = val;
618  *(dst_24++) = val;
619  }
620  }
621  }
622 
623 #else
624  int depth = CV_8U;
625  int channels = 3;
626  cv::Size size((int)m_width, (int)m_height);
627  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
628  m_background.cols != (int)m_width) {
629  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
630  }
631 
632  if (m_scale == 1) {
633  for (unsigned int i = 0; i < m_height; i++) {
634  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
635  for (unsigned int j = 0; j < m_width; j++) {
636  unsigned char val = I[i][j];
637  *(dst_24++) = val;
638  *(dst_24++) = val;
639  *(dst_24++) = val;
640  }
641  }
642  }
643  else {
644  for (unsigned int i = 0; i < m_height; i++) {
645  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
646  for (unsigned int j = 0; j < m_width; j++) {
647  unsigned char val = I[i * m_scale][j * m_scale];
648  *(dst_24++) = val;
649  *(dst_24++) = val;
650  *(dst_24++) = val;
651  }
652  }
653  }
654 #endif
655 
656  }
657  else {
658  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
659  }
660 }
661 
678  unsigned int h)
679 {
681 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
682  int depth = 8;
683  int channels = 3;
684  CvSize size = cvSize((int)this->m_width, (int)this->m_height);
685  if (m_background != nullptr) {
686  if (m_background->nChannels != channels || m_background->depth != depth ||
687  m_background->height != (int)m_height || m_background->width != (int)m_width) {
688  if (m_background->nChannels != 0)
689  cvReleaseImage(&m_background);
690  m_background = cvCreateImage(size, depth, channels);
691  }
692  }
693  else {
694  m_background = cvCreateImage(size, depth, channels);
695  }
696 
697  if (m_scale == 1) {
698  unsigned int i_min = (unsigned int)iP.get_i();
699  unsigned int j_min = (unsigned int)iP.get_j();
700  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
701  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
702  for (unsigned int i = i_min; i < i_max; i++) {
703  unsigned char *dst_24 =
704  (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep + j_min * 3);
705  for (unsigned int j = j_min; j < j_max; j++) {
706  unsigned char val = I[i][j];
707  *(dst_24++) = val;
708  *(dst_24++) = val;
709  *(dst_24++) = val;
710  }
711  }
712  }
713  else {
714  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
715  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
716  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
717  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
718  for (int i = i_min; i < i_max; i++) {
719  unsigned char *dst_24 =
720  (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep + j_min * 3);
721  for (int j = j_min; j < j_max; j++) {
722  unsigned char val = I[i * m_scale][j * m_scale];
723  *(dst_24++) = val;
724  *(dst_24++) = val;
725  *(dst_24++) = val;
726  }
727  }
728  }
729 
730 #else
731  int depth = CV_8U;
732  int channels = 3;
733  cv::Size size((int)m_width, (int)m_height);
734  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
735  m_background.cols != (int)m_width) {
736  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
737  }
738 
739  if (m_scale == 1) {
740  unsigned int i_min = (unsigned int)iP.get_i();
741  unsigned int j_min = (unsigned int)iP.get_j();
742  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
743  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
744  for (unsigned int i = i_min; i < i_max; i++) {
745  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
746  for (unsigned int j = j_min; j < j_max; j++) {
747  unsigned char val = I[i][j];
748  *(dst_24++) = val;
749  *(dst_24++) = val;
750  *(dst_24++) = val;
751  }
752  }
753  }
754  else {
755  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
756  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
757  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
758  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
759  for (int i = i_min; i < i_max; i++) {
760  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
761  for (int j = j_min; j < j_max; j++) {
762  unsigned char val = I[i * m_scale][j * m_scale];
763  *(dst_24++) = val;
764  *(dst_24++) = val;
765  *(dst_24++) = val;
766  }
767  }
768  }
769 #endif
770  }
771  else {
772  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
773  }
774 }
775 
788 {
789 
791 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
792  int depth = 8;
793  int channels = 3;
794  CvSize size = cvSize((int)this->m_width, (int)this->m_height);
795  if (m_background != nullptr) {
796  if (m_background->nChannels != channels || m_background->depth != depth ||
797  m_background->height != (int)m_height || m_background->width != (int)m_width) {
798  if (m_background->nChannels != 0)
799  cvReleaseImage(&m_background);
800  m_background = cvCreateImage(size, depth, channels);
801  }
802  }
803  else {
804  m_background = cvCreateImage(size, depth, channels);
805  }
806 
807  if (m_scale == 1) {
808  for (unsigned int i = 0; i < m_height; i++) {
809  unsigned char *dst_24 = (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep);
810  for (unsigned int j = 0; j < m_width; j++) {
811  vpRGBa val = I[i][j];
812  *(dst_24++) = val.B;
813  *(dst_24++) = val.G;
814  *(dst_24++) = val.R;
815  }
816  }
817  }
818  else {
819  for (unsigned int i = 0; i < m_height; i++) {
820  unsigned char *dst_24 = (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep);
821  for (unsigned int j = 0; j < m_width; j++) {
822  vpRGBa val = I[i * m_scale][j * m_scale];
823  *(dst_24++) = val.B;
824  *(dst_24++) = val.G;
825  *(dst_24++) = val.R;
826  }
827  }
828  }
829 #else
830  int depth = CV_8U;
831  int channels = 3;
832  cv::Size size((int)this->m_width, (int)this->m_height);
833  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
834  m_background.cols != (int)m_width) {
835  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
836  }
837 
838  if (m_scale == 1) {
839  for (unsigned int i = 0; i < m_height; i++) {
840  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
841  for (unsigned int j = 0; j < m_width; j++) {
842  vpRGBa val = I[i][j];
843  *(dst_24++) = val.B;
844  *(dst_24++) = val.G;
845  *(dst_24++) = val.R;
846  }
847  }
848  }
849  else {
850  for (unsigned int i = 0; i < m_height; i++) {
851  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width);
852  for (unsigned int j = 0; j < m_width; j++) {
853  vpRGBa val = I[i * m_scale][j * m_scale];
854  *(dst_24++) = val.B;
855  *(dst_24++) = val.G;
856  *(dst_24++) = val.R;
857  }
858  }
859  }
860 #endif
861  }
862  else {
863  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
864  }
865 }
866 
882 void vpDisplayOpenCV::displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, unsigned int w, unsigned int h)
883 {
885 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
886  int depth = 8;
887  int channels = 3;
888  CvSize size = cvSize((int)this->m_width, (int)this->m_height);
889  if (m_background != nullptr) {
890  if (m_background->nChannels != channels || m_background->depth != depth ||
891  m_background->height != (int)m_height || m_background->width != (int)m_width) {
892  if (m_background->nChannels != 0)
893  cvReleaseImage(&m_background);
894  m_background = cvCreateImage(size, depth, channels);
895  }
896  }
897  else {
898  m_background = cvCreateImage(size, depth, channels);
899  }
900 
901  if (m_scale == 1) {
902  unsigned int i_min = (unsigned int)iP.get_i();
903  unsigned int j_min = (unsigned int)iP.get_j();
904  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
905  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
906  for (unsigned int i = i_min; i < i_max; i++) {
907  unsigned char *dst_24 =
908  (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep + j_min * 3);
909  for (unsigned int j = j_min; j < j_max; j++) {
910  vpRGBa val = I[i][j];
911  *(dst_24++) = val.B;
912  *(dst_24++) = val.G;
913  *(dst_24++) = val.R;
914  }
915  }
916  }
917  else {
918  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
919  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
920  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
921  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
922  for (int i = i_min; i < i_max; i++) {
923  unsigned char *dst_24 =
924  (unsigned char *)m_background->imageData + (int)(i * m_background->widthStep + j_min * 3);
925  for (int j = j_min; j < j_max; j++) {
926  vpRGBa val = I[i * m_scale][j * m_scale];
927  *(dst_24++) = val.B;
928  *(dst_24++) = val.G;
929  *(dst_24++) = val.R;
930  }
931  }
932  }
933 #else
934  int depth = CV_8U;
935  int channels = 3;
936  cv::Size size((int)this->m_width, (int)this->m_height);
937  if (m_background.channels() != channels || m_background.depth() != depth || m_background.rows != (int)m_height ||
938  m_background.cols != (int)m_width) {
939  m_background = cv::Mat(size, CV_MAKETYPE(depth, channels));
940  }
941 
942  if (m_scale == 1) {
943  unsigned int i_min = (unsigned int)iP.get_i();
944  unsigned int j_min = (unsigned int)iP.get_j();
945  unsigned int i_max = std::min<unsigned int>(i_min + h, m_height);
946  unsigned int j_max = std::min<unsigned int>(j_min + w, m_width);
947  for (unsigned int i = i_min; i < i_max; i++) {
948  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
949  for (unsigned int j = j_min; j < j_max; j++) {
950  vpRGBa val = I[i][j];
951  *(dst_24++) = val.B;
952  *(dst_24++) = val.G;
953  *(dst_24++) = val.R;
954  }
955  }
956  }
957  else {
958  int i_min = std::max<int>((int)ceil(iP.get_i() / m_scale), 0);
959  int j_min = std::max<int>((int)ceil(iP.get_j() / m_scale), 0);
960  int i_max = std::min<int>((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
961  int j_max = std::min<int>((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
962  for (int i = i_min; i < i_max; i++) {
963  unsigned char *dst_24 = (unsigned char *)m_background.data + (int)(i * 3 * m_width + j_min * 3);
964  for (int j = j_min; j < j_max; j++) {
965  vpRGBa val = I[i * m_scale][j * m_scale];
966  *(dst_24++) = val.B;
967  *(dst_24++) = val.G;
968  *(dst_24++) = val.R;
969  }
970  }
971  }
972 #endif
973  }
974  else {
975  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
976  }
977 }
978 
984 void vpDisplayOpenCV::displayImage(const unsigned char * /* I */) { vpTRACE(" not implemented "); }
985 
994 {
995  if (col != nullptr) {
996  delete[] col;
997  col = nullptr;
998  }
999 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1000  if (font != nullptr) {
1001  delete font;
1002  font = nullptr;
1003  }
1004 #endif
1006 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1007  cvDestroyWindow(this->m_title.c_str());
1008 #else
1009  cv::destroyWindow(this->m_title);
1010 #endif
1011 
1012  for (size_t i = 0; i < m_listTitles.size(); i++) {
1013  if (m_title == m_listTitles[i]) {
1014  m_listTitles.erase(m_listTitles.begin() + (long int)i);
1015  break;
1016  }
1017  }
1018 
1019  m_title.clear();
1020 
1022  }
1023 }
1024 
1031 {
1033 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1034  cvShowImage(this->m_title.c_str(), m_background);
1035  cvWaitKey(5);
1036 #else
1037  cv::imshow(this->m_title, m_background);
1038  cv::waitKey(5);
1039 #endif
1040  }
1041  else {
1042  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1043  }
1044 }
1045 
1051 void vpDisplayOpenCV::flushDisplayROI(const vpImagePoint & /*iP*/, const unsigned int /*width*/,
1052  const unsigned int /*height*/)
1053 {
1055 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1056  cvShowImage(this->m_title.c_str(), m_background);
1057  cvWaitKey(5);
1058 #else
1059  cv::imshow(this->m_title.c_str(), m_background);
1060  cv::waitKey(5);
1061 #endif
1062  }
1063  else {
1064  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1065  }
1066 }
1067 
1071 void vpDisplayOpenCV::clearDisplay(const vpColor & /* color */)
1072 {
1073  static bool warn_displayed = false;
1074  if (!warn_displayed) {
1075  vpTRACE("Not implemented");
1076  warn_displayed = true;
1077  }
1078 }
1079 
1087 void vpDisplayOpenCV::displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1088  unsigned int w, unsigned int h, unsigned int thickness)
1089 {
1091  double a = ip2.get_i() - ip1.get_i();
1092  double b = ip2.get_j() - ip1.get_j();
1093  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
1094 
1095  // if ((a==0)&&(b==0))
1096  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
1097  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
1098  // DisplayCrossLarge(i1,j1,3,col) ;
1099  }
1100  else {
1101  a /= lg;
1102  b /= lg;
1103 
1104  vpImagePoint ip3;
1105  ip3.set_i(ip2.get_i() - w * a);
1106  ip3.set_j(ip2.get_j() - w * b);
1107 
1108  vpImagePoint ip4;
1109  ip4.set_i(ip3.get_i() - b * h);
1110  ip4.set_j(ip3.get_j() + a * h);
1111 
1112  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
1113  displayLine(ip2, ip4, color, thickness);
1114 
1115  ip4.set_i(ip3.get_i() + b * h);
1116  ip4.set_j(ip3.get_j() - a * h);
1117 
1118  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
1119  displayLine(ip2, ip4, color, thickness);
1120 
1121  displayLine(ip1, ip2, color, thickness);
1122  }
1123  }
1124  else {
1125  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1126  }
1127 }
1128 
1140 void vpDisplayOpenCV::displayText(const vpImagePoint &ip, const std::string &text, const vpColor &color)
1141 {
1143  if (color.id < vpColor::id_unknown) {
1144 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1145  cvPutText(m_background, text,
1146  cvPoint(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)), font,
1147  col[color.id]);
1148 #else
1149  cv::putText(m_background, text,
1150  cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)),
1151  font, fontScale, col[color.id]);
1152 #endif
1153  }
1154  else {
1155  cvcolor = CV_RGB(color.R, color.G, color.B);
1156 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1157  cvPutText(m_background, text,
1158  cvPoint(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)), font,
1159  cvcolor);
1160 #else
1161  cv::putText(m_background, text,
1162  cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale + fontHeight)),
1163  font, fontScale, cvcolor);
1164 #endif
1165  }
1166  }
1167  else {
1168  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1169  }
1170 }
1183 void vpDisplayOpenCV::displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill,
1184  unsigned int thickness)
1185 {
1187  int x = vpMath::round(center.get_u() / m_scale);
1188  int y = vpMath::round(center.get_v() / m_scale);
1189  int r = static_cast<int>(radius / m_scale);
1190  cv::Scalar cv_color;
1191  if (color.id < vpColor::id_unknown) {
1192  cv_color = col[color.id];
1193  }
1194  else {
1195  cv_color = CV_RGB(color.R, color.G, color.B);
1196  }
1197 
1198  if (fill == false) {
1199  int cv_thickness = static_cast<int>(thickness);
1200 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1201  cvCircle(m_background, cvPoint(x, y), r, cv_color, cv_thickness);
1202 #else
1203  cv::circle(m_background, cv::Point(x, y), r, cv_color, cv_thickness);
1204 #endif
1205  }
1206  else {
1207 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1208  int filled = cv::FILLED;
1209 #else
1210  int filled = CV_FILLED;
1211 #endif
1212  double opacity = static_cast<double>(color.A) / 255.0;
1213 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1214  overlay([x, y, r, cv_color, filled](cv::Mat image) { cvCircle(image, cvPoint(x, y), r, cv_color, filled); },
1215  opacity);
1216 #else
1217  overlay([x, y, r, cv_color, filled](cv::Mat image) { cv::circle(image, cv::Point(x, y), r, cv_color, filled); },
1218  opacity);
1219 #endif
1220  }
1221  }
1222  else {
1223  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1224  }
1225 }
1226 
1234 void vpDisplayOpenCV::displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color,
1235  unsigned int thickness)
1236 {
1238  vpImagePoint top, bottom, left, right;
1239  top.set_i(ip.get_i() - size / 2);
1240  top.set_j(ip.get_j());
1241  bottom.set_i(ip.get_i() + size / 2);
1242  bottom.set_j(ip.get_j());
1243  left.set_i(ip.get_i());
1244  left.set_j(ip.get_j() - size / 2);
1245  right.set_i(ip.get_i());
1246  right.set_j(ip.get_j() + size / 2);
1247  displayLine(top, bottom, color, thickness);
1248  displayLine(left, right, color, thickness);
1249  }
1250  else {
1251  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1252  }
1253 }
1254 
1262 void vpDisplayOpenCV::displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1263  unsigned int thickness)
1264 {
1266  vpImagePoint ip1_ = ip1;
1267  vpImagePoint ip2_ = ip2;
1268 
1269  double size = 10. * m_scale;
1270  double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
1271  bool vertical_line = (int)ip2_.get_j() == (int)ip1_.get_j();
1272  if (vertical_line) {
1273  if (ip2_.get_i() < ip1_.get_i()) {
1274  std::swap(ip1_, ip2_);
1275  }
1276  }
1277  else if (ip2_.get_j() < ip1_.get_j()) {
1278  std::swap(ip1_, ip2_);
1279  }
1280 
1281  double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
1282  double deltaj = size / length * diff_j;
1283  double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
1284  double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
1285  double orig = ip1_.get_i() - slope * ip1_.get_j();
1286 
1287  if (vertical_line) {
1288  for (unsigned int i = (unsigned int)ip1_.get_i(); i < ip2_.get_i(); i += (unsigned int)(2 * deltai)) {
1289  double j = ip1_.get_j();
1290  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j), color, thickness);
1291  }
1292  }
1293  else {
1294  for (unsigned int j = (unsigned int)ip1_.get_j(); j < ip2_.get_j(); j += (unsigned int)(2 * deltaj)) {
1295  double i = slope * j + orig;
1296  displayLine(vpImagePoint(i, j), vpImagePoint(i + deltai, j + deltaj), color, thickness);
1297  }
1298  }
1299  }
1300  else {
1301  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1302  }
1303 }
1304 
1311 void vpDisplayOpenCV::displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
1312  unsigned int thickness)
1313 {
1315  if (color.id < vpColor::id_unknown) {
1316 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1317  cvLine(m_background, cvPoint(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1318  cvPoint(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), col[color.id],
1319  (int)thickness);
1320 #else
1321  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1322  cv::Point(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), col[color.id],
1323  (int)thickness);
1324 #endif
1325  }
1326  else {
1327  cvcolor = CV_RGB(color.R, color.G, color.B);
1328 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1329  cvLine(m_background, cvPoint(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1330  cvPoint(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), cvcolor,
1331  (int)thickness);
1332 #else
1333  cv::line(m_background, cv::Point(vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale)),
1334  cv::Point(vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale)), cvcolor,
1335  (int)thickness);
1336 #endif
1337  }
1338  }
1339  else {
1340  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1341  }
1342 }
1343 
1350 void vpDisplayOpenCV::displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
1351 {
1353  for (unsigned int i = 0; i < thickness; i++) {
1354  if (color.id < vpColor::id_unknown) {
1355 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1356  cvLine(m_background, cvPoint(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1357  cvPoint(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1358  col[color.id], (int)thickness);
1359 #else
1360  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1361  cv::Point(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1362  col[color.id], (int)thickness);
1363 #endif
1364  }
1365  else {
1366  cvcolor = CV_RGB(color.R, color.G, color.B);
1367 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1368  cvLine(m_background, cvPoint(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1369  cvPoint(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1370  cvcolor, (int)thickness);
1371 #else
1372  cv::line(m_background, cv::Point(vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale)),
1373  cv::Point(vpMath::round(ip.get_u() / m_scale + thickness - 1), vpMath::round(ip.get_v() / m_scale)),
1374  cvcolor, (int)thickness);
1375 #endif
1376  }
1377  }
1378  }
1379  else {
1380  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1381  }
1382 }
1383 
1399 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, unsigned int w, unsigned int h,
1400  const vpColor &color, bool fill, unsigned int thickness)
1401 {
1403  int left = vpMath::round(topLeft.get_u() / m_scale);
1404  int top = vpMath::round(topLeft.get_v() / m_scale);
1405  int right = vpMath::round((topLeft.get_u() + w) / m_scale);
1406  int bottom = vpMath::round((topLeft.get_v() + h) / m_scale);
1407  cv::Scalar cv_color;
1408  if (color.id < vpColor::id_unknown) {
1409  cv_color = col[color.id];
1410  }
1411  else {
1412  cv_color = CV_RGB(color.R, color.G, color.B);
1413  }
1414 
1415  if (fill == false) {
1416  int cv_thickness = static_cast<int>(thickness);
1417 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1418  cvRectangle(m_background, cvPoint(left, top), cvPoint(right, bottom), cv_color, cv_thickness);
1419 #else
1420  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1421 #endif
1422  }
1423  else {
1424 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1425  int filled = cv::FILLED;
1426 #else
1427  int filled = CV_FILLED;
1428 #endif
1429  double opacity = static_cast<double>(color.A) / 255.0;
1430 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1431  overlay([left, top, right, bottom, cv_color, filled](
1432  cv::Mat image) { cvRectangle(image, cvPoint(left, top), cvPoint(right, bottom), cv_color, filled); },
1433  opacity);
1434 #else
1435  overlay(
1436  [left, top, right, bottom, cv_color, filled](cv::Mat image) {
1437  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1438  },
1439  opacity);
1440 #endif
1441  }
1442  }
1443  else {
1444  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1445  }
1446 }
1461 void vpDisplayOpenCV::displayRectangle(const vpImagePoint &topLeft, const vpImagePoint &bottomRight,
1462  const vpColor &color, bool fill, unsigned int thickness)
1463 {
1465  int left = vpMath::round(topLeft.get_u() / m_scale);
1466  int top = vpMath::round(topLeft.get_v() / m_scale);
1467  int right = vpMath::round(bottomRight.get_u() / m_scale);
1468  int bottom = vpMath::round(bottomRight.get_v() / m_scale);
1469  cv::Scalar cv_color;
1470  if (color.id < vpColor::id_unknown) {
1471  cv_color = col[color.id];
1472  }
1473  else {
1474  cv_color = CV_RGB(color.R, color.G, color.B);
1475  }
1476 
1477  if (fill == false) {
1478  int cv_thickness = static_cast<int>(thickness);
1479 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1480  cvRectangle(m_background, cvPoint(left, top), cvPoint(right, bottom), cv_color, cv_thickness);
1481 #else
1482  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1483 #endif
1484  }
1485  else {
1486 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1487  int filled = cv::FILLED;
1488 #else
1489  int filled = CV_FILLED;
1490 #endif
1491  double opacity = static_cast<double>(color.A) / 255.0;
1492 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1493  overlay([left, top, right, bottom, cv_color, filled](
1494  cv::Mat image) { cvRectangle(image, cvPoint(left, top), cvPoint(right, bottom), cv_color, filled); },
1495  opacity);
1496 #else
1497  overlay(
1498  [left, top, right, bottom, cv_color, filled](cv::Mat image) {
1499  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1500  },
1501  opacity);
1502 #endif
1503  }
1504  }
1505  else {
1506  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1507  }
1508 }
1509 
1523 void vpDisplayOpenCV::displayRectangle(const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
1524 {
1526  int left = vpMath::round(rectangle.getLeft() / m_scale);
1527  int top = vpMath::round(rectangle.getTop() / m_scale);
1528  int right = vpMath::round(rectangle.getRight() / m_scale);
1529  int bottom = vpMath::round(rectangle.getBottom() / m_scale);
1530  cv::Scalar cv_color;
1531  if (color.id < vpColor::id_unknown) {
1532  cv_color = col[color.id];
1533  }
1534  else {
1535  cv_color = CV_RGB(color.R, color.G, color.B);
1536  }
1537 
1538  if (fill == false) {
1539  int cv_thickness = static_cast<int>(thickness);
1540 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1541  cvRectangle(m_background, cvPoint(left, top), cvPoint(right, bottom), cv_color, cv_thickness);
1542 #else
1543  cv::rectangle(m_background, cv::Point(left, top), cv::Point(right, bottom), cv_color, cv_thickness);
1544 #endif
1545  }
1546  else {
1547 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
1548  int filled = cv::FILLED;
1549 #else
1550  int filled = CV_FILLED;
1551 #endif
1552  double opacity = static_cast<double>(color.A) / 255.0;
1553 #if VISP_HAVE_OPENCV_VERSION < 0x020408
1554  overlay([left, top, right, bottom, cv_color, filled](
1555  cv::Mat image) { cvRectangle(image, cvPoint(left, top), cvPoint(right, bottom), cv_color, filled); },
1556  opacity);
1557 #else
1558  overlay(
1559  [left, top, right, bottom, cv_color, filled](cv::Mat image) {
1560  cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv_color, filled);
1561  },
1562  opacity);
1563 #endif
1564  }
1565  }
1566  else {
1567  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1568  }
1569 }
1570 
1586 bool vpDisplayOpenCV::getClick(bool blocking)
1587 {
1588  bool ret = false;
1590  flushDisplay();
1591  if (blocking) {
1592  lbuttondown = false;
1593  mbuttondown = false;
1594  rbuttondown = false;
1595  }
1596  do {
1597  if (lbuttondown) {
1598  ret = true;
1599  lbuttondown = false;
1600  }
1601  if (mbuttondown) {
1602  ret = true;
1603  mbuttondown = false;
1604  }
1605  if (rbuttondown) {
1606  ret = true;
1607  rbuttondown = false;
1608  }
1609  if (blocking)
1610 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1611  cvWaitKey(10);
1612 #else
1613  cv::waitKey(10);
1614 #endif
1615  } while (ret == false && blocking == true);
1616  }
1617  else {
1618  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1619  }
1620  return ret;
1621 }
1622 
1638 bool vpDisplayOpenCV::getClick(vpImagePoint &ip, bool blocking)
1639 {
1640  bool ret = false;
1641 
1643  flushDisplay();
1644 
1645  double u, v;
1646 
1647  if (blocking) {
1648  lbuttondown = false;
1649  mbuttondown = false;
1650  rbuttondown = false;
1651  }
1652  do {
1653  if (lbuttondown) {
1654  ret = true;
1655  u = (unsigned int)x_lbuttondown * m_scale;
1656  v = (unsigned int)y_lbuttondown * m_scale;
1657  ip.set_u(u);
1658  ip.set_v(v);
1659  lbuttondown = false;
1660  }
1661  if (mbuttondown) {
1662  ret = true;
1663  u = (unsigned int)x_mbuttondown * m_scale;
1664  v = (unsigned int)y_mbuttondown * m_scale;
1665  ip.set_u(u);
1666  ip.set_v(v);
1667  mbuttondown = false;
1668  }
1669  if (rbuttondown) {
1670  ret = true;
1671  u = (unsigned int)x_rbuttondown * m_scale;
1672  v = (unsigned int)y_rbuttondown * m_scale;
1673  ip.set_u(u);
1674  ip.set_v(v);
1675  rbuttondown = false;
1676  }
1677  if (blocking)
1678 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1679  cvWaitKey(10);
1680 #else
1681  cv::waitKey(10);
1682 #endif
1683  } while (ret == false && blocking == true);
1684  }
1685  else {
1686  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1687  }
1688  return ret;
1689 }
1690 
1710 {
1711  bool ret = false;
1712 
1714  // flushDisplay() ;
1715  double u, v;
1716  if (blocking) {
1717  lbuttondown = false;
1718  mbuttondown = false;
1719  rbuttondown = false;
1720  }
1721  do {
1722  if (lbuttondown) {
1723  ret = true;
1724  u = (unsigned int)x_lbuttondown * m_scale;
1725  v = (unsigned int)y_lbuttondown * m_scale;
1726  ip.set_u(u);
1727  ip.set_v(v);
1728  button = vpMouseButton::button1;
1729  lbuttondown = false;
1730  }
1731  if (mbuttondown) {
1732  ret = true;
1733  u = (unsigned int)x_mbuttondown * m_scale;
1734  v = (unsigned int)y_mbuttondown * m_scale;
1735  ip.set_u(u);
1736  ip.set_v(v);
1737  button = vpMouseButton::button2;
1738  mbuttondown = false;
1739  }
1740  if (rbuttondown) {
1741  ret = true;
1742  u = (unsigned int)x_rbuttondown * m_scale;
1743  v = (unsigned int)y_rbuttondown * m_scale;
1744  ip.set_u(u);
1745  ip.set_v(v);
1746  button = vpMouseButton::button3;
1747  rbuttondown = false;
1748  }
1749  if (blocking)
1750 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1751  cvWaitKey(10);
1752 #else
1753  cv::waitKey(10);
1754 #endif
1755  } while (ret == false && blocking == true);
1756  }
1757  else {
1758  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1759  }
1760  return ret;
1761 }
1762 
1785 {
1786  bool ret = false;
1788  // flushDisplay() ;
1789  double u, v;
1790  if (blocking) {
1791  lbuttonup = false;
1792  mbuttonup = false;
1793  rbuttonup = false;
1794  }
1795  do {
1796  if (lbuttonup) {
1797  ret = true;
1798  u = (unsigned int)x_lbuttonup * m_scale;
1799  v = (unsigned int)y_lbuttonup * m_scale;
1800  ip.set_u(u);
1801  ip.set_v(v);
1802  button = vpMouseButton::button1;
1803  lbuttonup = false;
1804  }
1805  if (mbuttonup) {
1806  ret = true;
1807  u = (unsigned int)x_mbuttonup * m_scale;
1808  v = (unsigned int)y_mbuttonup * m_scale;
1809  ip.set_u(u);
1810  ip.set_v(v);
1811  button = vpMouseButton::button2;
1812  mbuttonup = false;
1813  }
1814  if (rbuttonup) {
1815  ret = true;
1816  u = (unsigned int)x_rbuttonup * m_scale;
1817  v = (unsigned int)y_rbuttonup * m_scale;
1818  ip.set_u(u);
1819  ip.set_v(v);
1820  button = vpMouseButton::button3;
1821  rbuttonup = false;
1822  }
1823  if (blocking)
1824 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1825  cvWaitKey(10);
1826 #else
1827  cv::waitKey(10);
1828 #endif
1829  } while (ret == false && blocking == true);
1830  }
1831  else {
1832  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1833  }
1834  return ret;
1835 }
1836 
1837 /*
1838  Gets the displayed image (including the overlay plane)
1839  and returns an RGBa image.
1840 */
1842 {
1843  vpImageConvert::convert(m_background, I);
1844  // should certainly be optimized.
1845 }
1846 
1847 void vpDisplayOpenCV::on_mouse(int event, int x, int y, int /*flags*/, void *display)
1848 {
1849  vpDisplayOpenCV *disp = static_cast<vpDisplayOpenCV *>(display);
1850  switch (event) {
1851 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1852  case CV_EVENT_MOUSEMOVE:
1853 #else
1854  case cv::EVENT_MOUSEMOVE:
1855 #endif
1856  {
1857  disp->move = true;
1858  disp->x_move = x;
1859  disp->y_move = y;
1860  break;
1861  }
1862 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1863  case CV_EVENT_LBUTTONDOWN:
1864 #else
1865  case cv::EVENT_LBUTTONDOWN:
1866 #endif
1867  {
1868  disp->lbuttondown = true;
1869  disp->x_lbuttondown = x;
1870  disp->y_lbuttondown = y;
1871  break;
1872  }
1873 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1874  case CV_EVENT_MBUTTONDOWN:
1875 #else
1876  case cv::EVENT_MBUTTONDOWN:
1877 #endif
1878  {
1879  disp->mbuttondown = true;
1880  disp->x_mbuttondown = x;
1881  disp->y_mbuttondown = y;
1882  break;
1883  }
1884 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1885  case CV_EVENT_RBUTTONDOWN:
1886 #else
1887  case cv::EVENT_RBUTTONDOWN:
1888 #endif
1889  {
1890  disp->rbuttondown = true;
1891  disp->x_rbuttondown = x;
1892  disp->y_rbuttondown = y;
1893  break;
1894  }
1895 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1896  case CV_EVENT_LBUTTONUP:
1897 #else
1898  case cv::EVENT_LBUTTONUP:
1899 #endif
1900  {
1901  disp->lbuttonup = true;
1902  disp->x_lbuttonup = x;
1903  disp->y_lbuttonup = y;
1904  break;
1905  }
1906 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1907  case CV_EVENT_MBUTTONUP:
1908 #else
1909  case cv::EVENT_MBUTTONUP:
1910 #endif
1911  {
1912  disp->mbuttonup = true;
1913  disp->x_mbuttonup = x;
1914  disp->y_mbuttonup = y;
1915  break;
1916  }
1917 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1918  case CV_EVENT_RBUTTONUP:
1919 #else
1920  case cv::EVENT_RBUTTONUP:
1921 #endif
1922  {
1923  disp->rbuttonup = true;
1924  disp->x_rbuttonup = x;
1925  disp->y_rbuttonup = y;
1926  break;
1927  }
1928 
1929  default:
1930  break;
1931  }
1932 }
1933 
1950 {
1952  int delay;
1953  flushDisplay();
1954  if (blocking)
1955  delay = 0;
1956  else
1957  delay = 10;
1958 
1959 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
1960  int key_pressed = cvWaitKey(delay);
1961 #else
1962  int key_pressed = cv::waitKey(delay);
1963 #endif
1964 
1965  if (key_pressed == -1)
1966  return false;
1967  return true;
1968  }
1969  else {
1970  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
1971  }
1972  // return false; // Never reached after throw()
1973 }
1992 bool vpDisplayOpenCV::getKeyboardEvent(std::string &key, bool blocking)
1993 {
1995  int delay;
1996  flushDisplay();
1997  if (blocking)
1998  delay = 0;
1999  else
2000  delay = 10;
2001 
2002 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
2003  int key_pressed = cvWaitKey(delay);
2004 #else
2005  int key_pressed = cv::waitKey(delay);
2006 #endif
2007  if (key_pressed == -1)
2008  return false;
2009  else {
2010  // std::cout << "Key pressed: \"" << key_pressed << "\"" << std::endl;
2011  std::stringstream ss;
2012  ss << key_pressed;
2013  key = ss.str();
2014  }
2015  return true;
2016  }
2017  else {
2018  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
2019  }
2020  // return false; // Never reached after throw()
2021 }
2022 
2034 {
2035  bool ret = false;
2036 
2038  // flushDisplay() ;
2039  if (move) {
2040  ret = true;
2041  double u = (unsigned int)x_move / m_scale;
2042  double v = (unsigned int)y_move / m_scale;
2043  ip.set_u(u);
2044  ip.set_v(v);
2045  move = false;
2046  }
2047  }
2048 
2049  else {
2050  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
2051  }
2052  return ret;
2053 }
2054 
2066 {
2068  bool moved = getPointerMotionEvent(ip);
2069  if (!moved) {
2070  double u, v;
2071  u = (unsigned int)x_move / m_scale;
2072  v = (unsigned int)y_move / m_scale;
2073  ip.set_u(u);
2074  ip.set_v(v);
2075  }
2076  return false;
2077  }
2078  else {
2079  throw(vpDisplayException(vpDisplayException::notInitializedError, "OpenCV not initialized"));
2080  }
2081 }
2082 
2087 void vpDisplayOpenCV::getScreenSize(unsigned int &w, unsigned int &h)
2088 {
2089  w = h = 0;
2090 
2091 #if defined(VISP_HAVE_X11)
2092  vpDisplayX d;
2093  d.getScreenSize(w, h);
2094 #elif defined(VISP_HAVE_XRANDR)
2095  std::string command = "xrandr | grep '*'";
2096  FILE *fpipe = (FILE *)popen(command.c_str(), "r");
2097  char line[256];
2098  while (fgets(line, sizeof(line), fpipe)) {
2099  std::string str(line);
2100  std::size_t found = str.find("Failed");
2101 
2102  if (found == std::string::npos) {
2103  std::vector<std::string> elm;
2104  elm = vpIoTools::splitChain(str, " ");
2105  for (size_t i = 0; i < elm.size(); i++) {
2106  if (!elm[i].empty()) {
2107  std::vector<std::string> resolution = vpIoTools::splitChain(elm[i], "x");
2108  if (resolution.size() == 2) {
2109  std::istringstream sswidth(resolution[0]), ssheight(resolution[1]);
2110  sswidth >> w;
2111  ssheight >> h;
2112  break;
2113  }
2114  }
2115  }
2116  }
2117  }
2118  pclose(fpipe);
2119 #elif defined(_WIN32)
2120 #if !defined(WINRT)
2121  w = GetSystemMetrics(SM_CXSCREEN);
2122  h = GetSystemMetrics(SM_CYSCREEN);
2123 #else
2124  throw(vpException(vpException::functionNotImplementedError, "The function vpDisplayOpenCV::getScreenSize() is not "
2125  "implemented on winrt"));
2126 #endif
2127 #endif
2128 }
2129 
2134 {
2135  unsigned int width, height;
2136  getScreenSize(width, height);
2137  return width;
2138 }
2139 
2144 {
2145  unsigned int width, height;
2146  getScreenSize(width, height);
2147  return height;
2148 }
2149 
2155 void vpDisplayOpenCV::overlay(std::function<void(cv::Mat &)> overlay_function, double opacity)
2156 {
2157  // Initialize overlay layer for transparency
2158  cv::Mat overlay;
2159  if (opacity < 1.0) {
2160  // Deep copy
2161  overlay = m_background.clone();
2162  }
2163  else {
2164  // Shallow copy
2165  overlay = m_background;
2166  }
2167 
2168  overlay_function(overlay);
2169 
2170  // Blend background and overlay
2171  if (opacity < 1.0) {
2172  cv::addWeighted(overlay, opacity, m_background, 1.0 - opacity, 0.0, m_background);
2173  }
2174 }
2175 
2176 #elif !defined(VISP_BUILD_SHARED_LIBS)
2177 // Work around to avoid warning: libvisp_core.a(vpDisplayOpenCV.cpp.o) has no symbols
2178 void dummy_vpDisplayOpenCV() { };
2179 #endif
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:152
static const vpColor white
Definition: vpColor.h:206
vpColorIdentifier id
Definition: vpColor.h:200
static const vpColor red
Definition: vpColor.h:211
static const vpColor darkGray
Definition: vpColor.h:209
static const vpColor black
Definition: vpColor.h:205
static const vpColor cyan
Definition: vpColor.h:220
static const vpColor orange
Definition: vpColor.h:221
static const vpColor darkRed
Definition: vpColor.h:212
static const vpColor blue
Definition: vpColor.h:217
static const vpColor lightGray
Definition: vpColor.h:207
static const vpColor lightBlue
Definition: vpColor.h:216
static const vpColor darkGreen
Definition: vpColor.h:215
static const vpColor darkBlue
Definition: vpColor.h:218
static const vpColor purple
Definition: vpColor.h:222
static const vpColor lightGreen
Definition: vpColor.h:213
static const vpColor yellow
Definition: vpColor.h:219
@ id_lightBlue
Definition: vpColor.h:178
@ id_yellow
Definition: vpColor.h:184
@ id_darkGray
Definition: vpColor.h:164
@ id_green
Definition: vpColor.h:174
@ id_darkRed
Definition: vpColor.h:170
@ id_lightGray
Definition: vpColor.h:160
@ id_red
Definition: vpColor.h:168
@ id_lightRed
Definition: vpColor.h:166
@ id_white
Definition: vpColor.h:158
@ id_black
Definition: vpColor.h:156
@ id_blue
Definition: vpColor.h:180
@ id_darkGreen
Definition: vpColor.h:176
@ id_gray
Definition: vpColor.h:162
@ id_lightGreen
Definition: vpColor.h:172
@ id_purple
Definition: vpColor.h:190
@ id_orange
Definition: vpColor.h:188
@ id_cyan
Definition: vpColor.h:186
@ id_darkBlue
Definition: vpColor.h:182
@ id_unknown
Definition: vpColor.h:193
static const vpColor lightRed
Definition: vpColor.h:210
static const vpColor green
Definition: vpColor.h:214
static const vpColor gray
Definition: vpColor.h:208
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:128
void getScreenSize(unsigned int &width, unsigned int &height) vp_override
Class that defines generic functionalities for display.
Definition: vpDisplay.h:173
unsigned int m_height
Definition: vpDisplay.h:212
vpScaleType m_scaleType
Definition: vpDisplay.h:215
unsigned int m_width
Definition: vpDisplay.h:211
static void display(const vpImage< unsigned char > &I)
int m_windowXPosition
display position
Definition: vpDisplay.h:208
std::string m_title
Definition: vpDisplay.h:213
int m_windowYPosition
display position
Definition: vpDisplay.h:210
unsigned int m_scale
Definition: vpDisplay.h:214
bool m_displayHasBeenInitialized
display has been initialized
Definition: vpDisplay.h:206
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:59
@ functionNotImplementedError
Function not implemented.
Definition: vpException.h:78
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:304
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:293
double get_u() const
Definition: vpImagePoint.h:136
void set_u(double u)
Definition: vpImagePoint.h:330
void set_v(double v)
Definition: vpImagePoint.h:341
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:184
vpDisplay * display
Definition: vpImage.h:140
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:2377
static double sqr(double x)
Definition: vpMath.h:201
static int round(double x)
Definition: vpMath.h:403
Definition: vpRGBa.h:61
unsigned char B
Blue component.
Definition: vpRGBa.h:139
unsigned char R
Red component.
Definition: vpRGBa.h:137
unsigned char G
Green component.
Definition: vpRGBa.h:138
unsigned char A
Additionnal component.
Definition: vpRGBa.h:140
Defines a rectangle in the plane.
Definition: vpRect.h:76
double getLeft() const
Definition: vpRect.h:170
double getRight() const
Definition: vpRect.h:176
double getBottom() const
Definition: vpRect.h:94
double getTop() const
Definition: vpRect.h:189
#define vpTRACE
Definition: vpDebug.h:405
#define vpERROR_TRACE
Definition: vpDebug.h:382