Visual Servoing Platform version 3.5.0
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
64namespace
65{
66template<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
171template<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
187template<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
198template<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
216template<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
355void 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
379void 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
445void 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
517 double coef2, double coef3, bool use_normalized_centered_moments, unsigned char color,
518 double smallalpha, double highalpha, unsigned int thickness)
519{
520 double a = 0., b = 0., e = 0.;
521
522 if (use_normalized_centered_moments) {
523 // Chaumette, Image Moments: A General and Useful Set of Features for Visual Servoing, TRO 2004, eq 24
524 // Similar code as in function vpMeEllipse::computeAbeFromNij() in vpMeEllipse.cpp
525 double n20_p = coef1;
526 double n11_p = coef2;
527 double n02_p = coef3;
528 double num = n20_p - n02_p;
529 double d = num * num + 4.0 * n11_p * n11_p; // always >= 0
530
531 if (d <= std::numeric_limits<double>::epsilon()) { // circle
532 e = 0.0; // case n20 = n02 and n11 = 0 : circle, e undefined
533 a = b = 2.0*sqrt(n20_p);
534 }
535 else { // real ellipse
536 e = atan2(2.0*n11_p, num)/2.0; // e in [-Pi/2 ; Pi/2]
537 d = sqrt(d); // d in sqrt always >= 0
538 num = n20_p + n02_p;
539 a = sqrt(2.0*(num + d)); // term in sqrt always > 0
540 b = sqrt(2.0*(num - d)); // term in sqrt always > 0
541 }
542 } else {
543 a = coef1;
544 b = coef2;
545 e = coef3;
546 }
547
548 // For all what follows similar code as in function vpMeEllipse::display() in vpMeEllipse.cpp
549
550 // Approximation of the circumference of an ellipse:
551 // [Ramanujan, S., "Modular Equations and Approximations to ,"
552 // Quart. J. Pure. Appl. Math., vol. 45 (1913-1914), pp. 350-372]
553 double angle = highalpha - smallalpha;
554
555 double t = (a - b) / (a + b);
556 t *= t; // t^2
557 double circumference = (angle/2.0) * (a + b) * (1.0 + 3.0 * t / (10.0 + sqrt(4.0 - 3.0 * t)));
558 unsigned int nbpoints = (unsigned int)(floor(circumference / 20));
559 if (nbpoints < 10) {
560 nbpoints = 10;
561 }
562 double incr = angle / nbpoints; // angle increment
563
564 double u0 = center.get_u();
565 double v0 = center.get_v();
566 double cose = cos(e);
567 double sine = sin(e);
568
569 double u = a * cos(smallalpha); // equation of an ellipse
570 double v = b * sin(smallalpha); // equation of an ellipse
571 angle = smallalpha;
572 // (i1,j1) are the coordinates on the origin centered ellipse ;
573 // a rotation by "e" and a translation by (xci,jc) are done
574 // to get the coordinates of the point on the shifted ellipse
575 vpImagePoint iP11;
576 iP11.set_uv(u0 + cose * u - sine * v, v0 + sine * u + cose * v);
577
578 // display the arc of the ellipse by successive small segments
579 for (unsigned int i = 0; i < nbpoints; i++) {
580 angle += incr;
581 // Two concentric circles method used
582 u = a * cos(angle);
583 v = b * sin(angle);
584 // to get the coordinates of the point on the shifted ellipse
585 vpImagePoint iP22;
586 iP22.set_uv(u0 + cose * u - sine * v, v0 + sine * u + cose * v);
587
588 drawLine(I, iP11, iP22, color, thickness);
589
590 iP11 = iP22;
591 }
592}
593
630void vpImageDraw::drawEllipse(vpImage<vpRGBa> &I, const vpImagePoint &center, double coef1,
631 double coef2, double coef3, bool use_normalized_centered_moments, const vpColor &color,
632 double smallalpha, double highalpha, unsigned int thickness)
633{
634 double a = 0., b = 0., e = 0.;
635
636 if (use_normalized_centered_moments) {
637 // Chaumette, Image Moments: A General and Useful Set of Features for Visual Servoing, TRO 2004, eq 24
638 // Similar code as in function vpMeEllipse::computeAbeFromNij() in vpMeEllipse.cpp
639 double n20_p = coef1;
640 double n11_p = coef2;
641 double n02_p = coef3;
642 double num = n20_p - n02_p;
643 double d = num * num + 4.0 * n11_p * n11_p; // always >= 0
644
645 if (d <= std::numeric_limits<double>::epsilon()) { // circle
646 e = 0.0; // case n20 = n02 and n11 = 0 : circle, e undefined
647 a = b = 2.0*sqrt(n20_p);
648 }
649 else { // real ellipse
650 e = atan2(2.0*n11_p, num)/2.0; // e in [-Pi/2 ; Pi/2]
651 d = sqrt(d); // d in sqrt always >= 0
652 num = n20_p + n02_p;
653 a = sqrt(2.0*(num + d)); // term in sqrt always > 0
654 b = sqrt(2.0*(num - d)); // term in sqrt always > 0
655 }
656 } else {
657 a = coef1;
658 b = coef2;
659 e = coef3;
660 }
661
662 // For all what follows similar code as in function vpMeEllipse::display() in vpMeEllipse.cpp
663
664 // Approximation of the circumference of an ellipse:
665 // [Ramanujan, S., "Modular Equations and Approximations to ,"
666 // Quart. J. Pure. Appl. Math., vol. 45 (1913-1914), pp. 350-372]
667 double angle = highalpha - smallalpha;
668
669 double t = (a - b) / (a + b);
670 t *= t; // t^2
671 double circumference = (angle/2.0) * (a + b) * (1.0 + 3.0 * t / (10.0 + sqrt(4.0 - 3.0 * t)));
672 unsigned int nbpoints = (unsigned int)(floor(circumference / 20));
673 if (nbpoints < 10) {
674 nbpoints = 10;
675 }
676 double incr = angle / nbpoints; // angle increment
677
678 double u0 = center.get_u();
679 double v0 = center.get_v();
680 double cose = cos(e);
681 double sine = sin(e);
682
683 double u = a * cos(smallalpha); // equation of an ellipse
684 double v = b * sin(smallalpha); // equation of an ellipse
685 angle = smallalpha;
686 // (i1,j1) are the coordinates on the origin centered ellipse ;
687 // a rotation by "e" and a translation by (xci,jc) are done
688 // to get the coordinates of the point on the shifted ellipse
689 vpImagePoint iP11;
690 iP11.set_uv(u0 + cose * u - sine * v, v0 + sine * u + cose * v);
691
692 // display the arc of the ellipse by successive small segments
693 for (unsigned int i = 0; i < nbpoints; i++) {
694 angle += incr;
695 // Two concentric circles method used
696 u = a * cos(angle);
697 v = b * sin(angle);
698 // to get the coordinates of the point on the shifted ellipse
699 vpImagePoint iP22;
700 iP22.set_uv(u0 + cose * u - sine * v, v0 + sine * u + cose * v);
701
702 drawLine(I, iP11, iP22, color, thickness);
703
704 iP11 = iP22;
705 }
706}
707
724 double size, unsigned char color, unsigned int thickness, const vpImagePoint &offset)
725{
726 vpPoint o(0.0, 0.0, 0.0);
727 vpPoint x(size, 0.0, 0.0);
728 vpPoint y(0.0, size, 0.0);
729 vpPoint z(0.0, 0.0, size);
730
731 o.track(cMo);
732 x.track(cMo);
733 y.track(cMo);
734 z.track(cMo);
735
736 vpImagePoint ipo, ip1;
737
738 vpMeterPixelConversion::convertPoint(cam, o.p[0], o.p[1], ipo);
739
740 vpMeterPixelConversion::convertPoint(cam, x.p[0], x.p[1], ip1);
741 drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
742
743 vpMeterPixelConversion::convertPoint(cam, y.p[0], y.p[1], ip1);
744 drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
745
746 vpMeterPixelConversion::convertPoint(cam, z.p[0], z.p[1], ip1);
747 drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
748}
749
766 double size, const vpColor &color, unsigned int thickness, const vpImagePoint &offset)
767{
768 vpPoint o(0.0, 0.0, 0.0);
769 vpPoint x(size, 0.0, 0.0);
770 vpPoint y(0.0, size, 0.0);
771 vpPoint z(0.0, 0.0, size);
772
773 o.track(cMo);
774 x.track(cMo);
775 y.track(cMo);
776 z.track(cMo);
777
778 vpImagePoint ipo, ip1;
779
780 if (color == vpColor::none) {
781 vpMeterPixelConversion::convertPoint(cam, o.p[0], o.p[1], ipo);
782
783 vpMeterPixelConversion::convertPoint(cam, x.p[0], x.p[1], ip1);
784 drawArrow(I, ipo + offset, ip1 + offset, vpColor::red, 4 * thickness, 2 * thickness, thickness);
785
786 vpMeterPixelConversion::convertPoint(cam, y.p[0], y.p[1], ip1);
787 drawArrow(I, ipo + offset, ip1 + offset, vpColor::green, 4 * thickness, 2 * thickness, thickness);
788
789 vpMeterPixelConversion::convertPoint(cam, z.p[0], z.p[1], ip1);
790 drawArrow(I, ipo + offset, ip1 + offset, vpColor::blue, 4 * thickness, 2 * thickness, thickness);
791 } else {
792 vpMeterPixelConversion::convertPoint(cam, o.p[0], o.p[1], ipo);
793
794 vpMeterPixelConversion::convertPoint(cam, x.p[0], x.p[1], ip1);
795 drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
796
797 vpMeterPixelConversion::convertPoint(cam, y.p[0], y.p[1], ip1);
798 drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
799
800 vpMeterPixelConversion::convertPoint(cam, z.p[0], z.p[1], ip1);
801 drawArrow(I, ipo + offset, ip1 + offset, color, 4 * thickness, 2 * thickness, thickness);
802 }
803}
804
813 unsigned char color, unsigned int thickness)
814{
815 DrawLine(I, static_cast<int>(ip1.get_u()), static_cast<int>(ip1.get_v()),
816 static_cast<int>(ip2.get_u()), static_cast<int>(ip2.get_v()), color,
817 thickness);
818}
819
827void vpImageDraw::drawLine(vpImage<vpRGBa> &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness)
828{
829 DrawLine(I, static_cast<int>(ip1.get_u()), static_cast<int>(ip1.get_v()),
830 static_cast<int>(ip2.get_u()), static_cast<int>(ip2.get_v()), vpRGBa(color.R, color.G, color.B),
831 thickness);
832}
833
841void vpImageDraw::drawPoint(vpImage<unsigned char> &I, const vpImagePoint &ip, unsigned char color, unsigned int thickness)
842{
843 drawRectangle(I, vpRect(ip, thickness, thickness), color, true);
844}
845
853void vpImageDraw::drawPoint(vpImage<vpRGBa> &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
854{
855 drawRectangle(I, vpRect(ip, thickness, thickness), color, true);
856}
857
866void vpImageDraw::drawPolygon(vpImage<unsigned char> &I, const std::vector<vpImagePoint> &vip,
867 unsigned char color, unsigned int thickness, bool closed)
868{
869 DrawPolygon(I, vip, color, thickness, closed);
870}
871
880void vpImageDraw::drawPolygon(vpImage<vpRGBa> &I, const std::vector<vpImagePoint> &vip,
881 const vpColor &color, unsigned int thickness, bool closed)
882{
883 DrawPolygon(I, vip, vpRGBa(color.R, color.G, color.B), thickness, closed);
884}
885
898void vpImageDraw::drawRectangle(vpImage<unsigned char> &I, const vpRect &rectangle, unsigned char color, bool fill, unsigned int thickness)
899{
900 if (fill) {
901 DrawFilledRectangle(I, rectangle, color);
902 } else {
903 DrawRectangle(I, rectangle, color, thickness);
904 }
905}
906
919void vpImageDraw::drawRectangle(vpImage<vpRGBa> &I, const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
920{
921 if (fill) {
922 DrawFilledRectangle(I, rectangle, vpRGBa(color.R, color.G, color.B));
923 } else {
924 DrawRectangle(I, rectangle, vpRGBa(color.R, color.G, color.B), thickness);
925 }
926}
Generic class defining intrinsic camera parameters.
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:158
static const vpColor red
Definition: vpColor.h:217
static const vpColor none
Definition: vpColor.h:229
static const vpColor blue
Definition: vpColor.h:223
static const vpColor green
Definition: vpColor.h:220
void track(const vpHomogeneousMatrix &cMo)
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void drawEllipse(vpImage< unsigned char > &I, const vpImagePoint &center, double coef1, double coef2, double coef3, bool use_normalized_centered_moments, unsigned char color, double smallalpha=0, double highalpha=2 *M_PI, unsigned int thickness=1)
static void drawRectangle(vpImage< unsigned char > &I, const vpRect &rectangle, unsigned char color, bool fill=false, unsigned int thickness=1)
static void drawCircle(vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, unsigned char color, unsigned int thickness=1)
static void drawLine(vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, unsigned char color, unsigned int thickness=1)
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 void drawPoint(vpImage< unsigned char > &I, const vpImagePoint &ip, 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))
static void drawPolygon(vpImage< unsigned char > &I, const std::vector< vpImagePoint > &vip, unsigned char color, unsigned int thickness=1, bool closed=true)
static void drawCross(vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, unsigned char color, unsigned int thickness=1)
static void drawDottedLine(vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, unsigned char color, unsigned int thickness=1)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void set_j(double jj)
Definition: vpImagePoint.h:177
double get_j() const
Definition: vpImagePoint.h:214
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_i(double ii)
Definition: vpImagePoint.h:166
double get_u() const
Definition: vpImagePoint.h:262
void set_uv(double u, double v)
Definition: vpImagePoint.h:247
double get_i() const
Definition: vpImagePoint.h:203
double get_v() const
Definition: vpImagePoint.h:273
Definition of the vpImage class member functions.
Definition: vpImage.h:139
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
static double sqr(double x)
Definition: vpMath.h:116
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:82
Definition: vpRGBa.h:67
unsigned char B
Blue component.
Definition: vpRGBa.h:150
unsigned char R
Red component.
Definition: vpRGBa.h:148
unsigned char G
Green component.
Definition: vpRGBa.h:149
Defines a rectangle in the plane.
Definition: vpRect.h:80
double getLeft() const
Definition: vpRect.h:174
double getRight() const
Definition: vpRect.h:180
double getBottom() const
Definition: vpRect.h:98
double getTop() const
Definition: vpRect.h:193
vpColVector p
Definition: vpTracker.h:73