Visual Servoing Platform  version 3.1.0
vpMbtDistanceLine.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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  * Make the complete tracking of an object by using its CAD model
33  *
34  * Authors:
35  * Nicolas Melchior
36  * Romain Tallonneau
37  * Eric Marchand
38  *
39  *****************************************************************************/
40 #include <visp3/core/vpConfig.h>
41 
47 #include <stdlib.h>
48 #include <visp3/core/vpMeterPixelConversion.h>
49 #include <visp3/core/vpPlane.h>
50 #include <visp3/mbt/vpMbtDistanceLine.h>
51 #include <visp3/visual_features/vpFeatureBuilder.h>
52 
53 void buildPlane(vpPoint &P, vpPoint &Q, vpPoint &R, vpPlane &plane);
54 void buildLine(vpPoint &P1, vpPoint &P2, vpPoint &P3, vpPoint &P4, vpLine &L);
55 
60  : name(), index(0), cam(), me(NULL), isTrackedLine(true), isTrackedLineWithVisibility(true), wmean(1), featureline(),
61  poly(), useScanLine(false), meline(), line(NULL), p1(NULL), p2(NULL), L(), error(), nbFeature(), nbFeatureTotal(0),
62  Reinit(false), hiddenface(NULL), Lindex_polygon(), Lindex_polygon_tracked(), isvisible(false)
63 {
64 }
65 
70 {
71  // cout << "Deleting line " << index << endl;
72  if (line != NULL)
73  delete line;
74 
75  for (unsigned int i = 0; i < meline.size(); i++)
76  if (meline[i] != NULL)
77  delete meline[i];
78 
79  meline.clear();
80 }
81 
88 void vpMbtDistanceLine::project(const vpHomogeneousMatrix &cMo)
89 {
90  line->project(cMo);
91  p1->project(cMo);
92  p2->project(cMo);
93 }
94 
104 void buildPlane(vpPoint &P, vpPoint &Q, vpPoint &R, vpPlane &plane)
105 {
106  vpColVector a(3);
107  vpColVector b(3);
108 
109  // Calculate vector corresponding to PQ
110  a[0] = P.get_oX() - Q.get_oX();
111  a[1] = P.get_oY() - Q.get_oY();
112  a[2] = P.get_oZ() - Q.get_oZ();
113 
114  // Calculate vector corresponding to PR
115  b[0] = P.get_oX() - R.get_oX();
116  b[1] = P.get_oY() - R.get_oY();
117  b[2] = P.get_oZ() - R.get_oZ();
118 
119  // Calculate normal vector to plane PQ x PR
121 
122  // Equation of the plane is given by:
123  double A = n[0];
124  double B = n[1];
125  double C = n[2];
126  double D = -(A * P.get_oX() + B * P.get_oY() + C * P.get_oZ());
127 
128  double norm = sqrt(A * A + B * B + C * C);
129  plane.setA(A / norm);
130  plane.setB(B / norm);
131  plane.setC(C / norm);
132  plane.setD(D / norm);
133 }
134 
148 void buildLine(vpPoint &P1, vpPoint &P2, vpPoint &P3, vpPoint &P4, vpLine &L)
149 {
150  vpPlane plane1;
151  vpPlane plane2;
152  buildPlane(P1, P2, P3, plane1);
153  buildPlane(P1, P2, P4, plane2);
154 
155  L.setWorldCoordinates(plane1.getA(), plane1.getB(), plane1.getC(), plane1.getD(), plane2.getA(), plane2.getB(),
156  plane2.getC(), plane2.getD());
157 }
158 
167 {
168  if (line == NULL) {
169  line = new vpLine;
170  }
171 
172  poly.setNbPoint(2);
173  poly.addPoint(0, _p1);
174  poly.addPoint(1, _p2);
175 
176  p1 = &poly.p[0];
177  p2 = &poly.p[1];
178 
179  vpColVector V1(3);
180  vpColVector V2(3);
181 
182  V1[0] = p1->get_oX();
183  V1[1] = p1->get_oY();
184  V1[2] = p1->get_oZ();
185  V2[0] = p2->get_oX();
186  V2[1] = p2->get_oY();
187  V2[2] = p2->get_oZ();
188 
189  // if((V1-V2).sumSquare()!=0)
190  if (std::fabs((V1 - V2).sumSquare()) > std::numeric_limits<double>::epsilon()) {
191  vpColVector V3(3);
192  V3[0] = double(rand() % 1000) / 100;
193  V3[1] = double(rand() % 1000) / 100;
194  V3[2] = double(rand() % 1000) / 100;
195 
196  vpColVector v_tmp1, v_tmp2;
197  v_tmp1 = V2 - V1;
198  v_tmp2 = V3 - V1;
199  vpColVector V4 = vpColVector::cross(v_tmp1, v_tmp2);
200 
201  vpPoint P3(V3[0], V3[1], V3[2]);
202  vpPoint P4(V4[0], V4[1], V4[2]);
203  buildLine(*p1, *p2, P3, P4, *line);
204  } else {
205  vpPoint P3(V1[0], V1[1], V1[2]);
206  vpPoint P4(V2[0], V2[1], V2[2]);
207  buildLine(*p1, *p2, P3, P4, *line);
208  }
209 }
210 
216 void vpMbtDistanceLine::addPolygon(const int &idx)
217 {
218  Lindex_polygon.push_back(idx);
219  Lindex_polygon_tracked.push_back(true);
220 }
221 
229 void vpMbtDistanceLine::setTracked(const std::string &polyname, const bool &track)
230 {
231  unsigned int ind = 0;
232  for (std::list<int>::const_iterator itpoly = Lindex_polygon.begin(); itpoly != Lindex_polygon.end(); ++itpoly) {
233  if ((*hiddenface)[(unsigned)(*itpoly)]->getName() == polyname) {
234  Lindex_polygon_tracked[ind] = track;
235  }
236  ind++;
237  }
238 
239  isTrackedLine = false;
240  for (unsigned int i = 0; i < Lindex_polygon_tracked.size(); i++)
241  if (Lindex_polygon_tracked[i]) {
242  isTrackedLine = true;
243  break;
244  }
245 
246  if (!isTrackedLine) {
247  isTrackedLineWithVisibility = false;
248  return;
249  }
250 
251  updateTracked();
252 }
253 
260 {
261  if (!isTrackedLine) {
262  isTrackedLineWithVisibility = false;
263  return;
264  }
265 
266  unsigned int ind = 0;
267  isTrackedLineWithVisibility = false;
268  for (std::list<int>::const_iterator itpoly = Lindex_polygon.begin(); itpoly != Lindex_polygon.end(); ++itpoly) {
269  if ((*hiddenface)[(unsigned)(*itpoly)]->isVisible() && Lindex_polygon_tracked[ind]) {
270  isTrackedLineWithVisibility = true;
271  break;
272  }
273  ind++;
274  }
275 }
276 
283 {
284  me = _me;
285 
286  for (unsigned int i = 0; i < meline.size(); i++)
287  if (meline[i] != NULL) {
288  // nbFeature[i] = 0;
289  meline[i]->reset();
290  meline[i]->setMe(me);
291  }
292 
293  // nbFeatureTotal = 0;
294 }
295 
306 {
307  for (unsigned int i = 0; i < meline.size(); i++) {
308  if (meline[i] != NULL)
309  delete meline[i];
310  }
311 
312  meline.clear();
313  nbFeature.clear();
314  nbFeatureTotal = 0;
315 
316  if (isvisible) {
317  p1->changeFrame(cMo);
318  p2->changeFrame(cMo);
319 
320  if (poly.getClipping() > 3) // Contains at least one FOV constraint
321  cam.computeFov(I.getWidth(), I.getHeight());
322 
323  poly.computePolygonClipped(cam);
324 
325  if (poly.polyClipped.size() == 2) { // Les points sont visibles.
326 
327  std::vector<std::pair<vpPoint, vpPoint> > linesLst;
328 
329  if (useScanLine) {
330  hiddenface->computeScanLineQuery(poly.polyClipped[0].first, poly.polyClipped[1].first, linesLst);
331  } else {
332  linesLst.push_back(std::make_pair(poly.polyClipped[0].first, poly.polyClipped[1].first));
333  }
334 
335  if (linesLst.size() == 0) {
336  // isvisible = false;
337  return false;
338  }
339 
340  // To have the exact same pose values as the old version (angle or ogre
341  // visibility test only), points should be reorganised when using
342  // scanline algorithm.
343  // if(sqrt(vpMath::sqr(poly.polyClipped[0].first.get_X() -
344  // linesLst[0].first.get_X())) >
345  // sqrt(vpMath::sqr(poly.polyClipped[0].first.get_X() -
346  // linesLst[0].second.get_X())))
347  // {
348  // std::vector<std::pair<vpPoint, vpPoint> > linesLstTmp;
349  // for(int i = linesLst.size()-1 ; i >= 0 ; i--)
350  // linesLstTmp.push_back(std::make_pair(linesLst[i].second,linesLst[i].first));
351  // linesLst = linesLstTmp;
352  // }
353 
354  line->changeFrame(cMo);
355  line->projection();
356  double rho, theta;
357  // rho theta uv
359 
360  while (theta > M_PI) {
361  theta -= M_PI;
362  }
363  while (theta < -M_PI) {
364  theta += M_PI;
365  }
366 
367  if (theta < -M_PI / 2.0)
368  theta = -theta - 3 * M_PI / 2.0;
369  else
370  theta = M_PI / 2.0 - theta;
371 
372  for (unsigned int i = 0; i < linesLst.size(); i++) {
373  vpImagePoint ip1, ip2;
374 
375  linesLst[i].first.project();
376  linesLst[i].second.project();
377 
378  vpMeterPixelConversion::convertPoint(cam, linesLst[i].first.get_x(), linesLst[i].first.get_y(), ip1);
379  vpMeterPixelConversion::convertPoint(cam, linesLst[i].second.get_x(), linesLst[i].second.get_y(), ip2);
380 
381  vpMbtMeLine *melinePt = new vpMbtMeLine;
382  melinePt->setMe(me);
383 
384  // meline[i]->setDisplay(vpMeSite::RANGE_RESULT);
385  melinePt->setInitRange(0);
386 
387  int marge = /*10*/ 5; // ou 5 normalement
388  if (ip1.get_j() < ip2.get_j()) {
389  melinePt->jmin = (int)ip1.get_j() - marge;
390  melinePt->jmax = (int)ip2.get_j() + marge;
391  } else {
392  melinePt->jmin = (int)ip2.get_j() - marge;
393  melinePt->jmax = (int)ip1.get_j() + marge;
394  }
395  if (ip1.get_i() < ip2.get_i()) {
396  melinePt->imin = (int)ip1.get_i() - marge;
397  melinePt->imax = (int)ip2.get_i() + marge;
398  } else {
399  melinePt->imin = (int)ip2.get_i() - marge;
400  melinePt->imax = (int)ip1.get_i() + marge;
401  }
402 
403  try {
404  melinePt->initTracking(I, ip1, ip2, rho, theta);
405  meline.push_back(melinePt);
406  // nbFeature.push_back((unsigned int)
407  // melinePt->getMeList().size()); nbFeatureTotal +=
408  // nbFeature.back();
409  } catch (...) {
410  // vpTRACE("the line can't be initialized");
411  delete melinePt;
412  isvisible = false;
413  return false;
414  }
415  }
416  } else {
417  isvisible = false;
418  // return false;
419  }
420  }
421 
422  // trackMovingEdge(I,cMo);
423  return true;
424 }
425 
433 {
434 
435  if (isvisible) {
436  // p1->changeFrame(cMo);
437  // p2->changeFrame(cMo);
438  //
439  // p1->projection();
440  // p2->projection();
441  //
442  // vpImagePoint ip1, ip2;
443  //
444  // vpMeterPixelConversion::convertPoint(*cam,p1->get_x(),p1->get_y(),ip1);
445  // vpMeterPixelConversion::convertPoint(*cam,p2->get_x(),p2->get_y(),ip2);
446  //
447  // int marge = /*10*/5; //ou 5 normalement
448  // if (ip1.get_j()<ip2.get_j()) { meline->jmin = ip1.get_j()-marge ;
449  // meline->jmax = ip2.get_j()+marge ; } else{ meline->jmin =
450  // ip2.get_j()-marge ; meline->jmax = ip1.get_j()+marge ; } if
451  // (ip1.get_i()<ip2.get_i()) { meline->imin = ip1.get_i()-marge ;
452  // meline->imax = ip2.get_i()+marge ; } else{ meline->imin =
453  // ip2.get_i()-marge ; meline->imax = ip1.get_i()+marge ; }
454 
455  try {
456  nbFeature.clear();
457  nbFeatureTotal = 0;
458  for (unsigned int i = 0; i < meline.size(); i++) {
459  meline[i]->track(I);
460  nbFeature.push_back((unsigned int)meline[i]->getMeList().size());
461  nbFeatureTotal += (unsigned int)meline[i]->getMeList().size();
462  }
463  } catch (...) {
464  for (unsigned int i = 0; i < meline.size(); i++) {
465  if (meline[i] != NULL)
466  delete meline[i];
467  }
468 
469  nbFeature.clear();
470  meline.clear();
471  nbFeatureTotal = 0;
472  Reinit = true;
473  isvisible = false;
474  }
475  }
476 }
477 
485 {
486  if (isvisible) {
487  p1->changeFrame(cMo);
488  p2->changeFrame(cMo);
489 
490  if (poly.getClipping() > 3) // Contains at least one FOV constraint
491  cam.computeFov(I.getWidth(), I.getHeight());
492 
493  poly.computePolygonClipped(cam);
494 
495  if (poly.polyClipped.size() == 2) { // Les points sont visibles.
496 
497  std::vector<std::pair<vpPoint, vpPoint> > linesLst;
498 
499  if (useScanLine) {
500  hiddenface->computeScanLineQuery(poly.polyClipped[0].first, poly.polyClipped[1].first, linesLst);
501  } else {
502  linesLst.push_back(std::make_pair(poly.polyClipped[0].first, poly.polyClipped[1].first));
503  }
504 
505  if (linesLst.size() != meline.size() || linesLst.size() == 0) {
506  for (unsigned int i = 0; i < meline.size(); i++) {
507  if (meline[i] != NULL)
508  delete meline[i];
509  }
510 
511  meline.clear();
512  nbFeature.clear();
513  nbFeatureTotal = 0;
514  isvisible = false;
515  Reinit = true;
516  } else {
517 
518  // To have the exact same pose values as the old version (angle or
519  // ogre visibility test only), points should be reorganised when using
520  // scanline algorithm.
521  // if(sqrt(vpMath::sqr(poly.polyClipped[0].first.get_X() -
522  // linesLst[0].first.get_X())) >
523  // sqrt(vpMath::sqr(poly.polyClipped[0].first.get_X() -
524  // linesLst[0].second.get_X())))
525  // {
526  // std::vector<std::pair<vpPoint, vpPoint> > linesLstTmp;
527  // for(int i = linesLst.size()-1 ; i >= 0 ; i--)
528  // linesLstTmp.push_back(std::make_pair(linesLst[i].second,linesLst[i].first));
529  // linesLst = linesLstTmp;
530  // }
531 
532  line->changeFrame(cMo);
533  line->projection();
534  double rho, theta;
535  // rho theta uv
537 
538  while (theta > M_PI) {
539  theta -= M_PI;
540  }
541  while (theta < -M_PI) {
542  theta += M_PI;
543  }
544 
545  if (theta < -M_PI / 2.0)
546  theta = -theta - 3 * M_PI / 2.0;
547  else
548  theta = M_PI / 2.0 - theta;
549 
550  try {
551  for (unsigned int i = 0; i < linesLst.size(); i++) {
552  vpImagePoint ip1, ip2;
553 
554  linesLst[i].first.project();
555  linesLst[i].second.project();
556 
557  vpMeterPixelConversion::convertPoint(cam, linesLst[i].first.get_x(), linesLst[i].first.get_y(), ip1);
558  vpMeterPixelConversion::convertPoint(cam, linesLst[i].second.get_x(), linesLst[i].second.get_y(), ip2);
559 
560  int marge = /*10*/ 5; // ou 5 normalement
561  if (ip1.get_j() < ip2.get_j()) {
562  meline[i]->jmin = (int)ip1.get_j() - marge;
563  meline[i]->jmax = (int)ip2.get_j() + marge;
564  } else {
565  meline[i]->jmin = (int)ip2.get_j() - marge;
566  meline[i]->jmax = (int)ip1.get_j() + marge;
567  }
568  if (ip1.get_i() < ip2.get_i()) {
569  meline[i]->imin = (int)ip1.get_i() - marge;
570  meline[i]->imax = (int)ip2.get_i() + marge;
571  } else {
572  meline[i]->imin = (int)ip2.get_i() - marge;
573  meline[i]->imax = (int)ip1.get_i() + marge;
574  }
575 
576  meline[i]->updateParameters(I, ip1, ip2, rho, theta);
577  nbFeature[i] = (unsigned int)meline[i]->getMeList().size();
579  }
580  } catch (...) {
581  for (unsigned int j = 0; j < meline.size(); j++) {
582  if (meline[j] != NULL)
583  delete meline[j];
584  }
585 
586  meline.clear();
587  nbFeature.clear();
588  nbFeatureTotal = 0;
589  isvisible = false;
590  Reinit = true;
591  }
592  }
593  } else {
594  for (unsigned int i = 0; i < meline.size(); i++) {
595  if (meline[i] != NULL)
596  delete meline[i];
597  }
598  nbFeature.clear();
599  meline.clear();
600  nbFeatureTotal = 0;
601  isvisible = false;
602  }
603  }
604 }
605 
616 {
617  for (unsigned int i = 0; i < meline.size(); i++) {
618  if (meline[i] != NULL)
619  delete meline[i];
620  }
621 
622  nbFeature.clear();
623  meline.clear();
624  nbFeatureTotal = 0;
625 
626  if (initMovingEdge(I, cMo) == false)
627  Reinit = true;
628 
629  Reinit = false;
630 }
631 
644  const vpCameraParameters &camera, const vpColor &col, const unsigned int thickness,
645  const bool displayFullModel)
646 {
647  if ((isvisible && isTrackedLine) || displayFullModel) {
648  p1->changeFrame(cMo);
649  p2->changeFrame(cMo);
650 
651  vpImagePoint ip1, ip2;
652  vpCameraParameters c = camera;
653  if (poly.getClipping() > 3) // Contains at least one FOV constraint
654  c.computeFov(I.getWidth(), I.getHeight());
655 
656  poly.computePolygonClipped(c);
657 
658  if (poly.polyClipped.size() == 2 &&
659  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::NEAR_CLIPPING) == 0) &&
660  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::FAR_CLIPPING) == 0) &&
661  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::DOWN_CLIPPING) == 0) &&
662  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::UP_CLIPPING) == 0) &&
663  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::LEFT_CLIPPING) == 0) &&
664  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::RIGHT_CLIPPING) == 0)) {
665 
666  std::vector<std::pair<vpPoint, vpPoint> > linesLst;
667  if (useScanLine && !displayFullModel) {
668  hiddenface->computeScanLineQuery(poly.polyClipped[0].first, poly.polyClipped[1].first, linesLst, true);
669  } else {
670  linesLst.push_back(std::make_pair(poly.polyClipped[0].first, poly.polyClipped[1].first));
671  }
672 
673  for (unsigned int i = 0; i < linesLst.size(); i++) {
674  linesLst[i].first.project();
675  linesLst[i].second.project();
676 
677  vpMeterPixelConversion::convertPoint(camera, linesLst[i].first.get_x(), linesLst[i].first.get_y(), ip1);
678  vpMeterPixelConversion::convertPoint(camera, linesLst[i].second.get_x(), linesLst[i].second.get_y(), ip2);
679 
680  vpDisplay::displayLine(I, ip1, ip2, col, thickness);
681  }
682  }
683  }
684 }
685 
698  const vpCameraParameters &camera, const vpColor &col, const unsigned int thickness,
699  const bool displayFullModel)
700 {
701  if ((isvisible && isTrackedLine) || displayFullModel) {
702  p1->changeFrame(cMo);
703  p2->changeFrame(cMo);
704 
705  vpImagePoint ip1, ip2;
706  vpCameraParameters c = camera;
707  if (poly.getClipping() > 3) // Contains at least one FOV constraint
708  c.computeFov(I.getWidth(), I.getHeight());
709 
710  poly.computePolygonClipped(c);
711 
712  if (poly.polyClipped.size() == 2 &&
713  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::NEAR_CLIPPING) == 0) &&
714  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::FAR_CLIPPING) == 0) &&
715  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::DOWN_CLIPPING) == 0) &&
716  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::UP_CLIPPING) == 0) &&
717  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::LEFT_CLIPPING) == 0) &&
718  ((poly.polyClipped[1].second & poly.polyClipped[0].second & vpPolygon3D::RIGHT_CLIPPING) == 0)) {
719 
720  std::vector<std::pair<vpPoint, vpPoint> > linesLst;
721  if (useScanLine && !displayFullModel) {
722  hiddenface->computeScanLineQuery(poly.polyClipped[0].first, poly.polyClipped[1].first, linesLst, true);
723  } else {
724  linesLst.push_back(std::make_pair(poly.polyClipped[0].first, poly.polyClipped[1].first));
725  }
726 
727  for (unsigned int i = 0; i < linesLst.size(); i++) {
728  linesLst[i].first.project();
729  linesLst[i].second.project();
730 
731  vpMeterPixelConversion::convertPoint(camera, linesLst[i].first.get_x(), linesLst[i].first.get_y(), ip1);
732  vpMeterPixelConversion::convertPoint(camera, linesLst[i].second.get_x(), linesLst[i].second.get_y(), ip2);
733 
734  vpDisplay::displayLine(I, ip1, ip2, col, thickness);
735  }
736  }
737  }
738 }
739 
755 {
756  for (unsigned int i = 0; i < meline.size(); i++)
757  if (meline[i] != NULL) {
758  meline[i]->display(I);
759  }
760 }
761 
766 {
767  if (isvisible == true) {
768  L.resize(nbFeatureTotal, 6);
770  } else {
771  for (unsigned int i = 0; i < meline.size(); i++) {
772  nbFeature[i] = 0;
773  // To be consistent with nbFeature[i] = 0
774  std::list<vpMeSite> &me_site_list = meline[i]->getMeList();
775  me_site_list.clear();
776  }
777  nbFeatureTotal = 0;
778  }
779 }
780 
786 {
787  if (isvisible) {
788  try {
789  // feature projection
790  line->changeFrame(cMo);
791  line->projection();
792 
793  vpFeatureBuilder::create(featureline, *line);
794 
795  double rho = featureline.getRho();
796  double theta = featureline.getTheta();
797 
798  double co = cos(theta);
799  double si = sin(theta);
800 
801  double mx = 1.0 / cam.get_px();
802  double my = 1.0 / cam.get_py();
803  double xc = cam.get_u0();
804  double yc = cam.get_v0();
805 
806  double alpha_;
807  vpMatrix H = featureline.interaction();
808 
809  double x, y;
810  unsigned int j = 0;
811 
812  for (unsigned int i = 0; i < meline.size(); i++) {
813  for (std::list<vpMeSite>::const_iterator it = meline[i]->getMeList().begin();
814  it != meline[i]->getMeList().end(); ++it) {
815  x = (double)it->j;
816  y = (double)it->i;
817 
818  x = (x - xc) * mx;
819  y = (y - yc) * my;
820 
821  alpha_ = x * si - y * co;
822 
823  double *Lrho = H[0];
824  double *Ltheta = H[1];
825  // Calculate interaction matrix for a distance
826  for (unsigned int k = 0; k < 6; k++) {
827  L[j][k] = (Lrho[k] + alpha_ * Ltheta[k]);
828  }
829  error[j] = rho - (x * co + y * si);
830  j++;
831  }
832  }
833  } catch (const vpException &e) {
834  std::cerr << "Catch an exception: " << e.what() << std::endl;
835  std::cerr << "Set the corresponding interaction matrix part to zero." << std::endl;
836 
837  unsigned int j = 0;
838  for (unsigned int i = 0; i < meline.size(); i++) {
839  for (std::list<vpMeSite>::const_iterator it = meline[i]->getMeList().begin();
840  it != meline[i]->getMeList().end(); ++it) {
841  for (unsigned int k = 0; k < 6; k++) {
842  L[j][k] = 0.0;
843  }
844 
845  error[j] = 0.0;
846  j++;
847  }
848  }
849  }
850  }
851 }
852 
861 bool vpMbtDistanceLine::closeToImageBorder(const vpImage<unsigned char> &I, const unsigned int threshold)
862 {
863  if (threshold > I.getWidth() || threshold > I.getHeight()) {
864  return true;
865  }
866  if (isvisible) {
867 
868  for (unsigned int i = 0; i < meline.size(); i++) {
869  for (std::list<vpMeSite>::const_iterator it = meline[i]->getMeList().begin(); it != meline[i]->getMeList().end();
870  ++it) {
871  int i_ = it->i;
872  int j_ = it->j;
873 
874  if (i_ < 0 || j_ < 0) { // out of image.
875  return true;
876  }
877 
878  if (((unsigned int)i_ > (I.getHeight() - threshold)) || (unsigned int)i_ < threshold ||
879  ((unsigned int)j_ > (I.getWidth() - threshold)) || (unsigned int)j_ < threshold) {
880  return true;
881  }
882  }
883  }
884  }
885  return false;
886 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
void setD(const double d)
Definition: vpPlane.h:88
double get_i() const
Definition: vpImagePoint.h:204
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.cpp:422
virtual void setNbPoint(const unsigned int nb)
unsigned int nbFeatureTotal
The number of moving edges.
vpLine * line
The 3D line.
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
bool Reinit
Indicates if the line has to be reinitialized.
static vpColVector cross(const vpColVector &a, const vpColVector &b)
Definition: vpColVector.h:280
Implementation of an homogeneous matrix and operations on such kind of matrices.
std::list< int > Lindex_polygon
Index of the faces which contain the line.
void setWorldCoordinates(const double &A1, const double &B1, const double &C1, const double &D1, const double &A2, const double &B2, const double &C2, const double &D2)
Definition: vpLine.cpp:85
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Point coordinates conversion from normalized coordinates in meter to pixel coordinates ...
Class to define colors available for display functionnalities.
Definition: vpColor.h:120
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
std::vector< bool > Lindex_polygon_tracked
vpPoint * p1
The first extremity.
void displayMovingEdges(const vpImage< unsigned char > &I)
double getRho() const
error that can be emited by ViSP classes.
Definition: vpException.h:71
vpPoint * p
corners in the object frame
Definition: vpPolygon3D.h:81
Definition: vpMe.h:60
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.cpp:420
bool isvisible
Indicates if the line is visible or not.
Class that defines what is a point.
Definition: vpPoint.h:58
std::vector< std::pair< vpPoint, unsigned int > > polyClipped
Region of interest clipped.
Definition: vpPolygon3D.h:83
void setTracked(const std::string &name, const bool &track)
Class that defines a line in the object frame, the camera frame and the image plane. All the parameters must be set in meter.
Definition: vpLine.h:105
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double getD() const
Definition: vpPlane.h:108
void computePolygonClipped(const vpCameraParameters &cam=vpCameraParameters())
vpPoint * p2
The second extremity.
unsigned int getClipping() const
Definition: vpPolygon3D.h:118
vpColVector error
The error vector.
double getB() const
Definition: vpPlane.h:104
double get_j() const
Definition: vpImagePoint.h:215
void addPoint(const unsigned int n, const vpPoint &P)
Generic class defining intrinsic camera parameters.
double getTheta() const
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.cpp:424
void setA(const double a)
Definition: vpPlane.h:82
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
void projection()
Definition: vpLine.cpp:193
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP)
Definition: vpLine.cpp:333
const char * what() const
void setC(const double c)
Definition: vpPlane.h:86
double getA() const
Definition: vpPlane.h:102
static void convertLine(const vpCameraParameters &cam, const double &rho_m, const double &theta_m, double &rho_p, double &theta_p)
Line coordinates conversion (rho,theta).
bool closeToImageBorder(const vpImage< unsigned char > &I, const unsigned int threshold)
double getTheta() const
Definition: vpLine.h:146
void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector< std::pair< vpPoint, vpPoint > > &lines, const bool &displayResults=false)
unsigned int getHeight() const
Definition: vpImage.h:178
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
void setMovingEdge(vpMe *Me)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
double getRho() const
Definition: vpLine.h:157
void setB(const double b)
Definition: vpPlane.h:84
double getC() const
Definition: vpPlane.h:106
void addPolygon(const int &index)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
std::vector< vpMbtMeLine * > meline
The moving edge container.
This class defines the container for a plane geometrical structure.
Definition: vpPlane.h:58
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &_cP)
Definition: vpPoint.cpp:233
unsigned int getWidth() const
Definition: vpImage.h:229
vpMatrix L
The interaction matrix.
std::vector< unsigned int > nbFeature
The number of moving edges.
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, const unsigned int thickness=1, const bool displayFullModel=false)
bool useScanLine
Use scanline rendering.
void buildFrom(vpPoint &_p1, vpPoint &_p2)
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:241
void computeFov(const unsigned int &w, const unsigned int &h)