Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
vpImageDraw.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Drawing functions.
33  *
34  *****************************************************************************/
35 // Contains code from:
36 /*
37 * Simd Library (http://ermig1979.github.io/Simd).
38 *
39 * Copyright (c) 2011-2017 Yermalayeu Ihar.
40 *
41 * Permission is hereby granted, free of charge, to any person obtaining a copy
42 * of this software and associated documentation files (the "Software"), to deal
43 * in the Software without restriction, including without limitation the rights
44 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45 * copies of the Software, and to permit persons to whom the Software is
46 * furnished to do so, subject to the following conditions:
47 *
48 * The above copyright notice and this permission notice shall be included in
49 * all copies or substantial portions of the Software.
50 *
51 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
56 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
57 * SOFTWARE.
58 */
59 
60 #include <visp3/core/vpImageDraw.h>
61 #include <visp3/core/vpPoint.h>
62 #include <visp3/core/vpMeterPixelConversion.h>
63 
64 namespace
65 {
66 template<class Type> void DrawLine(vpImage<Type> & canvas, int x1, int y1, int x2, int y2, const Type & color, unsigned int width = 1)
67 {
68  const int w = static_cast<int>(canvas.getWidth()) - 1;
69  const int h = static_cast<int>(canvas.getHeight()) - 1;
70 
71  if (x1 < 0 || y1 < 0 || (x1 - w) > 0 || (y1 - h) > 0 || x2 < 0 || y2 < 0 || (x2 - w) > 0 || (y2 - h) > 0) {
72  if ((x1 < 0 && x2 < 0) || (y1 < 0 && y2 < 0) || ((x1 - w) > 0 && (x2 - w) > 0) || ((y1 - h) > 0 && (y2 -h) > 0)) {
73  return;
74  }
75 
76  if (y1 == y2) {
77  x1 = std::min<int>(std::max<int>(x1, 0), w);
78  x2 = std::min<int>(std::max<int>(x2, 0), w);
79  } else if (x1 == x2) {
80  y1 = std::min<int>(std::max<int>(y1, 0), h);
81  y2 = std::min<int>(std::max<int>(y2, 0), h);
82  } else {
83  int x0 = (x1*y2 - y1*x2) / (y2 - y1);
84  int y0 = (y1*x2 - x1*y2) / (x2 - x1);
85  int xh = (x1*y2 - y1*x2 + h*(x2 - x1)) / (y2 - y1);
86  int yw = (y1*x2 - x1*y2 + w*(y2 - y1)) / (x2 - x1);
87 
88  if (x1 < 0) {
89  x1 = 0;
90  y1 = y0;
91  }
92  if (x2 < 0) {
93  x2 = 0;
94  y2 = y0;
95  }
96  if (x1 > w) {
97  x1 = w;
98  y1 = yw;
99  }
100  if (x2 > w) {
101  x2 = w;
102  y2 = yw;
103  }
104  if ((y1 < 0 && y2 < 0) || (y1 > h && y2 > h)) {
105  return;
106  }
107 
108  if (y1 < 0) {
109  x1 = x0;
110  y1 = 0;
111  }
112  if (y2 < 0) {
113  x2 = x0;
114  y2 = 0;
115  }
116 
117  if (y1 > h) {
118  x1 = xh;
119  y1 = h;
120  }
121  if (y2 > h) {
122  x2 = xh;
123  y2 = h;
124  }
125  }
126  }
127 
128  const bool inverse = ((std::abs(y2 - y1) - std::abs(x2 - x1)) > 0);
129  if (inverse) {
130  std::swap(x1, y1);
131  std::swap(x2, y2);
132  }
133 
134  if (x1 > x2) {
135  std::swap(x1, x2);
136  std::swap(y1, y2);
137  }
138 
139  const double dx = x2 - x1;
140  const double dy = static_cast<double>(std::abs(y2 - y1));
141 
142  double error = dx / 2.0f;
143  const int ystep = (y1 < y2) ? 1 : -1;
144  int y0 = y1 - static_cast<int>(width) / 2;
145 
146  for (int x = x1; x <= x2; x++) {
147  for (int i = 0; i < static_cast<int>(width); i++) {
148  int y = y0 + i;
149  if (y >= 0) {
150  if (inverse) {
151  if (y < w) {
152  canvas[x][y] = color;
153  }
154  } else {
155  if (y < h) {
156  canvas[y][x] = color;
157  }
158  }
159  }
160 
161  }
162 
163  error -= dy;
164  if (error < 0) {
165  y0 += ystep;
166  error += dx;
167  }
168  }
169 }
170 
171 template<class Type> void DrawCircle(vpImage<Type> & canvas, const vpImagePoint & center, int radius, const Type & color, unsigned int width = 1)
172 {
173  const size_t n = 8 * std::max(static_cast<size_t>(1), static_cast<size_t>(::pow(radius, 0.5)));
174  double px = 0, py = 0, da = 2 * M_PI / n;
175  for (size_t i = 0; i <= n; i++) {
176  double a = i*da;
177  double cx = radius*::cos(a) + center.get_u();
178  double cy = radius*::sin(a) + center.get_v();
179  if (i > 0) {
180  DrawLine(canvas, static_cast<int>(cx), static_cast<int>(cy), static_cast<int>(px), static_cast<int>(py), color, width);
181  }
182  px = cx;
183  py = cy;
184  }
185 }
186 
187 template<class Type> void DrawFilledRectangle(vpImage<Type> & canvas, vpRect rect, const Type & color)
188 {
189  rect &= vpRect(0, 0, canvas.getWidth(), canvas.getHeight());
190  for (int row = static_cast<int>(rect.getTop()); row < static_cast<int>(rect.getBottom()); row++) {
191  Type * dst = canvas[row];
192  for (int col = static_cast<int>(rect.getLeft()); col < static_cast<int>(rect.getRight()); col++) {
193  dst[col] = color;
194  }
195  }
196 }
197 
198 template<class Type> void DrawPolygon(vpImage<Type> & canvas, const std::vector<vpImagePoint> & polygon,
199  const Type & color, unsigned int width = 1, bool closed = true)
200 {
201  if (closed) {
202  for (size_t i = 0; i < polygon.size(); i++) {
203  const vpImagePoint & p1 = (i ? polygon[i - 1] : polygon.back()), p2 = polygon[i];
204  DrawLine(canvas, static_cast<int>(p1.get_u()), static_cast<int>(p1.get_v()),
205  static_cast<int>(p2.get_u()), static_cast<int>(p2.get_v()), color, width);
206  }
207  }
208  else {
209  for (size_t i = 1; i < polygon.size(); i++) {
210  DrawLine(canvas, static_cast<int>(polygon[i-1].get_u()), static_cast<int>(polygon[i-1].get_v()),
211  static_cast<int>(polygon[i].get_u()), static_cast<int>(polygon[i].get_v()), color, width);
212  }
213  }
214 }
215 
216 template<class Type> void DrawRectangle(vpImage<Type> & canvas, const vpRect & rect, const Type & color, unsigned int width = 1)
217 {
218  DrawLine(canvas, static_cast<int>(rect.getLeft()), static_cast<int>(rect.getTop()),
219  static_cast<int>(rect.getRight()), static_cast<int>(rect.getTop()), color, width);
220  DrawLine(canvas, static_cast<int>(rect.getRight()), static_cast<int>(rect.getTop()),
221  static_cast<int>(rect.getRight()), static_cast<int>(rect.getBottom()), color, width);
222  DrawLine(canvas, static_cast<int>(rect.getRight()), static_cast<int>(rect.getBottom()),
223  static_cast<int>(rect.getLeft()), static_cast<int>(rect.getBottom()), color, width);
224  DrawLine(canvas, static_cast<int>(rect.getLeft()), static_cast<int>(rect.getBottom()),
225  static_cast<int>(rect.getLeft()), static_cast<int>(rect.getTop()), color, width);
226 }
227 }
228 
238  unsigned char color, unsigned int w, unsigned int h, unsigned int thickness)
239 {
240  double a = ip2.get_i() - ip1.get_i();
241  double b = ip2.get_j() - ip1.get_j();
242  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
243 
244  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
245  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
246  // DisplayCrossLarge(i1,j1,3,col) ;
247  } else {
248  a /= lg;
249  b /= lg;
250 
251  vpImagePoint ip3;
252  ip3.set_i(ip2.get_i() - w * a);
253  ip3.set_j(ip2.get_j() - w * b);
254 
255  vpImagePoint ip4;
256  ip4.set_i(ip3.get_i() - b * h);
257  ip4.set_j(ip3.get_j() + a * h);
258 
259  if (lg > 2 * vpImagePoint::distance(ip2, ip4)) {
260  drawLine(I, ip2, ip4, color, thickness);
261  }
262 
263  ip4.set_i(ip3.get_i() + b * h);
264  ip4.set_j(ip3.get_j() - a * h);
265 
266  if (lg > 2 * vpImagePoint::distance(ip2, ip4)) {
267  drawLine(I, ip2, ip4, color, thickness);
268  }
269 
270  drawLine(I, ip1, ip2, color, thickness);
271  }
272 }
273 
283  const vpColor &color, unsigned int w, unsigned int h, unsigned int thickness)
284 {
285  double a = ip2.get_i() - ip1.get_i();
286  double b = ip2.get_j() - ip1.get_j();
287  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
288 
289  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
290  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
291  // DisplayCrossLarge(i1,j1,3,col) ;
292  } else {
293  a /= lg;
294  b /= lg;
295 
296  vpImagePoint ip3;
297  ip3.set_i(ip2.get_i() - w * a);
298  ip3.set_j(ip2.get_j() - w * b);
299 
300  vpImagePoint ip4;
301  ip4.set_i(ip3.get_i() - b * h);
302  ip4.set_j(ip3.get_j() + a * h);
303 
304  if (lg > 2 * vpImagePoint::distance(ip2, ip4)) {
305  drawLine(I, ip2, ip4, color, thickness);
306  }
307 
308  ip4.set_i(ip3.get_i() + b * h);
309  ip4.set_j(ip3.get_j() - a * h);
310 
311  if (lg > 2 * vpImagePoint::distance(ip2, ip4)) {
312  drawLine(I, ip2, ip4, color, thickness);
313  }
314 
315  drawLine(I, ip1, ip2, color, thickness);
316  }
317 }
318 
328  unsigned int radius, unsigned char color, unsigned int thickness)
329 {
330  DrawCircle(I, center, static_cast<int>(radius), color, thickness);
331 }
332 
342  unsigned int radius, const vpColor &color, unsigned int thickness)
343 {
344  DrawCircle(I, center, static_cast<int>(radius), vpRGBa(color.R, color.G, color.B), thickness);
345 }
346 
355 void vpImageDraw::drawCross(vpImage<unsigned char> &I, const vpImagePoint &ip, unsigned int size,
356  unsigned char color, unsigned int thickness)
357 {
358  vpImagePoint top, bottom, left, right;
359  top.set_i(ip.get_i() - size / 2);
360  top.set_j(ip.get_j());
361  bottom.set_i(ip.get_i() + size / 2);
362  bottom.set_j(ip.get_j());
363  left.set_i(ip.get_i());
364  left.set_j(ip.get_j() - size / 2);
365  right.set_i(ip.get_i());
366  right.set_j(ip.get_j() + size / 2);
367  drawLine(I, top, bottom, color, thickness);
368  drawLine(I, left, right, color, thickness);
369 }
370 
379 void vpImageDraw::drawCross(vpImage<vpRGBa> &I, const vpImagePoint &ip, unsigned int size,
380  const vpColor &color, unsigned int thickness)
381 {
382  vpImagePoint top, bottom, left, right;
383  top.set_i(ip.get_i() - size / 2);
384  top.set_j(ip.get_j());
385  bottom.set_i(ip.get_i() + size / 2);
386  bottom.set_j(ip.get_j());
387  left.set_i(ip.get_i());
388  left.set_j(ip.get_j() - size / 2);
389  right.set_i(ip.get_i());
390  right.set_j(ip.get_j() + size / 2);
391  drawLine(I, top, bottom, color, thickness);
392  drawLine(I, left, right, color, thickness);
393 }
394 
403  unsigned char color, unsigned int thickness)
404 {
405  vpImagePoint ip1_ = ip1;
406  vpImagePoint ip2_ = ip2;
407 
408  double size = 10;
409  double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
410  bool vertical_line = static_cast<int>(ip2_.get_j()) == static_cast<int>(ip1_.get_j());
411  if (vertical_line) {
412  if (ip2_.get_i() < ip1_.get_i()) {
413  std::swap(ip1_, ip2_);
414  }
415  } else if (ip2_.get_j() < ip1_.get_j()) {
416  std::swap(ip1_, ip2_);
417  }
418 
419  double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
420  double deltaj = size / length * diff_j;
421  double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
422  double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
423  double orig = ip1_.get_i() - slope * ip1_.get_j();
424 
425  if (vertical_line) {
426  for (unsigned int i = static_cast<unsigned int>(ip1_.get_i()); i < ip2_.get_i(); i += static_cast<unsigned int>(2 * deltai)) {
427  double j = ip1_.get_j();
428  drawLine(I, vpImagePoint(i, j), vpImagePoint(i + deltai, j), color, thickness);
429  }
430  } else {
431  for (unsigned int j = static_cast<unsigned int>(ip1_.get_j()); j < ip2_.get_j(); j += static_cast<unsigned int>(2 * deltaj)) {
432  double i = slope * j + orig;
433  drawLine(I, vpImagePoint(i, j), vpImagePoint(i + deltai, j + deltaj), color, thickness);
434  }
435  }
436 }
437 
445 void vpImageDraw::drawDottedLine(vpImage<vpRGBa> &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness)
446 {
447  vpImagePoint ip1_ = ip1;
448  vpImagePoint ip2_ = ip2;
449 
450  double size = 10;
451  double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
452  bool vertical_line = static_cast<int>(ip2_.get_j()) == static_cast<int>(ip1_.get_j());
453  if (vertical_line) {
454  if (ip2_.get_i() < ip1_.get_i()) {
455  std::swap(ip1_, ip2_);
456  }
457  } else if (ip2_.get_j() < ip1_.get_j()) {
458  std::swap(ip1_, ip2_);
459  }
460 
461  double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
462  double deltaj = size / length * diff_j;
463  double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
464  double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
465  double orig = ip1_.get_i() - slope * ip1_.get_j();
466 
467  if (vertical_line) {
468  for (unsigned int i = static_cast<unsigned int>(ip1_.get_i()); i < ip2_.get_i(); i += static_cast<unsigned int>(2 * deltai)) {
469  double j = ip1_.get_j();
470  drawLine(I, vpImagePoint(i, j), vpImagePoint(i + deltai, j), color, thickness);
471  }
472  } else {
473  for (unsigned int j = static_cast<unsigned int>(ip1_.get_j()); j < ip2_.get_j(); j += static_cast<unsigned int>(2 * deltaj)) {
474  double i = slope * j + orig;
475  drawLine(I, vpImagePoint(i, j), vpImagePoint(i + deltai, j + deltaj), color, thickness);
476  }
477  }
478 }
479 
535 void vpImageDraw::drawEllipse(vpImage<unsigned char> &I, const vpImagePoint &center, double coef1,
536  double coef2, double coef3, bool use_centered_moments, unsigned char color,
537  double theta1, double theta2, unsigned int thickness)
538 {
539  double a = 0., b = 0., e = 0.;
540 
541  double mu20_p = coef1;
542  double mu11_p = coef2;
543  double mu02_p = coef3;
544 
545  if (use_centered_moments) {
546  if (std::fabs(mu11_p) > std::numeric_limits<double>::epsilon()) {
547 
548  double val_p = sqrt(vpMath::sqr(mu20_p - mu02_p) + 4 * vpMath::sqr(mu11_p));
549  a = sqrt((mu20_p + mu02_p + val_p) / 2);
550  b = sqrt((mu20_p + mu02_p - val_p) / 2);
551 
552  e = (mu02_p - mu20_p + val_p) / (2 * mu11_p);
553  e = atan(e);
554  } else {
555  a = sqrt(mu20_p);
556  b = sqrt(mu02_p);
557  e = 0.;
558  }
559  } else {
560  a = coef1;
561  b = coef2;
562  e = coef3;
563  }
564 
565  // Approximation of the circumference of an ellipse:
566  // [Ramanujan, S., "Modular Equations and Approximations to ,"
567  // Quart. J. Pure. Appl. Math., vol. 45 (1913-1914), pp. 350-372]
568  double t = (a - b) / (a + b);
569  double circumference = M_PI * (a + b) * (1 + 3 * vpMath::sqr(t) / (10 + sqrt(4 - 3 * vpMath::sqr(t))));
570 
571  int nbpoints = static_cast<int>(floor(circumference / 5));
572  if (nbpoints < 10) {
573  nbpoints = 10;
574  }
575  double incr = 2 * M_PI / nbpoints; // angle increment
576 
577  double smallalpha = vpMath::rad(theta1);
578  double highalpha = vpMath::rad(theta2);
579  double ce = cos(e);
580  double se = sin(e);
581 
582  double k = smallalpha;
583  double j1 = a * cos(k); // equation of an ellipse
584  double i1 = b * sin(k); // equation of an ellipse
585 
586  // (i1,j1) are the coordinates on the origin centered ellipse ;
587  // a rotation by "e" and a translation by (xci,jc) are done
588  // to get the coordinates of the point on the shifted ellipse
589  vpImagePoint iP11, iP22;
590  iP11.set_j(center.get_j() + ce * j1 - se * i1);
591  iP11.set_i(center.get_i() + se * j1 + ce * i1);
592 
593  while (k + incr < highalpha + incr) {
594  double j2 = a * cos(k + incr); // equation of an ellipse
595  double i2 = b * sin(k + incr); // equation of an ellipse
596 
597  // to get the coordinates of the point on the shifted ellipse
598  iP22.set_j(center.get_j() + ce * j2 - se * i2);
599  iP22.set_i(center.get_i() + se * j2 + ce * i2);
600 
601  drawLine(I, iP11, iP22, color, thickness);
602 
603  iP11 = iP22;
604 
605  k += incr;
606  }
607 }
608 
664 void vpImageDraw::drawEllipse(vpImage<vpRGBa> &I, const vpImagePoint &center, double coef1,
665  double coef2, double coef3, bool use_centered_moments, const vpColor &color,
666  double theta1, double theta2, unsigned int thickness)
667 {
668  double a = 0., b = 0., e = 0.;
669 
670  double mu20_p = coef1;
671  double mu11_p = coef2;
672  double mu02_p = coef3;
673 
674  if (use_centered_moments) {
675  if (std::fabs(mu11_p) > std::numeric_limits<double>::epsilon()) {
676  double val_p = sqrt(vpMath::sqr(mu20_p - mu02_p) + 4 * vpMath::sqr(mu11_p));
677  a = sqrt((mu20_p + mu02_p + val_p) / 2);
678  b = sqrt((mu20_p + mu02_p - val_p) / 2);
679 
680  e = (mu02_p - mu20_p + val_p) / (2 * mu11_p);
681  e = atan(e);
682  } else {
683  a = sqrt(mu20_p);
684  b = sqrt(mu02_p);
685  e = 0.;
686  }
687  } else {
688  a = coef1;
689  b = coef2;
690  e = coef3;
691  }
692 
693  // Approximation of the circumference of an ellipse:
694  // [Ramanujan, S., "Modular Equations and Approximations to ,"
695  // Quart. J. Pure. Appl. Math., vol. 45 (1913-1914), pp. 350-372]
696  double t = (a - b) / (a + b);
697  double circumference = M_PI * (a + b) * (1 + 3 * vpMath::sqr(t) / (10 + sqrt(4 - 3 * vpMath::sqr(t))));
698 
699  int nbpoints = static_cast<int>(floor(circumference / 5));
700  if (nbpoints < 10) {
701  nbpoints = 10;
702  }
703  double incr = 2 * M_PI / nbpoints; // angle increment
704 
705  double smallalpha = vpMath::rad(theta1);
706  double highalpha = vpMath::rad(theta2);
707  double ce = cos(e);
708  double se = sin(e);
709 
710  double k = smallalpha;
711  double j1 = a * cos(k); // equation of an ellipse
712  double i1 = b * sin(k); // equation of an ellipse
713 
714  // (i1,j1) are the coordinates on the origin centered ellipse ;
715  // a rotation by "e" and a translation by (xci,jc) are done
716  // to get the coordinates of the point on the shifted ellipse
717  vpImagePoint iP11, iP22;
718  iP11.set_j(center.get_j() + ce * j1 - se * i1);
719  iP11.set_i(center.get_i() + se * j1 + ce * i1);
720 
721  while (k + incr < highalpha + incr) {
722  double j2 = a * cos(k + incr); // equation of an ellipse
723  double i2 = b * sin(k + incr); // equation of an ellipse
724 
725  // to get the coordinates of the point on the shifted ellipse
726  iP22.set_j(center.get_j() + ce * j2 - se * i2);
727  iP22.set_i(center.get_i() + se * j2 + ce * i2);
728 
729  drawLine(I, iP11, iP22, color, thickness);
730 
731  iP11 = iP22;
732 
733  k += incr;
734  }
735 }
736 
753  double size, unsigned char color, unsigned int thickness, const vpImagePoint &offset)
754 {
755  vpPoint o(0.0, 0.0, 0.0);
756  vpPoint x(size, 0.0, 0.0);
757  vpPoint y(0.0, size, 0.0);
758  vpPoint z(0.0, 0.0, size);
759 
760  o.track(cMo);
761  x.track(cMo);
762  y.track(cMo);
763  z.track(cMo);
764 
765  vpImagePoint ipo, ip1;
766 
767  vpMeterPixelConversion::convertPoint(cam, o.p[0], o.p[1], ipo);
768 
769  vpMeterPixelConversion::convertPoint(cam, x.p[0], x.p[1], ip1);
770  drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
771 
772  vpMeterPixelConversion::convertPoint(cam, y.p[0], y.p[1], ip1);
773  drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
774 
775  vpMeterPixelConversion::convertPoint(cam, z.p[0], z.p[1], ip1);
776  drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
777 }
778 
795  double size, const vpColor &color, unsigned int thickness, const vpImagePoint &offset)
796 {
797  vpPoint o(0.0, 0.0, 0.0);
798  vpPoint x(size, 0.0, 0.0);
799  vpPoint y(0.0, size, 0.0);
800  vpPoint z(0.0, 0.0, size);
801 
802  o.track(cMo);
803  x.track(cMo);
804  y.track(cMo);
805  z.track(cMo);
806 
807  vpImagePoint ipo, ip1;
808 
809  if (color == vpColor::none) {
810  vpMeterPixelConversion::convertPoint(cam, o.p[0], o.p[1], ipo);
811 
812  vpMeterPixelConversion::convertPoint(cam, x.p[0], x.p[1], ip1);
813  drawArrow(I, ipo + offset, ip1 + offset, vpColor::red, 4 * thickness, 2 * thickness, thickness);
814 
815  vpMeterPixelConversion::convertPoint(cam, y.p[0], y.p[1], ip1);
816  drawArrow(I, ipo + offset, ip1 + offset, vpColor::green, 4 * thickness, 2 * thickness, thickness);
817 
818  vpMeterPixelConversion::convertPoint(cam, z.p[0], z.p[1], ip1);
819  drawArrow(I, ipo + offset, ip1 + offset, vpColor::blue, 4 * thickness, 2 * thickness, thickness);
820  } else {
821  vpMeterPixelConversion::convertPoint(cam, o.p[0], o.p[1], ipo);
822 
823  vpMeterPixelConversion::convertPoint(cam, x.p[0], x.p[1], ip1);
824  drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
825 
826  vpMeterPixelConversion::convertPoint(cam, y.p[0], y.p[1], ip1);
827  drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
828 
829  vpMeterPixelConversion::convertPoint(cam, z.p[0], z.p[1], ip1);
830  drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
831  }
832 }
833 
842  unsigned char color, unsigned int thickness)
843 {
844  DrawLine(I, static_cast<int>(ip1.get_u()), static_cast<int>(ip1.get_v()),
845  static_cast<int>(ip2.get_u()), static_cast<int>(ip2.get_v()), color,
846  thickness);
847 }
848 
856 void vpImageDraw::drawLine(vpImage<vpRGBa> &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness)
857 {
858  DrawLine(I, static_cast<int>(ip1.get_u()), static_cast<int>(ip1.get_v()),
859  static_cast<int>(ip2.get_u()), static_cast<int>(ip2.get_v()), vpRGBa(color.R, color.G, color.B),
860  thickness);
861 }
862 
870 void vpImageDraw::drawPoint(vpImage<unsigned char> &I, const vpImagePoint &ip, unsigned char color, unsigned int thickness)
871 {
872  drawRectangle(I, vpRect(ip, thickness, thickness), color, true);
873 }
874 
882 void vpImageDraw::drawPoint(vpImage<vpRGBa> &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
883 {
884  drawRectangle(I, vpRect(ip, thickness, thickness), color, true);
885 }
886 
895 void vpImageDraw::drawPolygon(vpImage<unsigned char> &I, const std::vector<vpImagePoint> &vip,
896  unsigned char color, unsigned int thickness, bool closed)
897 {
898  DrawPolygon(I, vip, color, thickness, closed);
899 }
900 
909 void vpImageDraw::drawPolygon(vpImage<vpRGBa> &I, const std::vector<vpImagePoint> &vip,
910  const vpColor &color, unsigned int thickness, bool closed)
911 {
912  DrawPolygon(I, vip, vpRGBa(color.R, color.G, color.B), thickness, closed);
913 }
914 
927 void vpImageDraw::drawRectangle(vpImage<unsigned char> &I, const vpRect &rectangle, unsigned char color, bool fill, unsigned int thickness)
928 {
929  if (fill) {
930  DrawFilledRectangle(I, rectangle, color);
931  } else {
932  DrawRectangle(I, rectangle, color, thickness);
933  }
934 }
935 
948 void vpImageDraw::drawRectangle(vpImage<vpRGBa> &I, const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
949 {
950  if (fill) {
951  DrawFilledRectangle(I, rectangle, vpRGBa(color.R, color.G, color.B));
952  } else {
953  DrawRectangle(I, rectangle, vpRGBa(color.R, color.G, color.B), thickness);
954  }
955 }
double get_i() const
Definition: vpImagePoint.h:204
double getTop() const
Definition: vpRect.h:192
static void drawEllipse(vpImage< unsigned char > &I, const vpImagePoint &center, double coef1, double coef2, double coef3, bool use_centered_moments, unsigned char color, double theta1=0, double theta2=360, unsigned int thickness=1)
static void drawRectangle(vpImage< unsigned char > &I, const vpRect &rectangle, unsigned char color, bool fill=false, unsigned int thickness=1)
Implementation of an homogeneous matrix and operations on such kind of matrices.
unsigned char B
Blue component.
Definition: vpRGBa.h:150
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
static void drawCircle(vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, unsigned char color, unsigned int thickness=1)
static void drawFrame(vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, unsigned char color, unsigned int thickness=1, const vpImagePoint &offset=vpImagePoint(0, 0))
Class to define colors available for display functionnalities.
Definition: vpColor.h:119
static void drawArrow(vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, unsigned char color, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
static const vpColor none
Definition: vpColor.h:191
void track(const vpHomogeneousMatrix &cMo)
static void drawDottedLine(vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, unsigned char color, unsigned int thickness=1)
unsigned char G
Green component.
Definition: vpRGBa.h:149
static const vpColor green
Definition: vpColor.h:182
double getRight() const
Definition: vpRect.h:179
Definition: vpRGBa.h:66
static const vpColor red
Definition: vpColor.h:179
Class that defines what is a point.
Definition: vpPoint.h:58
double get_u() const
Definition: vpImagePoint.h:263
void set_i(double ii)
Definition: vpImagePoint.h:167
static double sqr(double x)
Definition: vpMath.h:114
static void drawPoint(vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned char color, unsigned int thickness=1)
double get_j() const
Definition: vpImagePoint.h:215
Generic class defining intrinsic camera parameters.
double getLeft() const
Definition: vpRect.h:173
static double rad(double deg)
Definition: vpMath.h:108
void set_j(double jj)
Definition: vpImagePoint.h:178
unsigned int getHeight() const
Definition: vpImage.h:186
static void drawCross(vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, unsigned char color, unsigned int thickness=1)
unsigned char R
Red component.
Definition: vpRGBa.h:148
static void drawPolygon(vpImage< unsigned char > &I, const std::vector< vpImagePoint > &vip, unsigned char color, unsigned int thickness=1, bool closed=true)
Defines a rectangle in the plane.
Definition: vpRect.h:78
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
unsigned int getWidth() const
Definition: vpImage.h:244
double getBottom() const
Definition: vpRect.h:97
static void drawLine(vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, unsigned char color, unsigned int thickness=1)
Definition of the vpImage class member functions.
Definition: vpImage.h:124
vpColVector p
Definition: vpTracker.h:71
double get_v() const
Definition: vpImagePoint.h:274
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
Definition: vpImagePoint.h:285
static const vpColor blue
Definition: vpColor.h:185