Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpMbtDistanceKltPoints.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 polygon, containing points of interest.
33  *
34 *****************************************************************************/
35 
36 #include <visp3/core/vpPolygon.h>
37 #include <visp3/mbt/vpMbtDistanceKltPoints.h>
38 #include <visp3/me/vpMeTracker.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 
56  : H(), N(), N_cur(), invd0(1.), cRc0_0n(), initPoints(std::map<int, vpImagePoint>()),
57  curPoints(std::map<int, vpImagePoint>()), curPointsInd(std::map<int, int>()), nbPointsCur(0), nbPointsInit(0),
58  minNbPoint(4), enoughPoints(false), dt(1.), d0(1.), cam(), isTrackedKltPoints(true), polygon(nullptr),
59  hiddenface(nullptr), useScanLine(false)
60 { }
61 
67 
77 void vpMbtDistanceKltPoints::init(const vpKltOpencv &_tracker, const vpImage<bool> *mask)
78 {
79  // extract ids of the points in the face
80  nbPointsInit = 0;
81  nbPointsCur = 0;
82  initPoints = std::map<int, vpImagePoint>();
83  curPoints = std::map<int, vpImagePoint>();
84  curPointsInd = std::map<int, int>();
85  std::vector<vpImagePoint> roi;
86  polygon->getRoiClipped(cam, roi);
87 
88  for (unsigned int i = 0; i < static_cast<unsigned int>(_tracker.getNbFeatures()); i++) {
89  long id;
90  float x_tmp, y_tmp;
91  _tracker.getFeature((int)i, id, x_tmp, y_tmp);
92 
93  bool add = false;
94 
95  // Add points inside visibility mask only
96  if (vpMeTracker::inRoiMask(mask, (unsigned int)y_tmp, (unsigned int)x_tmp)) {
97  if (useScanLine) {
98  if ((unsigned int)y_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getHeight() &&
99  (unsigned int)x_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getWidth() &&
100  hiddenface->getMbScanLineRenderer().getPrimitiveIDs()[(unsigned int)y_tmp][(unsigned int)x_tmp] ==
101  polygon->getIndex())
102  add = true;
103  }
104  else if (vpPolygon::isInside(roi, y_tmp, x_tmp)) {
105  add = true;
106  }
107  }
108 
109  if (add) {
110 #ifdef TARGET_OS_IPHONE
111  initPoints[(int)id] = vpImagePoint(y_tmp, x_tmp);
112  curPoints[(int)id] = vpImagePoint(y_tmp, x_tmp);
113  curPointsInd[(int)id] = (int)i;
114 #else
115  initPoints[id] = vpImagePoint(y_tmp, x_tmp);
116  curPoints[id] = vpImagePoint(y_tmp, x_tmp);
117  curPointsInd[id] = (int)i;
118 #endif
119  }
120  }
121 
122  nbPointsInit = (unsigned int)initPoints.size();
123  nbPointsCur = (unsigned int)curPoints.size();
124 
125  if (nbPointsCur >= minNbPoint)
126  enoughPoints = true;
127  else
128  enoughPoints = false;
129 
130  // initialisation of the value for the computation in SE3
132 
133  d0 = plan.getD();
134  N = plan.getNormal();
135 
136  N.normalize();
137  N_cur = N;
138  invd0 = 1.0 / d0;
139 }
140 
152 {
153  long id;
154  float x, y;
155  nbPointsCur = 0;
156  curPoints = std::map<int, vpImagePoint>();
157  curPointsInd = std::map<int, int>();
158 
159  for (unsigned int i = 0; i < static_cast<unsigned int>(_tracker.getNbFeatures()); i++) {
160  _tracker.getFeature((int)i, id, x, y);
161  if (isTrackedFeature((int)id) && vpMeTracker::inRoiMask(mask, (unsigned int)y, (unsigned int)x)) {
162 #ifdef TARGET_OS_IPHONE
163  curPoints[(int)id] = vpImagePoint(static_cast<double>(y), static_cast<double>(x));
164  curPointsInd[(int)id] = (int)i;
165 #else
166  curPoints[id] = vpImagePoint(static_cast<double>(y), static_cast<double>(x));
167  curPointsInd[id] = (int)i;
168 #endif
169  }
170  }
171 
172  nbPointsCur = (unsigned int)curPoints.size();
173 
174  if (nbPointsCur >= minNbPoint)
175  enoughPoints = true;
176  else
177  enoughPoints = false;
178 
179  return nbPointsCur;
180 }
181 
193 {
194  unsigned int index_ = 0;
195 
196  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
197  for (; iter != curPoints.end(); ++iter) {
198  int id(iter->first);
199  double i_cur(iter->second.get_i()), j_cur(iter->second.get_j());
200 
201  double x_cur(0), y_cur(0);
202  vpPixelMeterConversion::convertPoint(cam, j_cur, i_cur, x_cur, y_cur);
203 
204  vpImagePoint iP0 = initPoints[id];
205  double x0(0), y0(0);
206  vpPixelMeterConversion::convertPoint(cam, iP0, x0, y0);
207 
208  double x0_transform,
209  y0_transform; // equivalent x and y in the first image (reference)
210  computeP_mu_t(x0, y0, x0_transform, y0_transform, H);
211 
212  double invZ = compute_1_over_Z(x_cur, y_cur);
213 
214  _J[2 * index_][0] = -invZ;
215  _J[2 * index_][1] = 0;
216  _J[2 * index_][2] = x_cur * invZ;
217  _J[2 * index_][3] = x_cur * y_cur;
218  _J[2 * index_][4] = -(1 + x_cur * x_cur);
219  _J[2 * index_][5] = y_cur;
220 
221  _J[2 * index_ + 1][0] = 0;
222  _J[2 * index_ + 1][1] = -invZ;
223  _J[2 * index_ + 1][2] = y_cur * invZ;
224  _J[2 * index_ + 1][3] = (1 + y_cur * y_cur);
225  _J[2 * index_ + 1][4] = -y_cur * x_cur;
226  _J[2 * index_ + 1][5] = -x_cur;
227 
228  _R[2 * index_] = (x0_transform - x_cur);
229  _R[2 * index_ + 1] = (y0_transform - y_cur);
230  index_++;
231  }
232 }
233 
234 double vpMbtDistanceKltPoints::compute_1_over_Z(double x, double y)
235 {
236  double num = cRc0_0n[0] * x + cRc0_0n[1] * y + cRc0_0n[2];
237  double den = -(d0 - dt);
238  return num / den;
239 }
240 
253 inline void vpMbtDistanceKltPoints::computeP_mu_t(double x_in, double y_in, double &x_out, double &y_out,
254  const vpMatrix &_cHc0)
255 {
256  double p_mu_t_2 = x_in * _cHc0[2][0] + y_in * _cHc0[2][1] + _cHc0[2][2];
257 
258  if (fabs(p_mu_t_2) < std::numeric_limits<double>::epsilon()) {
259  x_out = 0.0;
260  y_out = 0.0;
261  throw vpException(vpException::divideByZeroError, "the depth of the point is calculated to zero");
262  }
263 
264  x_out = (x_in * _cHc0[0][0] + y_in * _cHc0[0][1] + _cHc0[0][2]) / p_mu_t_2;
265  y_out = (x_in * _cHc0[1][0] + y_in * _cHc0[1][1] + _cHc0[1][2]) / p_mu_t_2;
266 }
267 
282 {
283  vpRotationMatrix cRc0;
284  vpTranslationVector ctransc0;
285 
286  _cTc0.extract(cRc0);
287  _cTc0.extract(ctransc0);
288  vpMatrix cHc0 = _cHc0.convert();
289 
290  // vpGEMM(cRc0, 1.0, invd0, cRc0, -1.0, _cHc0, VP_GEMM_A_T);
291  vpGEMM(ctransc0, N, -invd0, cRc0, 1.0, cHc0, VP_GEMM_B_T);
292  cHc0 /= cHc0[2][2];
293 
294  H = cHc0;
295 
296  // vpQuaternionVector NQuat(N[0], N[1], N[2], 0.0);
297  // vpQuaternionVector RotQuat(cRc0);
298  // vpQuaternionVector RotQuatConj(-RotQuat.x(), -RotQuat.y(),
299  // -RotQuat.z(), RotQuat.w()); vpQuaternionVector partial = RotQuat *
300  // NQuat; vpQuaternionVector resQuat = (partial * RotQuatConj);
301  //
302  // cRc0_0n = vpColVector(3);
303  // cRc0_0n[0] = resQuat.x();
304  // cRc0_0n[1] = resQuat.y();
305  // cRc0_0n[2] = resQuat.z();
306 
307  cRc0_0n = cRc0 * N;
308 
309  // vpPlane p(corners[0], corners[1], corners[2]);
310  // vpColVector Ncur = p.getNormal();
311  // Ncur.normalize();
312  N_cur = cRc0_0n;
313  dt = 0.0;
314  for (unsigned int i = 0; i < 3; i += 1) {
315  dt += ctransc0[i] * (N_cur[i]);
316  }
317 }
318 
326 bool vpMbtDistanceKltPoints::isTrackedFeature(int _id)
327 {
328  // std::map<int, vpImagePoint>::const_iterator iter = initPoints.begin();
329  // while(iter != initPoints.end()){
330  // if(iter->first == _id){
331  // return true;
332  // }
333  // iter++;
334  // }
335 
336  std::map<int, vpImagePoint>::iterator iter = initPoints.find(_id);
337  if (iter != initPoints.end())
338  return true;
339 
340  return false;
341 }
342 
353  cv::Mat &mask,
354  unsigned char nb, unsigned int shiftBorder)
355 {
356  int width = mask.cols;
357  int height = mask.rows;
358 
359  int i_min, i_max, j_min, j_max;
360  std::vector<vpImagePoint> roi;
361  polygon->getRoiClipped(cam, roi);
362 
363  double shiftBorder_d = (double)shiftBorder;
364 
365 #if defined(VISP_HAVE_CLIPPER)
366  std::vector<vpImagePoint> roi_offset;
367 
368  ClipperLib::Path path;
369  for (std::vector<vpImagePoint>::const_iterator it = roi.begin(); it != roi.end(); ++it) {
370  path.push_back(ClipperLib::IntPoint((ClipperLib::cInt)it->get_u(), (ClipperLib::cInt)it->get_v()));
371  }
372 
373  ClipperLib::Paths solution;
374  ClipperLib::ClipperOffset co;
375  co.AddPath(path, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
376  co.Execute(solution, -shiftBorder_d);
377 
378  // Keep biggest polygon by area
379  if (!solution.empty()) {
380  size_t index_max = 0;
381 
382  if (solution.size() > 1) {
383  double max_area = 0;
384  vpPolygon polygon_area;
385 
386  for (size_t i = 0; i < solution.size(); i++) {
387  std::vector<vpImagePoint> corners;
388 
389  for (size_t j = 0; j < solution[i].size(); j++) {
390  corners.push_back(vpImagePoint((double)(solution[i][j].Y), (double)(solution[i][j].X)));
391  }
392 
393  polygon_area.build(corners);
394  if (polygon_area.getArea() > max_area) {
395  max_area = polygon_area.getArea();
396  index_max = i;
397  }
398  }
399  }
400 
401  for (size_t i = 0; i < solution[index_max].size(); i++) {
402  roi_offset.push_back(vpImagePoint((double)(solution[index_max][i].Y), (double)(solution[index_max][i].X)));
403  }
404  }
405  else {
406  roi_offset = roi;
407  }
408 
409  vpPolygon polygon_test(roi_offset);
410  vpImagePoint imPt;
411 #endif
412 
413 #if defined(VISP_HAVE_CLIPPER)
414  vpPolygon3D::getMinMaxRoi(roi_offset, i_min, i_max, j_min, j_max);
415 #else
416  vpPolygon3D::getMinMaxRoi(roi, i_min, i_max, j_min, j_max);
417 #endif
418 
419  /* check image boundaries */
420  if (i_min > height) { // underflow
421  i_min = 0;
422  }
423  if (i_max > height) {
424  i_max = height;
425  }
426  if (j_min > width) { // underflow
427  j_min = 0;
428  }
429  if (j_max > width) {
430  j_max = width;
431  }
432 
433  for (int i = i_min; i < i_max; i++) {
434  double i_d = (double)i;
435 
436  for (int j = j_min; j < j_max; j++) {
437  double j_d = (double)j;
438 
439 #if defined(VISP_HAVE_CLIPPER)
440  imPt.set_ij(i_d, j_d);
441  if (polygon_test.isInside(imPt)) {
442  mask.ptr<uchar>(i)[j] = nb;
443  }
444 #else
445  if (shiftBorder != 0) {
446  if (vpPolygon::isInside(roi, i_d, j_d) && vpPolygon::isInside(roi, i_d + shiftBorder_d, j_d + shiftBorder_d) &&
447  vpPolygon::isInside(roi, i_d - shiftBorder_d, j_d + shiftBorder_d) &&
448  vpPolygon::isInside(roi, i_d + shiftBorder_d, j_d - shiftBorder_d) &&
449  vpPolygon::isInside(roi, i_d - shiftBorder_d, j_d - shiftBorder_d)) {
450  mask.at<unsigned char>(i, j) = nb;
451  }
452  }
453  else {
454  if (vpPolygon::isInside(roi, i, j)) {
455  mask.at<unsigned char>(i, j) = nb;
456  }
457  }
458 #endif
459  }
460  }
461 }
462 
471 void vpMbtDistanceKltPoints::removeOutliers(const vpColVector &_w, const double &threshold_outlier)
472 {
473  std::map<int, vpImagePoint> tmp;
474  std::map<int, int> tmp2;
475  unsigned int nbSupp = 0;
476  unsigned int k = 0;
477 
478  nbPointsCur = 0;
479  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
480  for (; iter != curPoints.end(); ++iter) {
481  if (_w[k] > threshold_outlier && _w[k + 1] > threshold_outlier) {
482  // if(_w[k] > threshold_outlier || _w[k+1] > threshold_outlier){
483  tmp[iter->first] = vpImagePoint(iter->second.get_i(), iter->second.get_j());
484  tmp2[iter->first] = curPointsInd[iter->first];
485  nbPointsCur++;
486  }
487  else {
488  nbSupp++;
489  initPoints.erase(iter->first);
490  }
491 
492  k += 2;
493  }
494 
495  if (nbSupp != 0) {
496  curPoints = tmp;
497  curPointsInd = tmp2;
498  if (nbPointsCur >= minNbPoint)
499  enoughPoints = true;
500  else
501  enoughPoints = false;
502  }
503 }
504 
511 {
512  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
513  for (; iter != curPoints.end(); ++iter) {
514  int id(iter->first);
515  vpImagePoint iP;
516  iP.set_i(static_cast<double>(iter->second.get_i()));
517  iP.set_j(static_cast<double>(iter->second.get_j()));
518 
520 
521  iP.set_i(vpMath::round(iP.get_i() + 7));
522  iP.set_j(vpMath::round(iP.get_j() + 7));
523  std::stringstream ss;
524  ss << id;
525  vpDisplay::displayText(_I, iP, ss.str(), vpColor::red);
526  }
527 }
528 
535 {
536  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
537  for (; iter != curPoints.end(); ++iter) {
538  int id(iter->first);
539  vpImagePoint iP;
540  iP.set_i(static_cast<double>(iter->second.get_i()));
541  iP.set_j(static_cast<double>(iter->second.get_j()));
542 
544 
545  iP.set_i(vpMath::round(iP.get_i() + 7));
546  iP.set_j(vpMath::round(iP.get_j() + 7));
547  std::stringstream ss;
548  ss << id;
549  vpDisplay::displayText(_I, iP, ss.str(), vpColor::red);
550  }
551 }
552 
554  const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
555  bool displayFullModel)
556 {
557  std::vector<std::vector<double> > models = getModelForDisplay(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 
568  const vpCameraParameters &camera, const vpColor &col, unsigned int thickness,
569  bool displayFullModel)
570 {
571  std::vector<std::vector<double> > models = getModelForDisplay(camera, displayFullModel);
572 
573  for (size_t i = 0; i < models.size(); i++) {
574  vpImagePoint ip1(models[i][1], models[i][2]);
575  vpImagePoint ip2(models[i][3], models[i][4]);
576 
577  vpDisplay::displayLine(I, ip1, ip2, col, thickness);
578  }
579 }
580 
586 std::vector<std::vector<double> > vpMbtDistanceKltPoints::getFeaturesForDisplay()
587 {
588  std::vector<std::vector<double> > features;
589 
590  std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
591  for (; iter != curPoints.end(); ++iter) {
592  int id(iter->first);
593  vpImagePoint iP;
594  iP.set_i(static_cast<double>(iter->second.get_i()));
595  iP.set_j(static_cast<double>(iter->second.get_j()));
596 
597  vpImagePoint iP2;
598  iP2.set_i(vpMath::round(iP.get_i() + 7));
599  iP2.set_j(vpMath::round(iP.get_j() + 7));
600  std::vector<double> params = { 1, // KLT
601  iP.get_i(), iP.get_j(), iP2.get_i(), iP2.get_j(), static_cast<double>(id) };
602  features.push_back(params);
603  }
604 
605  return features;
606 }
607 
616 std::vector<std::vector<double> > vpMbtDistanceKltPoints::getModelForDisplay(const vpCameraParameters &camera,
617  bool displayFullModel)
618 {
619  std::vector<std::vector<double> > models;
620 
621  if ((polygon->isVisible() && isTrackedKltPoints) || displayFullModel) {
622  std::vector<std::pair<vpPoint, unsigned int> > roi;
624 
625  for (unsigned int j = 0; j < roi.size(); j += 1) {
626  if (((roi[(j + 1) % roi.size()].second & roi[j].second & vpPolygon3D::NEAR_CLIPPING) == 0) &&
627  ((roi[(j + 1) % roi.size()].second & roi[j].second & vpPolygon3D::FAR_CLIPPING) == 0) &&
628  ((roi[(j + 1) % roi.size()].second & roi[j].second & vpPolygon3D::DOWN_CLIPPING) == 0) &&
629  ((roi[(j + 1) % roi.size()].second & roi[j].second & vpPolygon3D::UP_CLIPPING) == 0) &&
630  ((roi[(j + 1) % roi.size()].second & roi[j].second & vpPolygon3D::LEFT_CLIPPING) == 0) &&
631  ((roi[(j + 1) % roi.size()].second & roi[j].second & vpPolygon3D::RIGHT_CLIPPING) == 0)) {
632 
633  vpImagePoint ip1, ip2;
634  std::vector<std::pair<vpPoint, vpPoint> > linesLst;
635 
636  if (useScanLine && !displayFullModel)
637  hiddenface->computeScanLineQuery(roi[j].first, roi[(j + 1) % roi.size()].first, linesLst, true);
638  else
639  linesLst.push_back(std::make_pair(roi[j].first, roi[(j + 1) % roi.size()].first));
640 
641  for (unsigned int i = 0; i < linesLst.size(); i++) {
642  linesLst[i].first.project();
643  linesLst[i].second.project();
644  vpMeterPixelConversion::convertPoint(camera, linesLst[i].first.get_x(), linesLst[i].first.get_y(), ip1);
645  vpMeterPixelConversion::convertPoint(camera, linesLst[i].second.get_x(), linesLst[i].second.get_y(), ip2);
646  std::vector<double> params = { 0, // 0 for line parameters
647  ip1.get_i(), ip1.get_j(), ip2.get_i(), ip2.get_j() };
648  models.push_back(params);
649  }
650  }
651  }
652  }
653 
654  return models;
655 }
656 END_VISP_NAMESPACE
657 #elif !defined(VISP_BUILD_SHARED_LIBS)
658 // Work around to avoid warning: libvisp_mbt.a(vpMbtDistanceKltPoints.cpp.o)
659 // has no symbols
660 void dummy_vpMbtDistanceKltPoints() { };
661 #endif
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
vpColVector & normalize()
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)
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ divideByZeroError
Division by zero.
Definition: vpException.h:70
Implementation of an homogeneous matrix and operations on such kind of matrices.
void extract(vpRotationMatrix &R) const
Implementation of an homography and operations on homographies.
Definition: vpHomography.h:174
vpMatrix convert() const
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 int round(double x)
Definition: vpMath.h:409
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
vpMbScanLine & getMbScanLineRenderer()
void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector< std::pair< vpPoint, vpPoint > > &lines, const bool &displayResults=false)
void updateMask(cv::Mat &mask, unsigned char _nb=255, unsigned int _shiftBorder=0)
void displayPrimitive(const vpImage< unsigned char > &_I)
bool useScanLine
Use scanline rendering.
void computeInteractionMatrixAndResidu(vpColVector &_R, vpMatrix &_J)
unsigned int computeNbDetectedCurrent(const vpKltOpencv &_tracker, const vpImage< bool > *mask=nullptr)
std::vector< std::vector< double > > getFeaturesForDisplay()
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
void init(const vpKltOpencv &_tracker, const vpImage< bool > *mask=nullptr)
std::vector< std::vector< double > > getModelForDisplay(const vpCameraParameters &cam, bool displayFullModel=false)
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
vpMbtPolygon * polygon
Pointer to the polygon that define a face.
void removeOutliers(const vpColVector &weight, const double &threshold_outlier)
void computeHomography(const vpHomogeneousMatrix &_cTc0, vpHomography &cHc0)
virtual bool isVisible(const vpHomogeneousMatrix &cMo, double alpha, const bool &modulo=false, const vpCameraParameters &cam=vpCameraParameters(), unsigned int width=0, unsigned int height=0)
int getIndex() const
Definition: vpMbtPolygon.h:93
static bool inRoiMask(const vpImage< bool > *mask, unsigned int i, unsigned int j)
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)
This class defines the container for a plane geometrical structure.
Definition: vpPlane.h:57
double getD() const
Definition: vpPlane.h:106
vpColVector getNormal() const
Definition: vpPlane.cpp:258
vpPoint & getPoint(const unsigned int _index)
void getRoiClipped(const vpCameraParameters &cam, std::vector< vpImagePoint > &roi)
void getPolygonClipped(std::vector< std::pair< vpPoint, unsigned int > > &poly)
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 & build(const std::vector< vpImagePoint > &corners, const bool &create_convex_hull=false)
Definition: vpPolygon.cpp:244
double getArea() const
Definition: vpPolygon.h:154
bool isInside(const vpImagePoint &iP, const PointInPolygonMethod &method=PnPolyRayCasting) const
Definition: vpPolygon.cpp:451
Implementation of a rotation matrix and operations on such kind of matrices.
Class that consider the case of a translation vector.