Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMbtDistanceCylinder.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:
31 * Make the complete tracking of an object by using its CAD model. Cylinder
32 * tracking.
33 *
34 * Authors:
35 * Romain Tallonneau
36 * Bertrand Delabarre
37 */
38
39#include <visp3/core/vpConfig.h>
40
45
46#include <algorithm>
47#include <stdlib.h>
48#include <visp3/core/vpMeterPixelConversion.h>
49#include <visp3/core/vpPixelMeterConversion.h>
50#include <visp3/core/vpPlane.h>
51#include <visp3/mbt/vpMbtDistanceCylinder.h>
52#include <visp3/visual_features/vpFeatureBuilder.h>
53#include <visp3/visual_features/vpFeatureEllipse.h>
54
55#include <visp3/vision/vpPose.h>
56
58namespace
59{
60const unsigned int defaultRange = 0U;
61}
66 : name(), index(0), cam(), me(nullptr), wmean1(1), wmean2(1), featureline1(), featureline2(), isTrackedCylinder(true),
67 meline1(nullptr), meline2(nullptr), cercle1(nullptr), cercle2(nullptr), radius(0), p1(nullptr), p2(nullptr), L(), error(),
68 nbFeature(0), nbFeaturel1(0), nbFeaturel2(0), Reinit(false), c(nullptr), hiddenface(nullptr), index_polygon(-1),
69 isvisible(false)
70{ }
71
76{
77 if (p1 != nullptr)
78 delete p1;
79 if (p2 != nullptr)
80 delete p2;
81 if (c != nullptr)
82 delete c;
83 if (meline1 != nullptr)
84 delete meline1;
85 if (meline2 != nullptr)
86 delete meline2;
87 if (cercle1 != nullptr)
88 delete cercle1;
89 if (cercle2 != nullptr)
90 delete cercle2;
91}
92
100void vpMbtDistanceCylinder::project(const vpHomogeneousMatrix &cMo)
101{
102 c->project(cMo);
103 p1->project(cMo);
104 p2->project(cMo);
105 cercle1->project(cMo);
106 cercle2->project(cMo);
107}
108
117void vpMbtDistanceCylinder::buildFrom(const vpPoint &_p1, const vpPoint &_p2, double r)
118{
119 c = new vpCylinder;
120 p1 = new vpPoint;
121 p2 = new vpPoint;
122 cercle1 = new vpCircle;
123 cercle2 = new vpCircle;
124
125 // Get the points
126 *p1 = _p1;
127 *p2 = _p2;
128
129 // Get the radius
130 radius = r;
131
132 vpColVector ABC(3);
133 vpColVector V1(3);
134 vpColVector V2(3);
135
136 V1[0] = _p1.get_oX();
137 V1[1] = _p1.get_oY();
138 V1[2] = _p1.get_oZ();
139 V2[0] = _p2.get_oX();
140 V2[1] = _p2.get_oY();
141 V2[2] = _p2.get_oZ();
142
143 // Get the axis of the cylinder
144 ABC = V1 - V2;
145
146 // Build our extremity circles
147 cercle1->setWorldCoordinates(ABC[0], ABC[1], ABC[2], _p1.get_oX(), _p1.get_oY(), _p1.get_oZ(), r);
148 cercle2->setWorldCoordinates(ABC[0], ABC[1], ABC[2], _p2.get_oX(), _p2.get_oY(), _p2.get_oZ(), r);
149
150 // Build our cylinder
151 c->setWorldCoordinates(ABC[0], ABC[1], ABC[2], (_p1.get_oX() + _p2.get_oX()) / 2.0,
152 (_p1.get_oY() + _p2.get_oY()) / 2.0, (_p1.get_oZ() + _p2.get_oZ()) / 2.0, r);
153}
154
161{
162 me = _me;
163 if (meline1 != nullptr) {
164 meline1->setMe(me);
165 }
166 if (meline2 != nullptr) {
167 meline2->setMe(me);
168 }
169}
170
185 bool doNotTrack, const vpImage<bool> *mask, const int &initRange)
186{
187 if (isvisible) {
188 // Perspective projection
189 p1->changeFrame(cMo);
190 p2->changeFrame(cMo);
191 cercle1->changeFrame(cMo);
192 cercle2->changeFrame(cMo);
193 c->changeFrame(cMo);
194
195 p1->projection();
196 p2->projection();
197 try {
198 cercle1->projection();
199 }
200 catch (...) {
201 // std::cout<<"Problem when projecting circle 1\n";
202 return false;
203 }
204 try {
205 cercle2->projection();
206 }
207 catch (...) {
208 // std::cout<<"Problem when projecting circle 2\n";
209 return false;
210 }
211 c->projection();
212
213 double rho1, theta1;
214 double rho2, theta2;
215
216 // Create the moving edges containers
217 meline1 = new vpMbtMeLine;
218 meline1->setMask(*mask);
219 meline1->setMe(me);
220 meline2 = new vpMbtMeLine;
221 meline1->setMask(*mask);
222 meline2->setMe(me);
223
224 // meline->setDisplay(vpMeSite::RANGE_RESULT);
225 unsigned int initRange_;
226 if (initRange < 0) {
227 initRange_ = defaultRange;
228 }
229 else {
230 initRange_ = static_cast<unsigned int>(initRange);
231 }
232 int oldInitRange = me->getInitRange();
233 me->setInitRange(initRange_);
234
235 // Conversion meter to pixels
236 vpMeterPixelConversion::convertLine(cam, c->getRho1(), c->getTheta1(), rho1, theta1);
237 vpMeterPixelConversion::convertLine(cam, c->getRho2(), c->getTheta2(), rho2, theta2);
238
239 // Determine intersections between circles and limbos
240 double i11, i12, i21, i22, j11, j12, j21, j22;
241 vpCircle::computeIntersectionPoint(*cercle1, cam, rho1, theta1, i11, j11);
242 vpCircle::computeIntersectionPoint(*cercle2, cam, rho1, theta1, i12, j12);
243 vpCircle::computeIntersectionPoint(*cercle1, cam, rho2, theta2, i21, j21);
244 vpCircle::computeIntersectionPoint(*cercle2, cam, rho2, theta2, i22, j22);
245
246 // Create the image points
247 vpImagePoint ip11, ip12, ip21, ip22;
248 ip11.set_ij(i11, j11);
249 ip12.set_ij(i12, j12);
250 ip21.set_ij(i21, j21);
251 ip22.set_ij(i22, j22);
252
253 // update limits of the melines.
254 int marge = /*10*/ 5; // ou 5 normalement
255 if (ip11.get_j() < ip12.get_j()) {
256 meline1->jmin = static_cast<int>(ip11.get_j()) - marge;
257 meline1->jmax = static_cast<int>(ip12.get_j()) + marge;
258 }
259 else {
260 meline1->jmin = static_cast<int>(ip12.get_j()) - marge;
261 meline1->jmax = static_cast<int>(ip11.get_j()) + marge;
262 }
263 if (ip11.get_i() < ip12.get_i()) {
264 meline1->imin = static_cast<int>(ip11.get_i()) - marge;
265 meline1->imax = static_cast<int>(ip12.get_i()) + marge;
266 }
267 else {
268 meline1->imin = static_cast<int>(ip12.get_i()) - marge;
269 meline1->imax = static_cast<int>(ip11.get_i()) + marge;
270 }
271
272 if (ip21.get_j() < ip22.get_j()) {
273 meline2->jmin = static_cast<int>(ip21.get_j()) - marge;
274 meline2->jmax = static_cast<int>(ip22.get_j()) + marge;
275 }
276 else {
277 meline2->jmin = static_cast<int>(ip22.get_j()) - marge;
278 meline2->jmax = static_cast<int>(ip21.get_j()) + marge;
279 }
280 if (ip21.get_i() < ip22.get_i()) {
281 meline2->imin = static_cast<int>(ip21.get_i()) - marge;
282 meline2->imax = static_cast<int>(ip22.get_i()) + marge;
283 }
284 else {
285 meline2->imin = static_cast<int>(ip22.get_i()) - marge;
286 meline2->imax = static_cast<int>(ip21.get_i()) + marge;
287 }
288
289 // Initialize the tracking
290 while (theta1 > M_PI) {
291 theta1 -= M_PI;
292 }
293 while (theta1 < -M_PI) {
294 theta1 += M_PI;
295 }
296
297 if (theta1 < -M_PI / 2.0)
298 theta1 = -theta1 - 3 * M_PI / 2.0;
299 else
300 theta1 = M_PI / 2.0 - theta1;
301
302 while (theta2 > M_PI) {
303 theta2 -= M_PI;
304 }
305 while (theta2 < -M_PI) {
306 theta2 += M_PI;
307 }
308
309 if (theta2 < -M_PI / 2.0)
310 theta2 = -theta2 - 3 * M_PI / 2.0;
311 else
312 theta2 = M_PI / 2.0 - theta2;
313
314 try {
315 meline1->initTracking(I, ip11, ip12, rho1, theta1, doNotTrack);
316 }
317 catch (...) {
318 // vpTRACE("the line can't be initialized");
319 me->setInitRange(oldInitRange);
320 return false;
321 }
322 try {
323 meline2->initTracking(I, ip21, ip22, rho2, theta2, doNotTrack);
324 }
325 catch (...) {
326 // vpTRACE("the line can't be initialized");
327 me->setInitRange(oldInitRange);
328 return false;
329 }
330 me->setInitRange(oldInitRange);
331 }
332 return true;
333}
334
342{
343 (void)cMo;
344 int oldInitRange = me->getInitRange();
345 me->setInitRange(defaultRange);
346 if (isvisible) {
347 try {
348 meline1->track(I);
349 }
350 catch (...) {
351 // std::cout << "Track meline1 failed" << std::endl;
352 meline1->reset();
353 Reinit = true;
354 }
355 try {
356 meline2->track(I);
357 }
358 catch (...) {
359 // std::cout << "Track meline2 failed" << std::endl;
360 meline2->reset();
361 Reinit = true;
362 }
363
364 // Update the number of features
365 nbFeaturel1 = static_cast<unsigned int>(meline1->getMeList().size());
366 nbFeaturel2 = static_cast<unsigned int>(meline2->getMeList().size());
368 }
369 me->setInitRange(oldInitRange);
370}
371
379{
380 int oldInitRange = me->getInitRange();
381 me->setInitRange(defaultRange);
382 if (isvisible) {
383 // Perspective projection
384 p1->changeFrame(cMo);
385 p2->changeFrame(cMo);
386 cercle1->changeFrame(cMo);
387 cercle2->changeFrame(cMo);
388 c->changeFrame(cMo);
389
390 p1->projection();
391 p2->projection();
392 try {
393 cercle1->projection();
394 }
395 catch (...) {
396 std::cout << "Probleme projection cercle 1\n";
397 }
398 try {
399 cercle2->projection();
400 }
401 catch (...) {
402 std::cout << "Probleme projection cercle 2\n";
403 }
404 c->projection();
405
406 // Get the limbos
407 double rho1, theta1;
408 double rho2, theta2;
409
410 // Conversion meter to pixels
411 vpMeterPixelConversion::convertLine(cam, c->getRho1(), c->getTheta1(), rho1, theta1);
412 vpMeterPixelConversion::convertLine(cam, c->getRho2(), c->getTheta2(), rho2, theta2);
413
414 // Determine intersections between circles and limbos
415 double i11, i12, i21, i22, j11, j12, j21, j22;
416
417 vpCircle::computeIntersectionPoint(*cercle1, cam, rho1, theta1, i11, j11);
418 vpCircle::computeIntersectionPoint(*cercle2, cam, rho1, theta1, i12, j12);
419
420 vpCircle::computeIntersectionPoint(*cercle1, cam, rho2, theta2, i21, j21);
421 vpCircle::computeIntersectionPoint(*cercle2, cam, rho2, theta2, i22, j22);
422
423 // Create the image points
424 vpImagePoint ip11, ip12, ip21, ip22;
425 ip11.set_ij(i11, j11);
426 ip12.set_ij(i12, j12);
427 ip21.set_ij(i21, j21);
428 ip22.set_ij(i22, j22);
429
430 // update limits of the meline.
431 int marge = /*10*/ 5; // ou 5 normalement
432 if (ip11.get_j() < ip12.get_j()) {
433 meline1->jmin = static_cast<int>(ip11.get_j()) - marge;
434 meline1->jmax = static_cast<int>(ip12.get_j()) + marge;
435 }
436 else {
437 meline1->jmin = static_cast<int>(ip12.get_j()) - marge;
438 meline1->jmax = static_cast<int>(ip11.get_j()) + marge;
439 }
440 if (ip11.get_i() < ip12.get_i()) {
441 meline1->imin = static_cast<int>(ip11.get_i()) - marge;
442 meline1->imax = static_cast<int>(ip12.get_i()) + marge;
443 }
444 else {
445 meline1->imin = static_cast<int>(ip12.get_i()) - marge;
446 meline1->imax = static_cast<int>(ip11.get_i()) + marge;
447 }
448
449 if (ip21.get_j() < ip22.get_j()) {
450 meline2->jmin = static_cast<int>(ip21.get_j()) - marge;
451 meline2->jmax = static_cast<int>(ip22.get_j()) + marge;
452 }
453 else {
454 meline2->jmin = static_cast<int>(ip22.get_j()) - marge;
455 meline2->jmax = static_cast<int>(ip21.get_j()) + marge;
456 }
457 if (ip21.get_i() < ip22.get_i()) {
458 meline2->imin = static_cast<int>(ip21.get_i()) - marge;
459 meline2->imax = static_cast<int>(ip22.get_i()) + marge;
460 }
461 else {
462 meline2->imin = static_cast<int>(ip22.get_i()) - marge;
463 meline2->imax = static_cast<int>(ip21.get_i()) + marge;
464 }
465
466 // Initialize the tracking
467 while (theta1 > M_PI) {
468 theta1 -= M_PI;
469 }
470 while (theta1 < -M_PI) {
471 theta1 += M_PI;
472 }
473
474 if (theta1 < -M_PI / 2.0)
475 theta1 = -theta1 - 3 * M_PI / 2.0;
476 else
477 theta1 = M_PI / 2.0 - theta1;
478
479 while (theta2 > M_PI) {
480 theta2 -= M_PI;
481 }
482 while (theta2 < -M_PI) {
483 theta2 += M_PI;
484 }
485
486 if (theta2 < -M_PI / 2.0)
487 theta2 = -theta2 - 3 * M_PI / 2.0;
488 else
489 theta2 = M_PI / 2.0 - theta2;
490
491 try {
492 // meline1->updateParameters(I,rho1,theta1);
493 meline1->updateParameters(I, ip11, ip12, rho1, theta1);
494 }
495 catch (...) {
496 Reinit = true;
497 }
498 try {
499 // meline2->updateParameters(I,rho2,theta2);
500 meline2->updateParameters(I, ip21, ip22, rho2, theta2);
501 }
502 catch (...) {
503 Reinit = true;
504 }
505
506 // Update the numbers of features
507 nbFeaturel1 = static_cast<unsigned int>(meline1->getMeList().size());
508 nbFeaturel2 = static_cast<unsigned int>(meline2->getMeList().size());
510 }
511 me->setInitRange(oldInitRange);
512}
513
526 const vpImage<bool> *mask)
527{
528 if (meline1 != nullptr)
529 delete meline1;
530 if (meline2 != nullptr)
531 delete meline2;
532
533 meline1 = nullptr;
534 meline2 = nullptr;
535
536 if (!initMovingEdge(I, cMo, false, mask))
537 Reinit = true;
538
539 Reinit = false;
540}
541
553 const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
554 bool displayFullModel)
555{
556 std::vector<std::vector<double> > models =
557 getModelForDisplay(I.getWidth(), I.getHeight(), cMo, camera, displayFullModel);
558
559 for (size_t i = 0; i < models.size(); i++) {
560 vpImagePoint ip1(models[i][1], models[i][2]);
561 vpImagePoint ip2(models[i][3], models[i][4]);
562
563 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
564 }
565}
566
578 const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
579 bool displayFullModel)
580{
581 std::vector<std::vector<double> > models =
582 getModelForDisplay(I.getWidth(), I.getHeight(), cMo, camera, displayFullModel);
583
584 for (size_t i = 0; i < models.size(); i++) {
585 vpImagePoint ip1(models[i][1], models[i][2]);
586 vpImagePoint ip2(models[i][3], models[i][4]);
587
588 vpDisplay::displayLine(I, ip1, ip2, col, thickness);
589 }
590}
591
596std::vector<std::vector<double> > vpMbtDistanceCylinder::getFeaturesForDisplay()
597{
598 std::vector<std::vector<double> > features;
599
600 if (meline1 != nullptr) {
601 for (std::list<vpMeSite>::const_iterator it = meline1->getMeList().begin(); it != meline1->getMeList().end();
602 ++it) {
603 vpMeSite p_me = *it;
604#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
605 std::vector<double> params = { 0, //ME
606 p_me.get_ifloat(),
607 p_me.get_jfloat(),
608 static_cast<double>(p_me.getState()) };
609#else
610 std::vector<double> params;
611 params.push_back(0); //ME
612 params.push_back(p_me.get_ifloat());
613 params.push_back(p_me.get_jfloat());
614 params.push_back(static_cast<double>(p_me.getState()));
615#endif
616
617 features.push_back(params);
618 }
619 }
620
621 if (meline2 != nullptr) {
622 for (std::list<vpMeSite>::const_iterator it = meline2->getMeList().begin(); it != meline2->getMeList().end();
623 ++it) {
624 vpMeSite p_me = *it;
625#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
626 std::vector<double> params = { 0, //ME
627 p_me.get_ifloat(),
628 p_me.get_jfloat(),
629 static_cast<double>(p_me.getState()) };
630#else
631 std::vector<double> params;
632 params.push_back(0); //ME
633 params.push_back(p_me.get_ifloat());
634 params.push_back(p_me.get_jfloat());
635 params.push_back(static_cast<double>(p_me.getState()));
636#endif
637
638 features.push_back(params);
639 }
640 }
641
642 return features;
643}
644
656std::vector<std::vector<double> > vpMbtDistanceCylinder::getModelForDisplay(unsigned int width, unsigned int height,
657 const vpHomogeneousMatrix &cMo,
658 const vpCameraParameters &camera,
659 bool displayFullModel)
660{
661 (void)width;
662 (void)height;
663 std::vector<std::vector<double> > models;
664
665 if ((isvisible && isTrackedCylinder) || displayFullModel) {
666 // Perspective projection
667 p1->changeFrame(cMo);
668 p2->changeFrame(cMo);
669 cercle1->changeFrame(cMo);
670 cercle2->changeFrame(cMo);
671 c->changeFrame(cMo);
672
673 p1->projection();
674 p2->projection();
675 try {
676 cercle1->projection();
677 }
678 catch (...) {
679 std::cout << "Problem projection circle 1";
680 }
681 try {
682 cercle2->projection();
683 }
684 catch (...) {
685 std::cout << "Problem projection circle 2";
686 }
687 c->projection();
688
689 double rho1, theta1;
690 double rho2, theta2;
691
692 // Meters to pixels conversion
693 vpMeterPixelConversion::convertLine(camera, c->getRho1(), c->getTheta1(), rho1, theta1);
694 vpMeterPixelConversion::convertLine(camera, c->getRho2(), c->getTheta2(), rho2, theta2);
695
696 // Determine intersections between circles and limbos
697 double i11, i12, i21, i22, j11, j12, j21, j22;
698
699 vpCircle::computeIntersectionPoint(*cercle1, cam, rho1, theta1, i11, j11);
700 vpCircle::computeIntersectionPoint(*cercle2, cam, rho1, theta1, i12, j12);
701
702 vpCircle::computeIntersectionPoint(*cercle1, cam, rho2, theta2, i21, j21);
703 vpCircle::computeIntersectionPoint(*cercle2, cam, rho2, theta2, i22, j22);
704
705 // Create the image points
706 vpImagePoint ip11, ip12, ip21, ip22;
707 ip11.set_ij(i11, j11);
708 ip12.set_ij(i12, j12);
709 ip21.set_ij(i21, j21);
710 ip22.set_ij(i22, j22);
711
712#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
713 std::vector<double> params1 = { 0,
714 ip11.get_i(),
715 ip11.get_j(),
716 ip12.get_i(),
717 ip12.get_j() };
718
719 std::vector<double> params2 = { 0,
720 ip21.get_i(),
721 ip21.get_j(),
722 ip22.get_i(),
723 ip22.get_j() };
724#else
725 std::vector<double> params1, params2;
726 params1.push_back(0);
727 params1.push_back(ip11.get_i());
728 params1.push_back(ip11.get_j());
729 params1.push_back(ip12.get_i());
730 params1.push_back(ip12.get_j());
731
732 params2.push_back(0);
733 params2.push_back(ip11.get_i());
734 params2.push_back(ip11.get_j());
735 params2.push_back(ip12.get_i());
736 params2.push_back(ip12.get_j());
737#endif
738
739 models.push_back(params1);
740 models.push_back(params2);
741 }
742
743 return models;
744}
745
761{
762 if (meline1 != nullptr) {
763 meline1->display(I);
764 }
765 if (meline2 != nullptr) {
766 meline2->display(I);
767 }
768}
769
771{
772 if (meline1 != nullptr) {
773 meline1->display(I);
774 }
775 if (meline2 != nullptr) {
776 meline2->display(I);
777 }
778}
779
784{
785 if (isvisible) {
786 nbFeaturel1 = static_cast<unsigned int>(meline1->getMeList().size());
787 nbFeaturel2 = static_cast<unsigned int>(meline2->getMeList().size());
789 L.resize(nbFeature, 6);
790 error.resize(nbFeature);
791 }
792 else {
793 nbFeature = 0;
794 nbFeaturel1 = 0;
795 nbFeaturel2 = 0;
796 }
797}
798
804 const vpImage<unsigned char> &I)
805{
806 if (isvisible) {
807 // Perspective projection
808 c->changeFrame(cMo);
809 c->projection();
810 cercle1->changeFrame(cMo);
811 cercle1->changeFrame(cMo);
812 try {
813 cercle1->projection();
814 }
815 catch (...) {
816 std::cout << "Problem projection circle 1\n";
817 }
818 try {
819 cercle2->projection();
820 }
821 catch (...) {
822 std::cout << "Problem projection circle 2\n";
823 }
824
825 bool disp = false;
826 bool disp2 = false;
827 if (disp || disp2)
829
830 // Build the lines
833
834 double rho1 = featureline1.getRho();
835 double theta1 = featureline1.getTheta();
836 double rho2 = featureline2.getRho();
837 double theta2 = featureline2.getTheta();
838
839 double co1 = cos(theta1);
840 double si1 = sin(theta1);
841 double co2 = cos(theta2);
842 double si2 = sin(theta2);
843
844 double mx = 1.0 / cam.get_px();
845 double my = 1.0 / cam.get_py();
846 double xc = cam.get_u0();
847 double yc = cam.get_v0();
848
849 vpMatrix H1;
850 H1 = featureline1.interaction();
851 vpMatrix H2;
852 H2 = featureline2.interaction();
853
854 vpMeSite p;
855 unsigned int j = 0;
856 for (std::list<vpMeSite>::const_iterator it = meline1->getMeList().begin(); it != meline1->getMeList().end();
857 ++it) {
858 double x = static_cast<double>(it->m_j);
859 double y = static_cast<double>(it->m_i);
860
861 x = (x - xc) * mx;
862 y = (y - yc) * my;
863
864 double alpha1 = x * si1 - y * co1;
865
866 double *Lrho = H1[0];
867 double *Ltheta = H1[1];
868 // Calculate interaction matrix for a distance
869 for (unsigned int k = 0; k < 6; k++) {
870 L[j][k] = (Lrho[k] + alpha1 * Ltheta[k]);
871 }
872 error[j] = rho1 - (x * co1 + y * si1);
873
874 if (disp)
875 vpDisplay::displayCross(I, it->m_i, it->m_j, static_cast<unsigned int>(error[j] * 100), vpColor::orange, 1);
876
877 j++;
878 }
879
880 for (std::list<vpMeSite>::const_iterator it = meline2->getMeList().begin(); it != meline2->getMeList().end();
881 ++it) {
882 double x = static_cast<double>(it->m_j);
883 double y = static_cast<double>(it->m_i);
884
885 x = (x - xc) * mx;
886 y = (y - yc) * my;
887
888 double alpha2 = x * si2 - y * co2;
889
890 double *Lrho = H2[0];
891 double *Ltheta = H2[1];
892 // Calculate interaction matrix for a distance
893 for (unsigned int k = 0; k < 6; k++) {
894 L[j][k] = (Lrho[k] + alpha2 * Ltheta[k]);
895 }
896 error[j] = rho2 - (x * co2 + y * si2);
897
898 if (disp)
899 vpDisplay::displayCross(I, it->m_i, it->m_j, static_cast<unsigned int>(error[j] * 100), vpColor::red, 1);
900
901 j++;
902 }
903 }
904}
905END_VISP_NAMESPACE
Generic class defining intrinsic camera parameters.
Class that defines a 3D circle in the object frame and allows forward projection of a 3D circle in th...
Definition vpCircle.h:87
static void computeIntersectionPoint(const vpCircle &circle, const vpCameraParameters &cam, const double &rho, const double &theta, double &i, double &j)
Definition vpCircle.cpp:458
Implementation of column vector and the associated operations.
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
static const vpColor red
Definition vpColor.h:198
static const vpColor orange
Definition vpColor.h:208
Class that defines a 3D cylinder in the object frame and allows forward projection of a 3D cylinder i...
Definition vpCylinder.h:101
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
Implementation of an homogeneous matrix and operations on such kind of matrices.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
double get_j() const
void set_ij(double ii, double jj)
double get_i() const
Definition of the vpImage class member functions.
Definition vpImage.h:131
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
void buildFrom(const vpPoint &_p1, const vpPoint &_p2, double r)
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo, const vpImage< unsigned char > &I)
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=nullptr)
vpMbtMeLine * meline2
The moving edge containers (second line of the cylinder).
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr, const int &initRange=0)
vpCylinder * c
The cylinder.
vpMatrix L
The interaction matrix.
unsigned int nbFeaturel2
The number of moving edges on line 2.
bool Reinit
Indicates if the line has to be reinitialized.
vpPoint * p2
The second extremity on the axe.
vpCircle * cercle1
The upper circle limiting the cylinder.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
double radius
The radius of the cylinder.
unsigned int nbFeaturel1
The number of moving edges on line 1.
vpColVector error
The error vector.
void displayMovingEdges(const vpImage< unsigned char > &I)
std::vector< std::vector< double > > getFeaturesForDisplay()
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
unsigned int nbFeature
The number of moving edges.
int index_polygon
Index of the face which contains the cylinder.
vpCircle * cercle2
The lower circle limiting the cylinder.
bool isvisible
Indicates if the cylinder is visible or not.
std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false)
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpPoint * p1
The first extremity on the axe.
vpMbtMeLine * meline1
The moving edge containers (first line of the cylinder).
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition vpMeSite.h:75
vpMeSiteState getState() const
Definition vpMeSite.h:306
double get_ifloat() const
Definition vpMeSite.h:212
double get_jfloat() const
Definition vpMeSite.h:218
Definition vpMe.h:143
static void convertLine(const vpCameraParameters &cam, const double &rho_m, const double &theta_m, double &rho_p, double &theta_p)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
double get_oX() const
Get the point oX coordinate in the object frame.
Definition vpPoint.cpp:418
double get_oZ() const
Get the point oZ coordinate in the object frame.
Definition vpPoint.cpp:422
double get_oY() const
Get the point oY coordinate in the object frame.
Definition vpPoint.cpp:420
const unsigned int defaultRange