Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpImageSimulator.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description: Class which enables to project an image in the 3D space
31 * and get the view of a virtual camera.
32 */
33
34#include <visp3/core/vpImageConvert.h>
35#include <visp3/core/vpMatrixException.h>
36#include <visp3/core/vpMeterPixelConversion.h>
37#include <visp3/core/vpPixelMeterConversion.h>
38#include <visp3/core/vpPolygon3D.h>
39#include <visp3/core/vpRotationMatrix.h>
40#include <visp3/robot/vpImageSimulator.h>
41
42#ifdef VISP_HAVE_MODULE_IO
43#include <visp3/io/vpImageIo.h>
44#endif
45
58 : cMt(), pt(), ptClipped(), interp(SIMPLE), normal_obj(), normal_Cam(), normal_Cam_optim(), distance(1.),
59 visible_result(1.), visible(false), X0_2_optim(nullptr), frobeniusNorm_u(0.), fronbniusNorm_v(0.), vbase_u(),
60 vbase_v(), vbase_u_optim(nullptr), vbase_v_optim(nullptr), Xinter_optim(nullptr), listTriangle(), colorI(col), Ig(), Ic(),
61 rect(), cleanPrevImage(false), setBackgroundTexture(false), bgColor(vpColor::white), focal(), needClipping(false)
62{
63 for (int i = 0; i < 4; i++)
64 X[i].resize(3);
65
66 for (int i = 0; i < 4; i++)
67 X2[i].resize(3);
68
69 normal_obj.resize(3);
70 visible = false;
71 normal_Cam.resize(3);
72
73 // Xinter.resize(3);
74
75 vbase_u.resize(3);
76 vbase_v.resize(3);
77
78 focal.resize(3);
79 focal = 0;
80 focal[2] = 1;
81
82 normal_Cam_optim = new double[3];
83 X0_2_optim = new double[3];
84 vbase_u_optim = new double[3];
85 vbase_v_optim = new double[3];
86 Xinter_optim = new double[3];
87
88 pt.resize(4);
89}
90
95 : cMt(), pt(), ptClipped(), interp(SIMPLE), normal_obj(), normal_Cam(), normal_Cam_optim(), distance(1.),
96 visible_result(1.), visible(false), X0_2_optim(nullptr), frobeniusNorm_u(0.), fronbniusNorm_v(0.), vbase_u(),
97 vbase_v(), vbase_u_optim(nullptr), vbase_v_optim(nullptr), Xinter_optim(nullptr), listTriangle(), colorI(GRAY_SCALED), Ig(),
98 Ic(), rect(), cleanPrevImage(false), setBackgroundTexture(false), bgColor(vpColor::white), focal(),
99 needClipping(false)
100{
101 pt.resize(4);
102 for (unsigned int i = 0; i < 4; i++) {
103 X[i] = text.X[i];
104 pt[i] = text.pt[i];
105 }
106
107 for (int i = 0; i < 4; i++)
108 X2[i].resize(3);
109
110 Ic = text.Ic;
111 Ig = text.Ig;
112
113 focal.resize(3);
114 focal = 0;
115 focal[2] = 1;
116
117 normal_obj = text.normal_obj;
118 frobeniusNorm_u = text.frobeniusNorm_u;
119 fronbniusNorm_v = text.fronbniusNorm_v;
120
121 normal_Cam.resize(3);
122 vbase_u.resize(3);
123 vbase_v.resize(3);
124
125 normal_Cam_optim = new double[3];
126 X0_2_optim = new double[3];
127 vbase_u_optim = new double[3];
128 vbase_v_optim = new double[3];
129 Xinter_optim = new double[3];
130
131 colorI = text.colorI;
132 interp = text.interp;
133 bgColor = text.bgColor;
134 cleanPrevImage = text.cleanPrevImage;
135 setBackgroundTexture = false;
136
137 setCameraPosition(text.cMt);
138}
139
144{
145 delete[] normal_Cam_optim;
146 delete[] X0_2_optim;
147 delete[] vbase_u_optim;
148 delete[] vbase_v_optim;
149 delete[] Xinter_optim;
150}
151
153{
154 for (unsigned int i = 0; i < 4; i++) {
155 X[i] = sim.X[i];
156 pt[i] = sim.pt[i];
157 }
158
159 Ic = sim.Ic;
160 Ig = sim.Ig;
161
162 bgColor = sim.bgColor;
163 cleanPrevImage = sim.cleanPrevImage;
164
165 focal = sim.focal;
166
167 normal_obj = sim.normal_obj;
168 frobeniusNorm_u = sim.frobeniusNorm_u;
169 fronbniusNorm_v = sim.fronbniusNorm_v;
170
171 colorI = sim.colorI;
172 interp = sim.interp;
173
174 setCameraPosition(sim.cMt);
175
176 return *this;
177}
178
185{
186 if (setBackgroundTexture)
187 // The Ig has been set to a previously defined background texture
188 I = Ig;
189 else {
190 if (cleanPrevImage) {
191 unsigned char col = static_cast<unsigned char>(0.2126 * bgColor.R + 0.7152 * bgColor.G + 0.0722 * bgColor.B);
192 for (unsigned int i = 0; i < I.getHeight(); i++) {
193 for (unsigned int j = 0; j < I.getWidth(); j++) {
194 I[i][j] = col;
195 }
196 }
197 }
198 }
199
200 if (visible) {
201 if (!needClipping)
202 getRoi(I.getWidth(), I.getHeight(), cam, pt, rect);
203 else
204 getRoi(I.getWidth(), I.getHeight(), cam, ptClipped, rect);
205
206 double top = rect.getTop();
207 double bottom = rect.getBottom();
208 double left = rect.getLeft();
209 double right = rect.getRight();
210
211 unsigned char *bitmap = I.bitmap;
212 unsigned int width = I.getWidth();
213 vpImagePoint ip;
214
215 for (unsigned int i = static_cast<unsigned int>(top); i < static_cast<unsigned int>(bottom); i++) {
216 for (unsigned int j = static_cast<unsigned int>(left); j < static_cast<unsigned int>(right); j++) {
217 double x = 0, y = 0;
218 ip.set_ij(i, j);
220 ip.set_ij(y, x);
221 if (colorI == GRAY_SCALED) {
222 unsigned char Ipixelplan = 0;
223 if (getPixel(ip, Ipixelplan)) {
224 *(bitmap + i * width + j) = Ipixelplan;
225 }
226 }
227 else if (colorI == COLORED) {
228 vpRGBa Ipixelplan;
229 if (getPixel(ip, Ipixelplan)) {
230 unsigned char pixelgrey =
231 static_cast<unsigned char>(0.2126 * Ipixelplan.R + 0.7152 * Ipixelplan.G + 0.0722 * Ipixelplan.B);
232 *(bitmap + i * width + j) = pixelgrey;
233 }
234 }
235 }
236 }
237 }
238}
239
250{
251 if (cleanPrevImage) {
252 unsigned char col = static_cast<unsigned char>(0.2126 * bgColor.R + 0.7152 * bgColor.G + 0.0722 * bgColor.B);
253 for (unsigned int i = 0; i < I.getHeight(); i++) {
254 for (unsigned int j = 0; j < I.getWidth(); j++) {
255 I[i][j] = col;
256 }
257 }
258 }
259 if (visible) {
260 if (!needClipping)
261 getRoi(I.getWidth(), I.getHeight(), cam, pt, rect);
262 else
263 getRoi(I.getWidth(), I.getHeight(), cam, ptClipped, rect);
264
265 double top = rect.getTop();
266 double bottom = rect.getBottom();
267 double left = rect.getLeft();
268 double right = rect.getRight();
269
270 unsigned char *bitmap = I.bitmap;
271 unsigned int width = I.getWidth();
272 vpImagePoint ip;
273
274 for (unsigned int i = static_cast<unsigned int>(top); i < static_cast<unsigned int>(bottom); i++) {
275 for (unsigned int j = static_cast<unsigned int>(left); j < static_cast<unsigned int>(right); j++) {
276 double x = 0, y = 0;
277 ip.set_ij(i, j);
279 ip.set_ij(y, x);
280 unsigned char Ipixelplan = 0;
281 if (getPixel(Isrc, ip, Ipixelplan)) {
282 *(bitmap + i * width + j) = Ipixelplan;
283 }
284 }
285 }
286 }
287}
288
305{
306 if (I.getWidth() != static_cast<unsigned int>(zBuffer.getCols()) || I.getHeight() != static_cast<unsigned int>(zBuffer.getRows()))
308 " zBuffer must have the same size as the image I ! "));
309
310 if (cleanPrevImage) {
311 unsigned char col = static_cast<unsigned char>(0.2126 * bgColor.R + 0.7152 * bgColor.G + 0.0722 * bgColor.B);
312 for (unsigned int i = 0; i < I.getHeight(); i++) {
313 for (unsigned int j = 0; j < I.getWidth(); j++) {
314 I[i][j] = col;
315 }
316 }
317 }
318 if (visible) {
319 if (!needClipping)
320 getRoi(I.getWidth(), I.getHeight(), cam, pt, rect);
321 else
322 getRoi(I.getWidth(), I.getHeight(), cam, ptClipped, rect);
323
324 double top = rect.getTop();
325 double bottom = rect.getBottom();
326 double left = rect.getLeft();
327 double right = rect.getRight();
328
329 unsigned char *bitmap = I.bitmap;
330 unsigned int width = I.getWidth();
331 vpImagePoint ip;
332
333 for (unsigned int i = static_cast<unsigned int>(top); i < static_cast<unsigned int>(bottom); i++) {
334 for (unsigned int j = static_cast<unsigned int>(left); j < static_cast<unsigned int>(right); j++) {
335 double x = 0, y = 0;
336 ip.set_ij(i, j);
338 ip.set_ij(y, x);
339 if (colorI == GRAY_SCALED) {
340 unsigned char Ipixelplan;
341 if (getPixel(ip, Ipixelplan)) {
342 if (Xinter_optim[2] < zBuffer[i][j] || zBuffer[i][j] < 0) {
343 *(bitmap + i * width + j) = Ipixelplan;
344 zBuffer[i][j] = Xinter_optim[2];
345 }
346 }
347 }
348 else if (colorI == COLORED) {
349 vpRGBa Ipixelplan;
350 if (getPixel(ip, Ipixelplan)) {
351 if (Xinter_optim[2] < zBuffer[i][j] || zBuffer[i][j] < 0) {
352 unsigned char pixelgrey =
353 static_cast<unsigned char>(0.2126 * Ipixelplan.R + 0.7152 * Ipixelplan.G + 0.0722 * Ipixelplan.B);
354 *(bitmap + i * width + j) = pixelgrey;
355 zBuffer[i][j] = Xinter_optim[2];
356 }
357 }
358 }
359 }
360 }
361 }
362}
363
372{
373 if (cleanPrevImage) {
374 for (unsigned int i = 0; i < I.getHeight(); i++) {
375 for (unsigned int j = 0; j < I.getWidth(); j++) {
376 I[i][j] = bgColor;
377 }
378 }
379 }
380
381 if (visible) {
382 if (!needClipping)
383 getRoi(I.getWidth(), I.getHeight(), cam, pt, rect);
384 else
385 getRoi(I.getWidth(), I.getHeight(), cam, ptClipped, rect);
386
387 double top = rect.getTop();
388 double bottom = rect.getBottom();
389 double left = rect.getLeft();
390 double right = rect.getRight();
391
392 vpRGBa *bitmap = I.bitmap;
393 unsigned int width = I.getWidth();
394 vpImagePoint ip;
395
396 for (unsigned int i = static_cast<unsigned int>(top); i < static_cast<unsigned int>(bottom); i++) {
397 for (unsigned int j = static_cast<unsigned int>(left); j < static_cast<unsigned int>(right); j++) {
398 double x = 0, y = 0;
399 ip.set_ij(i, j);
401 ip.set_ij(y, x);
402 if (colorI == GRAY_SCALED) {
403 unsigned char Ipixelplan;
404 if (getPixel(ip, Ipixelplan)) {
405 vpRGBa pixelcolor;
406 pixelcolor.R = Ipixelplan;
407 pixelcolor.G = Ipixelplan;
408 pixelcolor.B = Ipixelplan;
409 *(bitmap + i * width + j) = pixelcolor;
410 }
411 }
412 else if (colorI == COLORED) {
413 vpRGBa Ipixelplan;
414 if (getPixel(ip, Ipixelplan)) {
415 *(bitmap + i * width + j) = Ipixelplan;
416 }
417 }
418 }
419 }
420 }
421}
422
433{
434 if (cleanPrevImage) {
435 for (unsigned int i = 0; i < I.getHeight(); i++) {
436 for (unsigned int j = 0; j < I.getWidth(); j++) {
437 I[i][j] = bgColor;
438 }
439 }
440 }
441
442 if (visible) {
443 if (!needClipping)
444 getRoi(I.getWidth(), I.getHeight(), cam, pt, rect);
445 else
446 getRoi(I.getWidth(), I.getHeight(), cam, ptClipped, rect);
447
448 double top = rect.getTop();
449 double bottom = rect.getBottom();
450 double left = rect.getLeft();
451 double right = rect.getRight();
452
453 vpRGBa *bitmap = I.bitmap;
454 unsigned int width = I.getWidth();
455 vpImagePoint ip;
456
457 for (unsigned int i = static_cast<unsigned int>(top); i < static_cast<unsigned int>(bottom); i++) {
458 for (unsigned int j = static_cast<unsigned int>(left); j < static_cast<unsigned int>(right); j++) {
459 double x = 0, y = 0;
460 ip.set_ij(i, j);
462 ip.set_ij(y, x);
463 vpRGBa Ipixelplan;
464 if (getPixel(Isrc, ip, Ipixelplan)) {
465 *(bitmap + i * width + j) = Ipixelplan;
466 }
467 }
468 }
469 }
470}
471
488{
489 if (I.getWidth() != static_cast<unsigned int>(zBuffer.getCols()) || I.getHeight() != static_cast<unsigned int>(zBuffer.getRows()))
491 " zBuffer must have the same size as the image I ! "));
492
493 if (cleanPrevImage) {
494 for (unsigned int i = 0; i < I.getHeight(); i++) {
495 for (unsigned int j = 0; j < I.getWidth(); j++) {
496 I[i][j] = bgColor;
497 }
498 }
499 }
500 if (visible) {
501 if (!needClipping)
502 getRoi(I.getWidth(), I.getHeight(), cam, pt, rect);
503 else
504 getRoi(I.getWidth(), I.getHeight(), cam, ptClipped, rect);
505
506 double top = rect.getTop();
507 double bottom = rect.getBottom();
508 double left = rect.getLeft();
509 double right = rect.getRight();
510
511 vpRGBa *bitmap = I.bitmap;
512 unsigned int width = I.getWidth();
513 vpImagePoint ip;
514
515 for (unsigned int i = static_cast<unsigned int>(top); i < static_cast<unsigned int>(bottom); i++) {
516 for (unsigned int j = static_cast<unsigned int>(left); j < static_cast<unsigned int>(right); j++) {
517 double x = 0, y = 0;
518 ip.set_ij(i, j);
520 ip.set_ij(y, x);
521 if (colorI == GRAY_SCALED) {
522 unsigned char Ipixelplan;
523 if (getPixel(ip, Ipixelplan)) {
524 if (Xinter_optim[2] < zBuffer[i][j] || zBuffer[i][j] < 0) {
525 vpRGBa pixelcolor;
526 pixelcolor.R = Ipixelplan;
527 pixelcolor.G = Ipixelplan;
528 pixelcolor.B = Ipixelplan;
529 *(bitmap + i * width + j) = pixelcolor;
530 zBuffer[i][j] = Xinter_optim[2];
531 }
532 }
533 }
534 else if (colorI == COLORED) {
535 vpRGBa Ipixelplan;
536 if (getPixel(ip, Ipixelplan)) {
537 if (Xinter_optim[2] < zBuffer[i][j] || zBuffer[i][j] < 0) {
538 *(bitmap + i * width + j) = Ipixelplan;
539 zBuffer[i][j] = Xinter_optim[2];
540 }
541 }
542 }
543 }
544 }
545 }
546}
547
655void vpImageSimulator::getImage(vpImage<unsigned char> &I, std::list<vpImageSimulator> &list,
656 const vpCameraParameters &cam)
657{
658
659 unsigned int width = I.getWidth();
660 unsigned int height = I.getHeight();
661
662 unsigned int nbsimList = static_cast<unsigned int>(list.size());
663
664 if (nbsimList < 1)
665 return;
666
667 vpImageSimulator **simList = new vpImageSimulator *[nbsimList];
668
669 double topFinal = height + 1;
670 double bottomFinal = -1;
671 double leftFinal = width + 1;
672 double rightFinal = -1;
673
674 unsigned int unvisible = 0;
675 unsigned int indexSimu = 0;
676 for (std::list<vpImageSimulator>::iterator it = list.begin(); it != list.end(); ++it, ++indexSimu) {
677 vpImageSimulator *sim = &(*it);
678 if (sim->visible)
679 simList[indexSimu] = sim;
680 else
681 unvisible++;
682 }
683 nbsimList = nbsimList - unvisible;
684
685 if (nbsimList < 1) {
686 delete[] simList;
687 return;
688 }
689
690 for (unsigned int i = 0; i < nbsimList; i++) {
691 if (!simList[i]->needClipping)
692 simList[i]->getRoi(width, height, cam, simList[i]->pt, simList[i]->rect);
693 else
694 simList[i]->getRoi(width, height, cam, simList[i]->ptClipped, simList[i]->rect);
695
696 if (topFinal > simList[i]->rect.getTop())
697 topFinal = simList[i]->rect.getTop();
698 if (bottomFinal < simList[i]->rect.getBottom())
699 bottomFinal = simList[i]->rect.getBottom();
700 if (leftFinal > simList[i]->rect.getLeft())
701 leftFinal = simList[i]->rect.getLeft();
702 if (rightFinal < simList[i]->rect.getRight())
703 rightFinal = simList[i]->rect.getRight();
704 }
705
706 double zmin = -1;
707 int indice = -1;
708 unsigned char *bitmap = I.bitmap;
709 vpImagePoint ip;
710
711 for (unsigned int i = static_cast<unsigned int>(topFinal); i < static_cast<unsigned int>(bottomFinal); i++) {
712 for (unsigned int j = static_cast<unsigned int>(leftFinal); j < static_cast<unsigned int>(rightFinal); j++) {
713 zmin = -1;
714 double x = 0, y = 0;
715 ip.set_ij(i, j);
717 ip.set_ij(y, x);
718 for (int k = 0; k < static_cast<int>(nbsimList); k++) {
719 double z = 0;
720 if (simList[k]->getPixelDepth(ip, z)) {
721 if (z < zmin || zmin < 0) {
722 zmin = z;
723 indice = k;
724 }
725 }
726 }
727 if (indice >= 0) {
728 if (simList[indice]->colorI == GRAY_SCALED) {
729 unsigned char Ipixelplan = 255;
730 simList[indice]->getPixel(ip, Ipixelplan);
731 *(bitmap + i * width + j) = Ipixelplan;
732 }
733 else if (simList[indice]->colorI == COLORED) {
734 vpRGBa Ipixelplan(255, 255, 255);
735 simList[indice]->getPixel(ip, Ipixelplan);
736 unsigned char pixelgrey =
737 static_cast<unsigned char>(0.2126 * Ipixelplan.R + 0.7152 * Ipixelplan.G + 0.0722 * Ipixelplan.B);
738 *(bitmap + i * width + j) = pixelgrey;
739 }
740 }
741 }
742 }
743
744 delete[] simList;
745}
746
856void vpImageSimulator::getImage(vpImage<vpRGBa> &I, std::list<vpImageSimulator> &list, const vpCameraParameters &cam)
857{
858
859 unsigned int width = I.getWidth();
860 unsigned int height = I.getHeight();
861
862 unsigned int nbsimList = static_cast<unsigned int>(list.size());
863
864 if (nbsimList < 1)
865 return;
866
867 vpImageSimulator **simList = new vpImageSimulator *[nbsimList];
868
869 double topFinal = height + 1;
870 double bottomFinal = -1;
871 double leftFinal = width + 1;
872 double rightFinal = -1;
873
874 unsigned int unvisible = 0;
875 unsigned int indexSimu = 0;
876 for (std::list<vpImageSimulator>::iterator it = list.begin(); it != list.end(); ++it, ++indexSimu) {
877 vpImageSimulator *sim = &(*it);
878 if (sim->visible)
879 simList[indexSimu] = sim;
880 else
881 unvisible++;
882 }
883
884 nbsimList = nbsimList - unvisible;
885
886 if (nbsimList < 1) {
887 delete[] simList;
888 return;
889 }
890
891 for (unsigned int i = 0; i < nbsimList; i++) {
892 if (!simList[i]->needClipping)
893 simList[i]->getRoi(width, height, cam, simList[i]->pt, simList[i]->rect);
894 else
895 simList[i]->getRoi(width, height, cam, simList[i]->ptClipped, simList[i]->rect);
896
897 if (topFinal > simList[i]->rect.getTop())
898 topFinal = simList[i]->rect.getTop();
899 if (bottomFinal < simList[i]->rect.getBottom())
900 bottomFinal = simList[i]->rect.getBottom();
901 if (leftFinal > simList[i]->rect.getLeft())
902 leftFinal = simList[i]->rect.getLeft();
903 if (rightFinal < simList[i]->rect.getRight())
904 rightFinal = simList[i]->rect.getRight();
905 }
906
907 double zmin = -1;
908 int indice = -1;
909 vpRGBa *bitmap = I.bitmap;
910 vpImagePoint ip;
911
912 for (unsigned int i = static_cast<unsigned int>(topFinal); i < static_cast<unsigned int>(bottomFinal); i++) {
913 for (unsigned int j = static_cast<unsigned int>(leftFinal); j < static_cast<unsigned int>(rightFinal); j++) {
914 zmin = -1;
915 double x = 0, y = 0;
916 ip.set_ij(i, j);
918 ip.set_ij(y, x);
919 for (int k = 0; k < static_cast<int>(nbsimList); k++) {
920 double z = 0;
921 if (simList[k]->getPixelDepth(ip, z)) {
922 if (z < zmin || zmin < 0) {
923 zmin = z;
924 indice = k;
925 }
926 }
927 }
928 if (indice >= 0) {
929 if (simList[indice]->colorI == GRAY_SCALED) {
930 unsigned char Ipixelplan = 255;
931 simList[indice]->getPixel(ip, Ipixelplan);
932 vpRGBa pixelcolor;
933 pixelcolor.R = Ipixelplan;
934 pixelcolor.G = Ipixelplan;
935 pixelcolor.B = Ipixelplan;
936 *(bitmap + i * width + j) = pixelcolor;
937 }
938 else if (simList[indice]->colorI == COLORED) {
939 vpRGBa Ipixelplan(255, 255, 255);
940 simList[indice]->getPixel(ip, Ipixelplan);
941 // unsigned char pixelgrey = 0.2126 * Ipixelplan.R + 0.7152 *
942 // Ipixelplan.G + 0.0722 * Ipixelplan.B;
943 *(bitmap + i * width + j) = Ipixelplan;
944 }
945 }
946 }
947 }
948
949 delete[] simList;
950}
951
958{
959 cMt = cMt_;
961 cMt.extract(R);
962 needClipping = false;
963
964 normal_Cam = R * normal_obj;
965
966 visible_result = vpColVector::dotProd(normal_Cam, focal);
967
968 for (unsigned int i = 0; i < 4; i++)
969 pt[i].track(cMt);
970
971 vpColVector e1(3);
972 vpColVector e2(3);
973 vpColVector facenormal(3);
974
975 e1[0] = pt[1].get_X() - pt[0].get_X();
976 e1[1] = pt[1].get_Y() - pt[0].get_Y();
977 e1[2] = pt[1].get_Z() - pt[0].get_Z();
978
979 e2[0] = pt[2].get_X() - pt[1].get_X();
980 e2[1] = pt[2].get_Y() - pt[1].get_Y();
981 e2[2] = pt[2].get_Z() - pt[1].get_Z();
982
983 facenormal = vpColVector::crossProd(e1, e2);
984
985 double angle = pt[0].get_X() * facenormal[0] + pt[0].get_Y() * facenormal[1] + pt[0].get_Z() * facenormal[2];
986
987 if (angle > 0) {
988 visible = true;
989 }
990 else {
991 visible = false;
992 }
993
994 if (visible) {
995 for (unsigned int i = 0; i < 4; i++) {
996 project(X[i], cMt, X2[i]);
997 pt[i].track(cMt);
998 if (pt[i].get_Z() < 0)
999 needClipping = true;
1000 }
1001
1002 vbase_u = X2[1] - X2[0];
1003 vbase_v = X2[3] - X2[0];
1004
1005 distance = vpColVector::dotProd(normal_Cam, X2[1]);
1006
1007 if (distance < 0) {
1008 visible = false;
1009 return;
1010 }
1011
1012 for (unsigned int i = 0; i < 3; i++) {
1013 normal_Cam_optim[i] = normal_Cam[i];
1014 X0_2_optim[i] = X2[0][i];
1015 vbase_u_optim[i] = vbase_u[i];
1016 vbase_v_optim[i] = vbase_v[i];
1017 }
1018
1019 std::vector<vpPoint> *ptPtr = &pt;
1020 if (needClipping) {
1022 ptPtr = &ptClipped;
1023 }
1024
1025 listTriangle.clear();
1026 for (unsigned int i = 1; i < (*ptPtr).size() - 1; i++) {
1027 vpImagePoint ip1, ip2, ip3;
1028 ip1.set_j((*ptPtr)[0].get_x());
1029 ip1.set_i((*ptPtr)[0].get_y());
1030
1031 ip2.set_j((*ptPtr)[i].get_x());
1032 ip2.set_i((*ptPtr)[i].get_y());
1033
1034 ip3.set_j((*ptPtr)[i + 1].get_x());
1035 ip3.set_i((*ptPtr)[i + 1].get_y());
1036
1037 vpTriangle tri(ip1, ip2, ip3);
1038 listTriangle.push_back(tri);
1039 }
1040 }
1041}
1042
1043void vpImageSimulator::initPlan(vpColVector *X_)
1044{
1045 for (unsigned int i = 0; i < 4; i++) {
1046 X[i] = X_[i];
1047 pt[i].setWorldCoordinates(X_[i][0], X_[i][1], X_[i][2]);
1048 }
1049
1050 normal_obj = vpColVector::crossProd(X[1] - X[0], X[3] - X[0]);
1051 normal_obj = normal_obj / normal_obj.frobeniusNorm();
1052
1053 frobeniusNorm_u = (X[1] - X[0]).frobeniusNorm();
1054 fronbniusNorm_v = (X[3] - X[0]).frobeniusNorm();
1055}
1056
1072{
1073 Ig = I;
1075 initPlan(X_);
1076}
1077
1093{
1094 Ic = I;
1096 initPlan(X_);
1097}
1098
1099#ifdef VISP_HAVE_MODULE_IO
1115void vpImageSimulator::init(const char *file_image, vpColVector *X_)
1116{
1117 vpImageIo::read(Ig, file_image);
1118 vpImageIo::read(Ic, file_image);
1119 initPlan(X_);
1120}
1121#endif
1122
1138void vpImageSimulator::init(const vpImage<unsigned char> &I, const std::vector<vpPoint> &X_)
1139{
1140 if (X_.size() != 4) {
1141 throw vpException(vpException::dimensionError, "the vector must contains 4 points to initialise the simulator");
1142 }
1143 vpColVector Xvec[4];
1144 for (unsigned int i = 0; i < 4; ++i) {
1145 Xvec[i].resize(3);
1146 Xvec[i][0] = X_[i].get_oX();
1147 Xvec[i][1] = X_[i].get_oY();
1148 Xvec[i][2] = X_[i].get_oZ();
1149 }
1150
1151 Ig = I;
1153 initPlan(Xvec);
1154}
1155
1170void vpImageSimulator::init(const vpImage<vpRGBa> &I, const std::vector<vpPoint> &X_)
1171{
1172 if (X_.size() != 4) {
1173 throw vpException(vpException::dimensionError, "the vector must contains 4 points to initialise the simulator");
1174 }
1175 vpColVector Xvec[4];
1176 for (unsigned int i = 0; i < 4; ++i) {
1177 Xvec[i].resize(3);
1178 Xvec[i][0] = X_[i].get_oX();
1179 Xvec[i][1] = X_[i].get_oY();
1180 Xvec[i][2] = X_[i].get_oZ();
1181 }
1182
1183 Ic = I;
1185 initPlan(Xvec);
1186}
1187
1188#ifdef VISP_HAVE_MODULE_IO
1205void vpImageSimulator::init(const char *file_image, const std::vector<vpPoint> &X_)
1206{
1207 if (X_.size() != 4) {
1208 throw vpException(vpException::dimensionError, "the vector must contains 4 points to initialise the simulator");
1209 }
1210 vpColVector Xvec[4];
1211 for (unsigned int i = 0; i < 4; ++i) {
1212 Xvec[i].resize(3);
1213 Xvec[i][0] = X_[i].get_oX();
1214 Xvec[i][1] = X_[i].get_oY();
1215 Xvec[i][2] = X_[i].get_oZ();
1216 }
1217
1218 vpImageIo::read(Ig, file_image);
1219 vpImageIo::read(Ic, file_image);
1220 initPlan(Xvec);
1221}
1222#endif
1223
1224bool vpImageSimulator::getPixel(const vpImagePoint &iP, unsigned char &Ipixelplan)
1225{
1226 // std::cout << "In get Pixel" << std::endl;
1227 // test si pixel dans zone projetee
1228 bool inside = false;
1229 for (unsigned int i = 0; i < listTriangle.size(); i++)
1230 if (listTriangle[i].inTriangle(iP)) {
1231 inside = true;
1232 break;
1233 }
1234 if (!inside)
1235 return false;
1236
1237 // if(!T1.inTriangle(iP) && !T2.inTriangle(iP)){
1240 // return false;}
1241
1242 // methoed algebrique
1243 double z;
1244
1245 // calcul de la profondeur de l'intersection
1246 z = distance / (normal_Cam_optim[0] * iP.get_u() + normal_Cam_optim[1] * iP.get_v() + normal_Cam_optim[2]);
1247 // calcul coordonnees 3D intersection
1248 Xinter_optim[0] = iP.get_u() * z;
1249 Xinter_optim[1] = iP.get_v() * z;
1250 Xinter_optim[2] = z;
1251
1252 // recuperation des coordonnes de l'intersection dans le plan objet
1253 // repere plan object :
1254 // centre = X0_2_optim[i] (premier point definissant le plan)
1255 // base = u:(X[1]-X[0]) et v:(X[3]-X[0])
1256 // ici j'ai considere que le plan est un rectangle => coordonnees sont
1257 // simplement obtenu par un produit scalaire
1258 double u = 0, v = 0;
1259 for (unsigned int i = 0; i < 3; i++) {
1260 double diff = (Xinter_optim[i] - X0_2_optim[i]);
1261 u += diff * vbase_u_optim[i];
1262 v += diff * vbase_v_optim[i];
1263 }
1264 u = u / (frobeniusNorm_u * frobeniusNorm_u);
1265 v = v / (fronbniusNorm_v * fronbniusNorm_v);
1266
1267 if (u > 0 && v > 0 && u < 1. && v < 1.) {
1268 double i2, j2;
1269 i2 = v * (Ig.getHeight() - 1);
1270 j2 = u * (Ig.getWidth() - 1);
1271 if (interp == BILINEAR_INTERPOLATION)
1272 Ipixelplan = Ig.getValue(i2, j2);
1273 else if (interp == SIMPLE)
1274 Ipixelplan = Ig[static_cast<unsigned int>(i2)][static_cast<unsigned int>(j2)];
1275 return true;
1276 }
1277 else
1278 return false;
1279}
1280
1281bool vpImageSimulator::getPixel(vpImage<unsigned char> &Isrc, const vpImagePoint &iP, unsigned char &Ipixelplan)
1282{
1283 // test si pixel dans zone projetee
1284 bool inside = false;
1285 for (unsigned int i = 0; i < listTriangle.size(); i++)
1286 if (listTriangle[i].inTriangle(iP)) {
1287 inside = true;
1288 break;
1289 }
1290 if (!inside)
1291 return false;
1292
1293 // if(!T1.inTriangle(iP) && !T2.inTriangle(iP))
1294 // return false;
1295
1296 // methoed algebrique
1297 double z;
1298
1299 // calcul de la profondeur de l'intersection
1300 z = distance / (normal_Cam_optim[0] * iP.get_u() + normal_Cam_optim[1] * iP.get_v() + normal_Cam_optim[2]);
1301 // calcul coordonnees 3D intersection
1302 Xinter_optim[0] = iP.get_u() * z;
1303 Xinter_optim[1] = iP.get_v() * z;
1304 Xinter_optim[2] = z;
1305
1306 // recuperation des coordonnes de l'intersection dans le plan objet
1307 // repere plan object :
1308 // centre = X0_2_optim[i] (premier point definissant le plan)
1309 // base = u:(X[1]-X[0]) et v:(X[3]-X[0])
1310 // ici j'ai considere que le plan est un rectangle => coordonnees sont
1311 // simplement obtenu par un produit scalaire
1312 double u = 0, v = 0;
1313 for (unsigned int i = 0; i < 3; i++) {
1314 double diff = (Xinter_optim[i] - X0_2_optim[i]);
1315 u += diff * vbase_u_optim[i];
1316 v += diff * vbase_v_optim[i];
1317 }
1318 u = u / (frobeniusNorm_u * frobeniusNorm_u);
1319 v = v / (fronbniusNorm_v * fronbniusNorm_v);
1320
1321 if (u > 0 && v > 0 && u < 1. && v < 1.) {
1322 double i2, j2;
1323 i2 = v * (Isrc.getHeight() - 1);
1324 j2 = u * (Isrc.getWidth() - 1);
1325 if (interp == BILINEAR_INTERPOLATION)
1326 Ipixelplan = Isrc.getValue(i2, j2);
1327 else if (interp == SIMPLE)
1328 Ipixelplan = Isrc[static_cast<unsigned int>(i2)][static_cast<unsigned int>(j2)];
1329 return true;
1330 }
1331 else
1332 return false;
1333}
1334
1335bool vpImageSimulator::getPixel(const vpImagePoint &iP, vpRGBa &Ipixelplan)
1336{
1337 // test si pixel dans zone projetee
1338 bool inside = false;
1339 for (unsigned int i = 0; i < listTriangle.size(); i++)
1340 if (listTriangle[i].inTriangle(iP)) {
1341 inside = true;
1342 break;
1343 }
1344 if (!inside)
1345 return false;
1346 // if(!T1.inTriangle(iP) && !T2.inTriangle(iP))
1347 // return false;
1348
1349 // methoed algebrique
1350 double z;
1351
1352 // calcul de la profondeur de l'intersection
1353 z = distance / (normal_Cam_optim[0] * iP.get_u() + normal_Cam_optim[1] * iP.get_v() + normal_Cam_optim[2]);
1354 // calcul coordonnees 3D intersection
1355 Xinter_optim[0] = iP.get_u() * z;
1356 Xinter_optim[1] = iP.get_v() * z;
1357 Xinter_optim[2] = z;
1358
1359 // recuperation des coordonnes de l'intersection dans le plan objet
1360 // repere plan object :
1361 // centre = X0_2_optim[i] (premier point definissant le plan)
1362 // base = u:(X[1]-X[0]) et v:(X[3]-X[0])
1363 // ici j'ai considere que le plan est un rectangle => coordonnees sont
1364 // simplement obtenu par un produit scalaire
1365 double u = 0, v = 0;
1366 for (unsigned int i = 0; i < 3; i++) {
1367 double diff = (Xinter_optim[i] - X0_2_optim[i]);
1368 u += diff * vbase_u_optim[i];
1369 v += diff * vbase_v_optim[i];
1370 }
1371 u = u / (frobeniusNorm_u * frobeniusNorm_u);
1372 v = v / (fronbniusNorm_v * fronbniusNorm_v);
1373
1374 if (u > 0 && v > 0 && u < 1. && v < 1.) {
1375 double i2, j2;
1376 i2 = v * (Ic.getHeight() - 1);
1377 j2 = u * (Ic.getWidth() - 1);
1378 if (interp == BILINEAR_INTERPOLATION)
1379 Ipixelplan = Ic.getValue(i2, j2);
1380 else if (interp == SIMPLE)
1381 Ipixelplan = Ic[static_cast<unsigned int>(i2)][static_cast<unsigned int>(j2)];
1382 return true;
1383 }
1384 else
1385 return false;
1386}
1387
1388bool vpImageSimulator::getPixel(vpImage<vpRGBa> &Isrc, const vpImagePoint &iP, vpRGBa &Ipixelplan)
1389{
1390 // test si pixel dans zone projetee
1391 // if(!T1.inTriangle(iP) && !T2.inTriangle(iP))
1392 // return false;
1393 bool inside = false;
1394 for (unsigned int i = 0; i < listTriangle.size(); i++)
1395 if (listTriangle[i].inTriangle(iP)) {
1396 inside = true;
1397 break;
1398 }
1399 if (!inside)
1400 return false;
1401
1402 // methoed algebrique
1403 double z;
1404
1405 // calcul de la profondeur de l'intersection
1406 z = distance / (normal_Cam_optim[0] * iP.get_u() + normal_Cam_optim[1] * iP.get_v() + normal_Cam_optim[2]);
1407 // calcul coordonnees 3D intersection
1408 Xinter_optim[0] = iP.get_u() * z;
1409 Xinter_optim[1] = iP.get_v() * z;
1410 Xinter_optim[2] = z;
1411
1412 // recuperation des coordonnes de l'intersection dans le plan objet
1413 // repere plan object :
1414 // centre = X0_2_optim[i] (premier point definissant le plan)
1415 // base = u:(X[1]-X[0]) et v:(X[3]-X[0])
1416 // ici j'ai considere que le plan est un rectangle => coordonnees sont
1417 // simplement obtenu par un produit scalaire
1418 double u = 0, v = 0;
1419 for (unsigned int i = 0; i < 3; i++) {
1420 double diff = (Xinter_optim[i] - X0_2_optim[i]);
1421 u += diff * vbase_u_optim[i];
1422 v += diff * vbase_v_optim[i];
1423 }
1424 u = u / (frobeniusNorm_u * frobeniusNorm_u);
1425 v = v / (fronbniusNorm_v * fronbniusNorm_v);
1426
1427 if (u > 0 && v > 0 && u < 1. && v < 1.) {
1428 double i2, j2;
1429 i2 = v * (Isrc.getHeight() - 1);
1430 j2 = u * (Isrc.getWidth() - 1);
1431 if (interp == BILINEAR_INTERPOLATION)
1432 Ipixelplan = Isrc.getValue(i2, j2);
1433 else if (interp == SIMPLE)
1434 Ipixelplan = Isrc[static_cast<unsigned int>(i2)][static_cast<unsigned int>(j2)];
1435 return true;
1436 }
1437 else
1438 return false;
1439}
1440
1441bool vpImageSimulator::getPixelDepth(const vpImagePoint &iP, double &Zpixelplan)
1442{
1443 // test si pixel dans zone projetee
1444 bool inside = false;
1445 for (unsigned int i = 0; i < listTriangle.size(); i++)
1446 if (listTriangle[i].inTriangle(iP)) {
1447 inside = true;
1448 break;
1449 }
1450 if (!inside)
1451 return false;
1452 // if(!T1.inTriangle(iP) && !T2.inTriangle(iP))
1453 // return false;
1454
1455 Zpixelplan = distance / (normal_Cam_optim[0] * iP.get_u() + normal_Cam_optim[1] * iP.get_v() + normal_Cam_optim[2]);
1456 return true;
1457}
1458
1459bool vpImageSimulator::getPixelVisibility(const vpImagePoint &iP, double &Visipixelplan)
1460{
1461 // test si pixel dans zone projetee
1462 bool inside = false;
1463 for (unsigned int i = 0; i < listTriangle.size(); i++)
1464 if (listTriangle[i].inTriangle(iP)) {
1465 inside = true;
1466 break;
1467 }
1468 if (!inside)
1469 return false;
1470 // if(!T1.inTriangle(iP) && !T2.inTriangle(iP))
1471 // return false;
1472
1473 Visipixelplan = visible_result;
1474 return true;
1475}
1476
1477void vpImageSimulator::project(const vpColVector &_vin, const vpHomogeneousMatrix &_cMt, vpColVector &_vout)
1478{
1479 vpColVector XH(4);
1480 getHomogCoord(_vin, XH);
1481 getCoordFromHomog(_cMt * XH, _vout);
1482}
1483
1484void vpImageSimulator::getHomogCoord(const vpColVector &_v, vpColVector &_vH)
1485{
1486 for (unsigned int i = 0; i < 3; i++)
1487 _vH[i] = _v[i];
1488 _vH[3] = 1.;
1489}
1490
1491void vpImageSimulator::getCoordFromHomog(const vpColVector &_vH, vpColVector &_v)
1492{
1493 for (unsigned int i = 0; i < 3; i++)
1494 _v[i] = _vH[i] / _vH[3];
1495}
1496
1497void vpImageSimulator::getRoi(const unsigned int &Iwidth, const unsigned int &Iheight, const vpCameraParameters &cam,
1498 const std::vector<vpPoint> &point, vpRect &rectangle)
1499{
1500 double top = Iheight + 1;
1501 double bottom = -1;
1502 double right = -1;
1503 double left = Iwidth + 1;
1504
1505 for (unsigned int i = 0; i < point.size(); i++) {
1506 double u = 0, v = 0;
1507 vpMeterPixelConversion::convertPoint(cam, point[i].get_x(), point[i].get_y(), u, v);
1508 if (v < top)
1509 top = v;
1510 if (v > bottom)
1511 bottom = v;
1512 if (u < left)
1513 left = u;
1514 if (u > right)
1515 right = u;
1516 }
1517 if (top < 0)
1518 top = 0;
1519 if (top >= Iheight)
1520 top = Iheight - 1;
1521 if (bottom < 0)
1522 bottom = 0;
1523 if (bottom >= Iheight)
1524 bottom = Iheight - 1;
1525 if (left < 0)
1526 left = 0;
1527 if (left >= Iwidth)
1528 left = Iwidth - 1;
1529 if (right < 0)
1530 right = 0;
1531 if (right >= Iwidth)
1532 right = Iwidth - 1;
1533
1534 rectangle.setTop(top);
1535 rectangle.setBottom(bottom);
1536 rectangle.setLeft(left);
1537 rectangle.setRight(right);
1538}
1539
1541{
1542 std::vector<vpColVector> X_;
1543 for (int i = 0; i < 4; i++)
1544 X_.push_back(X[i]);
1545 return X_;
1546}
1547
1548VISP_EXPORT std::ostream &operator<<(std::ostream &os, const vpImageSimulator & /*ip*/)
1549{
1550 os << "";
1551 return os;
1552}
1553END_VISP_NAMESPACE
unsigned int getCols() const
Definition vpArray2D.h:423
unsigned int getRows() const
Definition vpArray2D.h:433
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
static double dotProd(const vpColVector &a, const vpColVector &b)
static vpColVector crossProd(const vpColVector &a, const vpColVector &b)
void resize(unsigned int i, bool flagNullify=true)
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ dimensionError
Bad dimension.
Definition vpException.h:71
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_j(double jj)
void set_ij(double ii, double jj)
void set_i(double ii)
double get_u() const
double get_v() const
void getImage(vpImage< unsigned char > &I, const vpCameraParameters &cam)
VP_EXPLICIT vpImageSimulator(const vpColorPlan &col=COLORED)
std::vector< vpColVector > get3DcornersTextureRectangle()
void init(const vpImage< unsigned char > &I, vpColVector *X)
friend VISP_EXPORT std::ostream & operator<<(std::ostream &os, const vpImageSimulator &)
void setCameraPosition(const vpHomogeneousMatrix &cMt)
vpImageSimulator & operator=(const vpImageSimulator &sim)
Definition of the vpImage class member functions.
Definition vpImage.h:131
unsigned int getWidth() const
Definition vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition vpImage.h:544
Type getValue(unsigned int i, unsigned int j) const
unsigned int getHeight() const
Definition vpImage.h:181
error that can be emitted by the vpMatrix class and its derivatives
@ incorrectMatrixSizeError
Incorrect matrix size.
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
static void getClippedPolygon(const std::vector< vpPoint > &ptIn, std::vector< vpPoint > &ptOut, const vpHomogeneousMatrix &cMo, const unsigned int &clippingFlags, const vpCameraParameters &cam=vpCameraParameters(), const double &znear=0.001, const double &zfar=100)
unsigned char B
Blue component.
Definition vpRGBa.h:327
unsigned char R
Red component.
Definition vpRGBa.h:325
unsigned char G
Green component.
Definition vpRGBa.h:326
Defines a rectangle in the plane.
Definition vpRect.h:79
void setTop(double pos)
Definition vpRect.h:357
double getLeft() const
Definition vpRect.h:173
void setLeft(double pos)
Definition vpRect.h:321
void setRight(double pos)
Definition vpRect.h:348
double getRight() const
Definition vpRect.h:179
double getBottom() const
Definition vpRect.h:97
void setBottom(double pos)
Definition vpRect.h:288
double getTop() const
Definition vpRect.h:192
Implementation of a rotation matrix and operations on such kind of matrices.
Defines a 2D triangle.
Definition vpTriangle.h:54