Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpMbtDistanceKltCylinder.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 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 https://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  * Klt cylinder, containing points of interest.
33  *
34 *****************************************************************************/
35 
36 #include <visp3/core/vpPolygon.h>
37 #include <visp3/mbt/vpMbtDistanceKltCylinder.h>
38 #include <visp3/mbt/vpMbtDistanceKltPoints.h>
39 
40 #if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
41 
42 #if defined(VISP_HAVE_CLIPPER)
43 #include <clipper.hpp> // clipper private library
44 #endif
45 
46 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
47 #include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IPHONE or TARGET_OS_IOS macro
48 #endif
49 
50 BEGIN_VISP_NAMESPACE
55 vpMbtDistanceKltCylinder::vpMbtDistanceKltCylinder()
56  : c0Mo(), p1Ext(), p2Ext(), cylinder(), circle1(), circle2(), initPoints(), initPoints3D(), curPoints(),
57  curPointsInd(), nbPointsCur(0), nbPointsInit(0), minNbPoint(4), enoughPoints(false), cam(),
58  isTrackedKltCylinder(true), listIndicesCylinderBBox(), hiddenface(nullptr), useScanLine(false)
59 { }
60 
65 vpMbtDistanceKltCylinder::~vpMbtDistanceKltCylinder() { }
66 
67 void vpMbtDistanceKltCylinder::buildFrom(const vpPoint &p1, const vpPoint &p2, const double &r)
68 {
69  p1Ext = p1;
70  p2Ext = p2;
71 
72  vpColVector ABC(3);
73  vpColVector V1(3);
74  vpColVector V2(3);
75 
76  V1[0] = p1.get_oX();
77  V1[1] = p1.get_oY();
78  V1[2] = p1.get_oZ();
79  V2[0] = p2.get_oX();
80  V2[1] = p2.get_oY();
81  V2[2] = p2.get_oZ();
82 
83  // Get the axis of the cylinder
84  ABC = V1 - V2;
85 
86  // Build our extremity circles
87  circle1.setWorldCoordinates(ABC[0], ABC[1], ABC[2], p1.get_oX(), p1.get_oY(), p1.get_oZ(), r);
88  circle2.setWorldCoordinates(ABC[0], ABC[1], ABC[2], p2.get_oX(), p2.get_oY(), p2.get_oZ(), r);
89 
90  // Build our cylinder
91  cylinder.setWorldCoordinates(ABC[0], ABC[1], ABC[2], (p1.get_oX() + p2.get_oX()) / 2.0,
92  (p1.get_oY() + p2.get_oY()) / 2.0, (p1.get_oZ() + p2.get_oZ()) / 2.0, r);
93 }
94 
103 void vpMbtDistanceKltCylinder::init(const vpKltOpencv &_tracker, const vpHomogeneousMatrix &cMo)
104 {
105  c0Mo = cMo;
106  cylinder.changeFrame(cMo);
107 
108  // extract ids of the points in the face
109  nbPointsInit = 0;
110  nbPointsCur = 0;
111  initPoints = std::map<int, vpImagePoint>();
112  initPoints3D = std::map<int, vpPoint>();
113  curPoints = std::map<int, vpImagePoint>();
114  curPointsInd = std::map<int, int>();
115 
116  for (unsigned int i = 0; i < static_cast<unsigned int>(_tracker.getNbFeatures()); i++) {
117  long id;
118  float x_tmp, y_tmp;
119  _tracker.getFeature((int)i, id, x_tmp, y_tmp);
120 
121  bool add = false;
122 
123  if (useScanLine) {
124  if ((unsigned int)y_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getHeight() &&
125  (unsigned int)x_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getWidth()) {
126  for (unsigned int kc = 0; kc < listIndicesCylinderBBox.size(); kc++)
127  if (hiddenface->getMbScanLineRenderer().getPrimitiveIDs()[(unsigned int)y_tmp][(unsigned int)x_tmp] ==
128  listIndicesCylinderBBox[kc]) {
129  add = true;
130  break;
131  }
132  }
133  }
134  else {
135  std::vector<vpImagePoint> roi;
136  for (unsigned int kc = 0; kc < listIndicesCylinderBBox.size(); kc++) {
137  hiddenface->getPolygon()[(size_t)listIndicesCylinderBBox[kc]]->getRoiClipped(cam, roi);
138  if (vpPolygon::isInside(roi, y_tmp, x_tmp)) {
139  add = true;
140  break;
141  }
142  roi.clear();
143  }
144  }
145 
146  if (add) {
147 
148  double xm = 0, ym = 0;
149  vpPixelMeterConversion::convertPoint(cam, x_tmp, y_tmp, xm, ym);
150  double Z = computeZ(xm, ym);
151  if (!vpMath::isNaN(Z)) {
152 #ifdef TARGET_OS_IPHONE
153  initPoints[(int)id] = vpImagePoint(y_tmp, x_tmp);
154  curPoints[(int)id] = vpImagePoint(y_tmp, x_tmp);
155  curPointsInd[(int)id] = (int)i;
156 #else
157  initPoints[id] = vpImagePoint(y_tmp, x_tmp);
158  curPoints[id] = vpImagePoint(y_tmp, x_tmp);
159  curPointsInd[id] = (int)i;
160 #endif
161  nbPointsInit++;
162  nbPointsCur++;
163 
164  vpPoint p;
165  p.setWorldCoordinates(xm * Z, ym * Z, Z);
166 #ifdef TARGET_OS_IPHONE
167  initPoints3D[(int)id] = p;
168 #else
169  initPoints3D[id] = p;
170 #endif
171  // std::cout << "Computed Z for : " << xm << "," << ym << " : " <<
172  // computeZ(xm,ym) << std::endl;
173  }
174  }
175  }
176 
177  if (nbPointsCur >= minNbPoint)
178  enoughPoints = true;
179  else
180  enoughPoints = false;
181 
182  // std::cout << "Nb detected points in cylinder : " << nbPointsCur <<
183  // std::endl;
184 }
185 
194 unsigned int vpMbtDistanceKltCylinder::computeNbDetectedCurrent(const vpKltOpencv &_tracker)
195 {
196  long id;
197  float x, y;
198  nbPointsCur = 0;
199  curPoints = std::map<int, vpImagePoint>();
200  curPointsInd = std::map<int, int>();
201 
202  for (unsigned int i = 0; i < static_cast<unsigned int>(_tracker.getNbFeatures()); i++) {
203  _tracker.getFeature((int)i, id, x, y);
204  if (isTrackedFeature((int)id)) {
205 #ifdef TARGET_OS_IPHONE
206  curPoints[(int)id] = vpImagePoint(static_cast<double>(y), static_cast<double>(x));
207  curPointsInd[(int)id] = (int)i;
208 #else
209  curPoints[id] = vpImagePoint(static_cast<double>(y), static_cast<double>(x));
210  curPointsInd[id] = (int)i;
211 #endif
212  nbPointsCur++;
213  }
214  }
215 
216  if (nbPointsCur >= minNbPoint)
217  enoughPoints = true;
218  else
219  enoughPoints = false;
220 
221  return nbPointsCur;
222 }
223 
232 void vpMbtDistanceKltCylinder::removeOutliers(const vpColVector &_w, const double &threshold_outlier)
233 {
234  std::map<int, vpImagePoint> tmp;
235  std::map<int, int> tmp2;
236  unsigned int nbSupp = 0;
237  unsigned int k = 0;
238 
239  nbPointsCur = 0;
240  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
241  for (; iter != curPoints.end(); ++iter) {
242  if (_w[k] > threshold_outlier && _w[k + 1] > threshold_outlier) {
243  // if(_w[k] > threshold_outlier || _w[k+1] > threshold_outlier){
244  tmp[iter->first] = vpImagePoint(iter->second.get_i(), iter->second.get_j());
245  tmp2[iter->first] = curPointsInd[iter->first];
246  nbPointsCur++;
247  }
248  else {
249  nbSupp++;
250  initPoints.erase(iter->first);
251  }
252 
253  k += 2;
254  }
255 
256  if (nbSupp != 0) {
257  curPoints = std::map<int, vpImagePoint>();
258  curPointsInd = std::map<int, int>();
259 
260  curPoints = tmp;
261  curPointsInd = tmp2;
262  if (nbPointsCur >= minNbPoint)
263  enoughPoints = true;
264  else
265  enoughPoints = false;
266  }
267 }
268 
280 void vpMbtDistanceKltCylinder::computeInteractionMatrixAndResidu(const vpHomogeneousMatrix &_cMc0, vpColVector &_R,
281  vpMatrix &_J)
282 {
283  unsigned int index_ = 0;
284 
285  cylinder.changeFrame(_cMc0 * c0Mo);
286 
287  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
288  for (; iter != curPoints.end(); ++iter) {
289  int id(iter->first);
290  double i_cur(iter->second.get_i()), j_cur(iter->second.get_j());
291 
292  double x_cur(0), y_cur(0);
293  vpPixelMeterConversion::convertPoint(cam, j_cur, i_cur, x_cur, y_cur);
294 
295  vpPoint p0 = initPoints3D[id];
296  p0.changeFrame(_cMc0);
297  p0.project();
298 
299  double x0_transform(p0.get_x()), y0_transform(p0.get_y());
300 
301  double Z = computeZ(x_cur, y_cur);
302 
303  if (vpMath::isNaN(Z) || Z < std::numeric_limits<double>::epsilon()) {
304  // std::cout << "Z is Nan : " << A << " , " << B << " , " << C << "
305  // | " << Z << " | " << x_cur << " , " << y_cur << std::endl;
306  // std::cout << std::sqrt(B*B - A*C) << " , " << B*B - A*C <<
307  // std::endl;
308 
309  _J[2 * index_][0] = 0;
310  _J[2 * index_][1] = 0;
311  _J[2 * index_][2] = 0;
312  _J[2 * index_][3] = 0;
313  _J[2 * index_][4] = 0;
314  _J[2 * index_][5] = 0;
315 
316  _J[2 * index_ + 1][0] = 0;
317  _J[2 * index_ + 1][1] = 0;
318  _J[2 * index_ + 1][2] = 0;
319  _J[2 * index_ + 1][3] = 0;
320  _J[2 * index_ + 1][4] = 0;
321  _J[2 * index_ + 1][5] = 0;
322 
323  _R[2 * index_] = (x0_transform - x_cur);
324  _R[2 * index_ + 1] = (y0_transform - y_cur);
325  index_++;
326  }
327  else {
328  double invZ = 1.0 / Z;
329 
330  _J[2 * index_][0] = -invZ;
331  _J[2 * index_][1] = 0;
332  _J[2 * index_][2] = x_cur * invZ;
333  _J[2 * index_][3] = x_cur * y_cur;
334  _J[2 * index_][4] = -(1 + x_cur * x_cur);
335  _J[2 * index_][5] = y_cur;
336 
337  _J[2 * index_ + 1][0] = 0;
338  _J[2 * index_ + 1][1] = -invZ;
339  _J[2 * index_ + 1][2] = y_cur * invZ;
340  _J[2 * index_ + 1][3] = (1 + y_cur * y_cur);
341  _J[2 * index_ + 1][4] = -y_cur * x_cur;
342  _J[2 * index_ + 1][5] = -x_cur;
343 
344  _R[2 * index_] = (x0_transform - x_cur);
345  _R[2 * index_ + 1] = (y0_transform - y_cur);
346  index_++;
347  }
348  }
349 }
350 
358 bool vpMbtDistanceKltCylinder::isTrackedFeature(int _id)
359 {
360  std::map<int, vpImagePoint>::iterator iter = initPoints.find(_id);
361  if (iter != initPoints.end())
362  return true;
363 
364  return false;
365 }
366 
376 void vpMbtDistanceKltCylinder::updateMask(
377  cv::Mat &mask,
378  unsigned char nb, unsigned int shiftBorder)
379 {
380  int width = mask.cols;
381  int height = mask.rows;
382 
383  for (unsigned int kc = 0; kc < listIndicesCylinderBBox.size(); kc++) {
384  if ((*hiddenface)[(unsigned int)listIndicesCylinderBBox[kc]]->isVisible() &&
385  (*hiddenface)[(unsigned int)listIndicesCylinderBBox[kc]]->getNbPoint() > 2) {
386  int i_min, i_max, j_min, j_max;
387  std::vector<vpImagePoint> roi;
388  (*hiddenface)[(unsigned int)listIndicesCylinderBBox[kc]]->getRoiClipped(cam, roi);
389 
390  double shiftBorder_d = (double)shiftBorder;
391 #if defined(VISP_HAVE_CLIPPER)
392  std::vector<vpImagePoint> roi_offset;
393 
394  ClipperLib::Path path;
395  for (std::vector<vpImagePoint>::const_iterator it = roi.begin(); it != roi.end(); ++it) {
396  path.push_back(ClipperLib::IntPoint((ClipperLib::cInt)it->get_u(), (ClipperLib::cInt)it->get_v()));
397  }
398 
399  ClipperLib::Paths solution;
400  ClipperLib::ClipperOffset co;
401  co.AddPath(path, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
402  co.Execute(solution, -shiftBorder_d);
403 
404  // Keep biggest polygon by area
405  if (!solution.empty()) {
406  size_t index_max = 0;
407 
408  if (solution.size() > 1) {
409  double max_area = 0;
410  vpPolygon polygon_area;
411 
412  for (size_t i = 0; i < solution.size(); i++) {
413  std::vector<vpImagePoint> corners;
414 
415  for (size_t j = 0; j < solution[i].size(); j++) {
416  corners.push_back(vpImagePoint((double)(solution[i][j].Y), (double)(solution[i][j].X)));
417  }
418 
419  polygon_area.buildFrom(corners);
420  if (polygon_area.getArea() > max_area) {
421  max_area = polygon_area.getArea();
422  index_max = i;
423  }
424  }
425  }
426 
427  for (size_t i = 0; i < solution[index_max].size(); i++) {
428  roi_offset.push_back(vpImagePoint((double)(solution[index_max][i].Y), (double)(solution[index_max][i].X)));
429  }
430  }
431  else {
432  roi_offset = roi;
433  }
434 
435  vpPolygon polygon_test(roi_offset);
436  vpImagePoint imPt;
437 #endif
438 
439 #if defined(VISP_HAVE_CLIPPER)
440  vpPolygon3D::getMinMaxRoi(roi_offset, i_min, i_max, j_min, j_max);
441 #else
442  vpPolygon3D::getMinMaxRoi(roi, i_min, i_max, j_min, j_max);
443 #endif
444 
445  /* check image boundaries */
446  if (i_min > height) { // underflow
447  i_min = 0;
448  }
449  if (i_max > height) {
450  i_max = height;
451  }
452  if (j_min > width) { // underflow
453  j_min = 0;
454  }
455  if (j_max > width) {
456  j_max = width;
457  }
458 
459  for (int i = i_min; i < i_max; i++) {
460  double i_d = (double)i;
461 
462  for (int j = j_min; j < j_max; j++) {
463  double j_d = (double)j;
464 
465 #if defined(VISP_HAVE_CLIPPER)
466  imPt.set_ij(i_d, j_d);
467  if (polygon_test.isInside(imPt)) {
468  mask.ptr<uchar>(i)[j] = nb;
469  }
470 #else
471  if (shiftBorder != 0) {
472  if (vpPolygon::isInside(roi, i_d, j_d) &&
473  vpPolygon::isInside(roi, i_d + shiftBorder_d, j_d + shiftBorder_d) &&
474  vpPolygon::isInside(roi, i_d - shiftBorder_d, j_d + shiftBorder_d) &&
475  vpPolygon::isInside(roi, i_d + shiftBorder_d, j_d - shiftBorder_d) &&
476  vpPolygon::isInside(roi, i_d - shiftBorder_d, j_d - shiftBorder_d)) {
477  mask.at<unsigned char>(i, j) = nb;
478  }
479  }
480  else {
481  if (vpPolygon::isInside(roi, i, j)) {
482  mask.at<unsigned char>(i, j) = nb;
483  }
484  }
485 #endif
486  }
487  }
488  }
489  }
490 }
491 
497 void vpMbtDistanceKltCylinder::displayPrimitive(const vpImage<unsigned char> &_I)
498 {
499  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
500  for (; iter != curPoints.end(); ++iter) {
501  int id(iter->first);
502  vpImagePoint iP;
503  iP.set_i(static_cast<double>(iter->second.get_i()));
504  iP.set_j(static_cast<double>(iter->second.get_j()));
505 
507 
508  iP.set_i(vpMath::round(iP.get_i() + 7));
509  iP.set_j(vpMath::round(iP.get_j() + 7));
510  std::stringstream ss;
511  ss << id;
512  vpDisplay::displayText(_I, iP, ss.str(), vpColor::red);
513  }
514 }
515 
521 void vpMbtDistanceKltCylinder::displayPrimitive(const vpImage<vpRGBa> &_I)
522 {
523  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
524  for (; iter != curPoints.end(); ++iter) {
525  int id(iter->first);
526  vpImagePoint iP;
527  iP.set_i(static_cast<double>(iter->second.get_i()));
528  iP.set_j(static_cast<double>(iter->second.get_j()));
529 
531 
532  iP.set_i(vpMath::round(iP.get_i() + 7));
533  iP.set_j(vpMath::round(iP.get_j() + 7));
534  std::stringstream ss;
535  ss << id;
536  vpDisplay::displayText(_I, iP, ss.str(), vpColor::red);
537  }
538 }
539 
540 void vpMbtDistanceKltCylinder::display(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo,
541  const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
542  const bool /*displayFullModel*/)
543 {
544  std::vector<std::vector<double> > models = getModelForDisplay(cMo, camera);
545 
546  for (size_t i = 0; i < models.size(); i++) {
547  vpImagePoint ip1(models[i][1], models[i][2]);
548  vpImagePoint ip2(models[i][3], models[i][4]);
549  vpDisplay::displayLine(I, ip1, ip2, col, thickness);
550  }
551 }
552 
553 void vpMbtDistanceKltCylinder::display(const vpImage<vpRGBa> &I, const vpHomogeneousMatrix &cMo,
554  const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
555  const bool /*displayFullModel*/)
556 {
557  std::vector<std::vector<double> > models = getModelForDisplay(cMo, camera);
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 
572 std::vector<std::vector<double> > vpMbtDistanceKltCylinder::getFeaturesForDisplay()
573 {
574  std::vector<std::vector<double> > features;
575 
576  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
577  for (; iter != curPoints.end(); ++iter) {
578  int id(iter->first);
579  vpImagePoint iP;
580  iP.set_i(static_cast<double>(iter->second.get_i()));
581  iP.set_j(static_cast<double>(iter->second.get_j()));
582 
583  vpImagePoint iP2;
584  iP2.set_i(vpMath::round(iP.get_i() + 7));
585  iP2.set_j(vpMath::round(iP.get_j() + 7));
586 
587  std::vector<double> params = { 1, // KLT
588  iP.get_i(), iP.get_j(), iP2.get_i(), iP2.get_j(), static_cast<double>(id) };
589 
590  features.push_back(params);
591  }
592 
593  return features;
594 }
595 
604 std::vector<std::vector<double> > vpMbtDistanceKltCylinder::getModelForDisplay(const vpHomogeneousMatrix &cMo,
605  const vpCameraParameters &camera)
606 {
607  std::vector<std::vector<double> > models;
608 
609  // if(isvisible || displayFullModel)
610  {
611  // Perspective projection
612  circle1.changeFrame(cMo);
613  circle2.changeFrame(cMo);
614  cylinder.changeFrame(cMo);
615 
616  try {
617  circle1.projection();
618  }
619  catch (...) {
620  std::cout << "Problem projection circle 1";
621  }
622  try {
623  circle2.projection();
624  }
625  catch (...) {
626  std::cout << "Problem projection circle 2";
627  }
628 
629  cylinder.projection();
630 
631  double rho1, theta1;
632  double rho2, theta2;
633 
634  // Meters to pixels conversion
635  vpMeterPixelConversion::convertLine(camera, cylinder.getRho1(), cylinder.getTheta1(), rho1, theta1);
636  vpMeterPixelConversion::convertLine(camera, cylinder.getRho2(), cylinder.getTheta2(), rho2, theta2);
637 
638  // Determine intersections between circles and limbos
639  double i11, i12, i21, i22, j11, j12, j21, j22;
640 
641  vpCircle::computeIntersectionPoint(circle1, camera, rho1, theta1, i11, j11);
642  vpCircle::computeIntersectionPoint(circle2, camera, rho1, theta1, i12, j12);
643 
644  vpCircle::computeIntersectionPoint(circle1, camera, rho2, theta2, i21, j21);
645  vpCircle::computeIntersectionPoint(circle2, camera, rho2, theta2, i22, j22);
646 
647  // Create the image points
648  vpImagePoint ip11, ip12, ip21, ip22;
649  ip11.set_ij(i11, j11);
650  ip12.set_ij(i12, j12);
651  ip21.set_ij(i21, j21);
652  ip22.set_ij(i22, j22);
653 
654  std::vector<double> params1 = { 0, // line parameters
655  ip11.get_i(), ip11.get_j(), ip12.get_i(), ip12.get_j() };
656  models.push_back(params1);
657 
658  std::vector<double> params2 = { 0, // line parameters
659  ip21.get_i(), ip21.get_j(), ip22.get_i(), ip22.get_j() };
660 
661  models.push_back(params1);
662  models.push_back(params2);
663  }
664 
665  return models;
666 }
667 
668 // ######################
669 // Private Functions
670 // ######################
671 
672 double vpMbtDistanceKltCylinder::computeZ(const double &x, const double &y)
673 {
674  // double A = x*x + y*y + 1 -
675  // ((cylinder.getA()*x+cylinder.getB()*y+cylinder.getC()) *
676  // (cylinder.getA()*x+cylinder.getB()*y+cylinder.getC())); double B = (x *
677  // cylinder.getX() + y * cylinder.getY() + cylinder.getZ()); double C =
678  // cylinder.getX() * cylinder.getX() + cylinder.getY() * cylinder.getY() +
679  // cylinder.getZ() * cylinder.getZ() - cylinder.getR() * cylinder.getR();
680  //
681  // return (B - std::sqrt(B*B - A*C))/A;
682 
683  return cylinder.computeZ(x, y);
684 }
685 END_VISP_NAMESPACE
686 #elif !defined(VISP_BUILD_SHARED_LIBS)
687 // Work around to avoid warning:
688 // libvisp_mbt.a(vpMbtDistanceKltCylinder.cpp.o) has no symbols
689 void dummy_vpMbtDistanceKltCylinder() { };
690 #endif
Generic class defining intrinsic camera parameters.
static void computeIntersectionPoint(const vpCircle &circle, const vpCameraParameters &cam, const double &rho, const double &theta, double &i, double &j)
Definition: vpCircle.cpp:446
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
static const vpColor red
Definition: vpColor.h:217
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 displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
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 ...
Definition: vpImagePoint.h:82
void set_j(double jj)
Definition: vpImagePoint.h:309
double get_j() const
Definition: vpImagePoint.h:125
void set_ij(double ii, double jj)
Definition: vpImagePoint.h:320
void set_i(double ii)
Definition: vpImagePoint.h:298
double get_i() const
Definition: vpImagePoint.h:114
Wrapper for the KLT (Kanade-Lucas-Tomasi) feature tracker implemented in OpenCV. Thus to enable this ...
Definition: vpKltOpencv.h:74
int getNbFeatures() const
Get the number of current features.
Definition: vpKltOpencv.h:198
void getFeature(const int &index, long &id, float &x, float &y) const
static bool isNaN(double value)
Definition: vpMath.cpp:92
static int round(double x)
Definition: vpMath.h:410
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
static void convertLine(const vpCameraParameters &cam, const double &rho_m, const double &theta_m, double &rho_p, double &theta_p)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
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:411
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.cpp:422
double get_oZ() const
Get the point oZ coordinate in the object frame.
Definition: vpPoint.cpp:415
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.cpp:420
double get_oY() const
Get the point oY coordinate in the object frame.
Definition: vpPoint.cpp:413
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const VP_OVERRIDE
Definition: vpPoint.cpp:267
void setWorldCoordinates(double oX, double oY, double oZ)
Definition: vpPoint.cpp:111
static void getMinMaxRoi(const std::vector< vpImagePoint > &roi, int &i_min, int &i_max, int &j_min, int &j_max)
Defines a generic 2D polygon.
Definition: vpPolygon.h:103
vpPolygon & buildFrom(const std::vector< vpImagePoint > &corners, const bool &create_convex_hull=false)
Definition: vpPolygon.cpp:193
double getArea() const
Definition: vpPolygon.h:148
bool isInside(const vpImagePoint &iP, const PointInPolygonMethod &method=PnPolyRayCasting) const
Definition: vpPolygon.cpp:400