MRPT  1.9.9
CFaceDetection.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "detectors-precomp.h" // Precompiled headers
11 #include <mrpt/gui.h>
13 
17 #include <mrpt/opengl/CSphere.h>
18 #include <mrpt/opengl/CArrow.h>
20 #include <mrpt/opengl/CAxis.h>
21 #include <mrpt/math/CMatrix.h>
23 #include <mrpt/math/geometry.h>
25 
27 #include <mrpt/slam/CICP.h>
28 
29 // Universal include for all versions of OpenCV
30 #include <mrpt/otherlibs/do_opencv_includes.h>
31 
32 using namespace std;
33 using namespace mrpt;
34 using namespace mrpt::detectors;
35 using namespace mrpt::math;
36 using namespace mrpt::img;
37 using namespace mrpt::gui;
38 using namespace mrpt::math;
39 using namespace mrpt::opengl;
40 using namespace mrpt::system;
41 using namespace mrpt::maps;
42 using namespace mrpt::obs;
43 
44 //------------------------------------------------------------------------
45 // CFaceDetection
46 //------------------------------------------------------------------------
47 CFaceDetection::CFaceDetection() : m_end_threads(false)
48 {
51 
52  m_measure.faceNum = 0;
53 
54  m_timeLog.enable();
55 }
56 
57 //------------------------------------------------------------------------
58 // ~CFaceDetection
59 //------------------------------------------------------------------------
61 {
62  // Stop filters threads
63 
64  m_end_threads = true;
65 
66  m_enter_checkIfFacePlaneCov.set_value();
67  m_enter_checkIfFaceRegions.set_value();
69 
73 }
74 
75 //------------------------------------------------------------------------
76 // init
77 //------------------------------------------------------------------------
79 {
81  cfg.read_int("FaceDetection", "confidenceThreshold", 240);
82  m_options.multithread = cfg.read_bool("FaceDetection", "multithread", true);
84  cfg.read_bool("FaceDetection", "useCovFilter", true);
86  cfg.read_bool("FaceDetection", "useRegionsFilter", true);
88  cfg.read_bool("FaceDetection", "useSizeDistanceRelationFilter", true);
90  cfg.read_bool("FaceDetection", "useDiagonalDistanceFilter", true);
91 
93  cfg.read_double("FaceDetection", "planeThreshold", 50);
95  cfg.read_double("FaceDetection", "planeTest_eigenVal_top", 0.011);
97  cfg.read_double("FaceDetection", "planeTest_eigenVal_bottom", 0.0002);
99  "FaceDetection", "regionsTest_sumDistThreshold_top", 0.5);
101  "FaceDetection", "regionsTest_sumDistThreshold_bottom", 0.04);
102 
103  m_measure.takeTime = cfg.read_bool("FaceDetection", "takeTime", false);
105  cfg.read_bool("FaceDetection", "takeMeasures", false);
107  cfg.read_bool("FaceDetection", "saveMeasurementsToFile", false);
108 
109  // Run filters threads
111  {
114  std::thread(dummy_checkIfFaceRegions, this);
117  std::thread(dummy_checkIfFacePlaneCov, this);
121  std::thread(dummy_checkIfDiagonalSurface, this);
122 
126  }
127 
128  cascadeClassifier.init(cfg);
129 }
130 
131 //------------------------------------------------------------------------
132 // detectObjects
133 //------------------------------------------------------------------------
136 {
137  MRPT_START
138 
139  // Detect possible faces
140  vector_detectable_object localDetected;
141 
142  // To obtain experimental results
143  {
144  if (m_measure.takeTime) m_timeLog.enter("Detection time");
145  }
146 
147  cascadeClassifier.detectObjects(obs, localDetected);
148 
149  // To obtain experimental results
150  {
151  if (m_measure.takeTime) m_timeLog.leave("Detection time");
152 
153  // if ( m_measure.takeMeasures )
154  m_measure.numPossibleFacesDetected += localDetected.size();
155  }
156 
157  // Check if we are using a 3D Camera and 3D points are saved
158  if ((IS_CLASS(obs, CObservation3DRangeScan)) && (localDetected.size() > 0))
159  {
160  // To obtain experimental results
161  {
162  if (m_measure.takeTime) m_timeLog.enter("Check if real face time");
163  }
164 
166  const_cast<CObservation*>(obs));
167 
168  if (o->hasPoints3D)
169  {
170  // Vector to save detected objects to delete if they aren't a face
171  vector<size_t> deleteDetected;
172 
173  // Check if all possible detected faces satisfy a serial of
174  // constrains
175  for (unsigned int i = 0; i < localDetected.size(); i++)
176  {
177  CDetectable2D::Ptr rec =
178  std::dynamic_pointer_cast<CDetectable2D>(localDetected[i]);
179 
180  // Calculate initial and final rows and columns
181  unsigned int r1 = rec->m_y;
182  unsigned int r2 = rec->m_y + rec->m_height;
183  unsigned int c1 = rec->m_x;
184  unsigned int c2 = rec->m_x + rec->m_width;
185 
186  o->getZoneAsObs(m_lastFaceDetected, r1, r2, c1, c2);
187 
189  {
190  // To obtain experimental results
191  {
192  if (m_measure.takeTime)
193  m_timeLog.enter("Multithread filters application");
194  }
195 
196  // Semaphores signal
198  m_enter_checkIfFacePlaneCov.set_value();
200  m_enter_checkIfFaceRegions.set_value();
203  m_enter_checkIfDiagonalSurface.set_value();
204 
205  // Semaphores wait
207  m_leave_checkIfFacePlaneCov.get_future().wait();
209  m_leave_checkIfFaceRegions.get_future().wait();
212  m_leave_checkIfDiagonalSurface.get_future().wait();
213 
214  // Check resutls
218  deleteDetected.push_back(i);
219 
220  // To obtain experimental results
221  {
222  if (m_measure.takeTime)
223  m_timeLog.leave("Multithread filters application");
224  }
225 
226  m_measure.faceNum++;
227  }
228  else
229  {
230  // To obtain experimental results
231  {
232  if (m_measure.takeTime)
233  m_timeLog.enter("Secuential filters application");
234  }
235 
236  /////////////////////////////////////////////////////
237  // CMatrixTemplate<bool> region;
238  // experimental_segmentFace( m_lastFaceDetected, region);
239  /////////////////////////////////////////////////////
240 
241  // m_lastFaceDetected.intensityImage.saveToFile(format("%i.jpg",m_measure.faceNum));
242 
243  bool remove = false;
244 
245  // First check if we can adjust a plane to detected region
246  // as face, if yes it isn't a face!
247  if (m_options.useCovFilter &&
249  {
250  deleteDetected.push_back(i);
251  remove = true;
252  }
253  else if (
256  {
257  deleteDetected.push_back(i);
258  remove = true;
259  }
260  else if (
264  {
265  deleteDetected.push_back(i);
266  remove = true;
267  }
268 
269  if (remove)
270  {
271  /*ofstream f;
272  f.open("deleted.txt", ofstream::app);
273  f << "Deleted: " << m_measure.faceNum << endl;
274  f.close();*/
276  }
277 
278  m_measure.faceNum++;
279 
280  // To obtain experimental results
281  {
282  if (m_measure.takeTime)
283  m_timeLog.leave("Secuential filters application");
284  }
285  }
286  }
287 
288  // Delete non faces
289  for (unsigned int i = deleteDetected.size(); i > 0; i--)
290  localDetected.erase(
291  localDetected.begin() + deleteDetected[i - 1]);
292  }
293 
294  // Convert 2d detected objects to 3d
295  for (unsigned int i = 0; i < localDetected.size(); i++)
296  {
298  std::dynamic_pointer_cast<CDetectable2D>(localDetected[i])));
299  detected.push_back(object3d);
300  }
301 
302  // To obtain experimental results
303  {
304  if (m_measure.takeTime) m_timeLog.leave("Check if real face time");
305  }
306  }
307  else // Not using a 3D camera
308  {
309  detected = localDetected;
310  }
311 
312  // To obtain experimental results
313  {
314  // if ( m_measure.takeMeasures )
315  m_measure.numRealFacesDetected += detected.size();
316  }
317 
318  MRPT_END
319 }
320 
321 //------------------------------------------------------------------------
322 // checkIfFacePlane
323 //------------------------------------------------------------------------
325 {
326  vector<TPoint3D> points;
327 
328  size_t N = face->points3D_x.size();
329 
330  points.resize(N);
331 
332  for (size_t i = 0; i < N; i++)
333  points[i] = TPoint3D(
334  face->points3D_x.at(i), face->points3D_y.at(i),
335  face->points3D_z.at(i));
336 
337  // Try to ajust a plane
338  TPlane plane;
339 
340  // To obtain experimental results
341  {
343  m_measure.errorEstimations.push_back(
344  (double)getRegressionPlane(points, plane));
345  }
346 
348  return true;
349 
350  return false;
351 }
352 
354 {
355  obj->thread_checkIfFacePlaneCov();
356 }
357 
359 {
360  for (;;)
361  {
362  m_enter_checkIfFacePlaneCov.get_future().wait();
363 
364  if (m_end_threads) break;
365 
366  // Perform filter
368 
369  m_leave_checkIfFacePlaneCov.set_value();
370  }
371 }
372 
373 //------------------------------------------------------------------------
374 // checkIfFacePlaneCov
375 //------------------------------------------------------------------------
377 {
379 
380  // To obtain experimental results
381  {
382  if (m_measure.takeTime)
383  m_timeLog.enter("Check if face plane: covariance");
384  }
385 
386  // Get face region size
387  const unsigned int faceWidth = face->intensityImage.getWidth();
388  const unsigned int faceHeight = face->intensityImage.getHeight();
389 
390  // We work with a confidence image?
391  const bool confidence = face->hasConfidenceImage;
392 
393  // To fill with valid points
394  vector<CArrayDouble<3>> pointsVector;
395 
396  CMatrixTemplate<bool> region; // To save the segmented region
397  experimental_segmentFace(*face, region);
398 
399  for (unsigned int j = 0; j < faceHeight; j++)
400  {
401  for (unsigned int k = 0; k < faceWidth; k++)
402  {
403  CArrayDouble<3> aux;
404 
405  if (region.get_unsafe(j, k) &&
406  (((!confidence) ||
407  ((confidence) &&
408  (*(face->confidenceImage.get_unsafe(k, j, 0)) >
410  (*(face->intensityImage.get_unsafe(k, j)) >
411  50))))) // Don't take in account dark pixels
412  {
413  int position = faceWidth * j + k;
414  aux[0] = face->points3D_x[position];
415  aux[1] = face->points3D_y[position];
416  aux[2] = face->points3D_z[position];
417  pointsVector.push_back(aux);
418  }
419  }
420  }
421 
422  // Check if points vector is empty to avoid a future crash
423  if (pointsVector.empty()) return false;
424 
425  // experimental_viewFacePointsScanned( *face );
426 
427  // To obtain the covariance vector and eigenvalues
429  CMatrixDouble eVects, m_eVals;
430  CVectorDouble eVals;
431 
432  cov = covVector<vector<CArrayDouble<3>>, CMatrixDouble>(pointsVector);
433 
434  cov.eigenValues(eVals);
435 
436  cov.eigenVectors(eVects, m_eVals);
437 
438  // To obtain experimental results
439  {
440  if (m_measure.takeMeasures) m_measure.lessEigenVals.push_back(eVals[0]);
441 
442  if (m_measure.takeTime)
443  m_timeLog.leave("Check if face plane: covariance");
444 
445  // Uncomment if you want to analyze the calculated eigenvalues
446  // ofstream f;
447  /*f.open("eigenvalues.txt", ofstream::app);
448  f << m_measure.faceNum << " " << eVals[0] << endl;
449  f.close();*/
450 
451  // f.open("eigenvalues2.txt", ofstream::app);
452  cout << eVals[0] << " " << eVals[1] << " " << eVals[2] << " > ";
453  cout << eVals[0] / eVals[2] << endl;
454  // f << eVals[0]/eVals[2] << endl;
455  // f.close();
456  }
457 
458  if (m_measure.faceNum >= 314)
459  experimental_viewFacePointsAndEigenVects(pointsVector, eVects, eVals);
460 
461  // Check if the less eigenvalue is out of the permited area
462  // if ( ( eVals[0] > m_options.planeEigenValThreshold_down )
463  // && ( eVals[0] < m_options.planeEigenValThreshold_up ) )
464  if (eVals[0] / eVals[2] > 0.06)
465  {
466  // Uncomment if you want to save the face regions discarted by this
467  // filter
468  /*ofstream f;
469  f.open("deletedCOV.txt", ofstream::app);
470  f << m_measure.faceNum << endl;
471  f.close();*/
472 
473  return true; // Filter not passed
474  }
475 
476  return false; // Filter passed
477 
479 }
480 
482 {
483  obj->thread_checkIfFaceRegions();
484 }
485 
487 {
488  for (;;)
489  {
490  m_enter_checkIfFaceRegions.get_future().wait();
491 
492  if (m_end_threads) break;
493 
494  // Perform filter
496 
497  m_leave_checkIfFaceRegions.set_value();
498  }
499 }
500 
501 //------------------------------------------------------------------------
502 // checkIfFaceRegions
503 //------------------------------------------------------------------------
504 
506 {
507  MRPT_START
508 
509  // To obtain experimental results
510  {
511  if (m_measure.takeTime) m_timeLog.enter("Check if face plane: regions");
512  }
513 
514  // To obtain region size
515  const unsigned int faceWidth = face->intensityImage.getWidth();
516  const unsigned int faceHeight = face->intensityImage.getHeight();
517 
518  // Initial vertical size of a region
519  unsigned int sectionVSize = faceHeight / 3.0;
520 
521  // Steps of this filter
522  // 1. To segment the region detected as face using a regions growing
523  // algorithm
524  // 2. To obtain the first and last column to work (a profile face detected
525  // can have a lateral area without to use)
526  // 3. To calculate the histogram of the upper zone of the region for
527  // determine if we use it (if this zone present
528  // a lot of dark pixels the measurements can be wrong)
529  // 4. To obtain the coordinates of pixels that form each subregion
530  // 5. To calculate medians or means of each subregion
531  // 6. To check subregions constrains
532 
533  vector<TPoint3D> points;
534 
535  TPoint3D meanPos[3][3] = {
536  {TPoint3D(0, 0, 0), TPoint3D(0, 0, 0), TPoint3D(0, 0, 0)},
537  {TPoint3D(0, 0, 0), TPoint3D(0, 0, 0), TPoint3D(0, 0, 0)},
538  {TPoint3D(0, 0, 0), TPoint3D(0, 0, 0), TPoint3D(0, 0, 0)}};
539  int numPoints[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
540 
541  vector<TPoint3D> regions2[9];
542 
543  //
544  // 1. To segment the region detected as face using a regions growing
545  // algorithm
546  //
547 
548  CMatrixTemplate<bool> region; // To save the segmented region
549  experimental_segmentFace(*face, region);
550 
551  //
552  // 2. To obtain the first and last column to work (a profile face detected
553  // can have a lateral area without to use)
554  //
555 
556  size_t start = faceWidth, end = 0;
557 
558  for (size_t r = 0; r < region.rows(); r++)
559  for (size_t c = 1; c < region.cols(); c++)
560  {
561  if ((!(region.get_unsafe(r, c - 1))) && (region.get_unsafe(r, c)))
562  {
563  if (c < start) start = c;
564  }
565  else if (
566  (region.get_unsafe(r, c - 1)) && (!(region.get_unsafe(r, c))))
567  if (c > end) end = c;
568 
569  if ((c > end) && (region.get_unsafe(r, c))) end = c;
570  }
571 
572  if (end == 0) end = faceWidth - 1; // Check if the end has't changed
573  if (end < 3 * (faceWidth / 4))
574  end = 3 * (faceWidth / 4); // To avoid spoiler
575  if (start == faceWidth) start = 0; // Check if the start has't changed
576  if (start > faceWidth / 4) start = faceWidth / 4; // To avoid spoiler
577 
578  // cout << "Start: " << start << " End: " << end << endl;
579 
580  // To use the start and end calculated to obtain the final regions limits
581  unsigned int utilWidth = faceWidth - start - (faceWidth - end);
582  unsigned int c1 = ceil(utilWidth / 3.0 + start);
583  unsigned int c2 = ceil(2 * (utilWidth / 3.0) + start);
584 
585  //
586  // 3. To calculate the histogram of the upper zone of the region for
587  // determine if we use it
588  //
589 
591  hist.setSize(1, 256, true);
593  face->intensityImage, start, 0, end, ceil(faceHeight * 0.1), hist);
594 
595  size_t countHist = 0;
596  for (size_t i = 0; i < 60; i++)
597  {
598  countHist += hist.get_unsafe(0, i);
599  }
600 
601  size_t upLimit = 0;
602  size_t downLimit = faceHeight - 1;
603 
604  if (countHist > 10)
605  {
606  upLimit = floor(faceHeight * 0.1);
607  downLimit = floor(faceHeight * 0.9);
608  }
609 
610  // Uncomment it if you want to analyze the number of pixels that have more
611  // dark that the 60 gray tone
612  // m_meanHist.push_back( countHist );
613 
614  //
615  // 4. To obtain the coordinates of pixels that form each region
616  //
617 
618  unsigned int cont = 0;
619 
620  for (unsigned int r = 0; r < faceHeight; r++)
621  {
622  for (unsigned int c = 0; c < faceWidth; c++, cont++)
623  {
624  if ((r >= upLimit) && (r <= downLimit) &&
625  (region.get_unsafe(r, c)) &&
626  (*(face->confidenceImage.get_unsafe(c, r, 0)) >
628  (*(face->intensityImage.get_unsafe(c, r)) > 50))
629  {
630  unsigned int row, col;
631  if (r < sectionVSize + upLimit * 0.3)
632  row = 0;
633  else if (r < sectionVSize * 2 - upLimit * 0.15)
634  row = 1;
635  else
636  row = 2;
637 
638  if (c < c1)
639  col = 0;
640  else if (c < c2)
641  col = 1;
642  else
643  col = 2;
644 
645  TPoint3D point(
646  face->points3D_x[cont], face->points3D_y[cont],
647  face->points3D_z[cont]);
648  meanPos[row][col] = meanPos[row][col] + point;
649 
650  ++numPoints[row][col];
651 
652  if (row == 0 && col == 0)
653  regions2[0].push_back(TPoint3D(
654  face->points3D_x[cont], face->points3D_y[cont],
655  face->points3D_z[cont]));
656  else if (row == 0 && col == 1)
657  regions2[1].push_back(TPoint3D(
658  face->points3D_x[cont], face->points3D_y[cont],
659  face->points3D_z[cont]));
660  else if (row == 0 && col == 2)
661  regions2[2].push_back(TPoint3D(
662  face->points3D_x[cont], face->points3D_y[cont],
663  face->points3D_z[cont]));
664  else if (row == 1 && col == 0)
665  regions2[3].push_back(TPoint3D(
666  face->points3D_x[cont], face->points3D_y[cont],
667  face->points3D_z[cont]));
668  else if (row == 1 && col == 1)
669  regions2[4].push_back(TPoint3D(
670  face->points3D_x[cont], face->points3D_y[cont],
671  face->points3D_z[cont]));
672  else if (row == 1 && col == 2)
673  regions2[5].push_back(TPoint3D(
674  face->points3D_x[cont], face->points3D_y[cont],
675  face->points3D_z[cont]));
676  else if (row == 2 && col == 0)
677  regions2[6].push_back(TPoint3D(
678  face->points3D_x[cont], face->points3D_y[cont],
679  face->points3D_z[cont]));
680  else if (row == 2 && col == 1)
681  regions2[7].push_back(TPoint3D(
682  face->points3D_x[cont], face->points3D_y[cont],
683  face->points3D_z[cont]));
684  else
685  regions2[8].push_back(TPoint3D(
686  face->points3D_x[cont], face->points3D_y[cont],
687  face->points3D_z[cont]));
688  }
689  }
690  }
691 
692  //
693  // 5. To calculate medians or means of each subregion
694  //
695 
696  vector<double> oldPointsX1;
697 
698  size_t middle1 = 0;
699  size_t middle2 = 0;
700 
701  if (regions2[0].size() > 0)
702  {
703  for (size_t i = 0; i < regions2[0].size(); i++)
704  oldPointsX1.push_back(regions2[0][i].x);
705 
706  middle1 = floor((double)oldPointsX1.size() / 2);
707  nth_element(
708  oldPointsX1.begin(), oldPointsX1.begin() + middle1,
709  oldPointsX1.end()); // Obtain center element
710  }
711 
712  vector<double> oldPointsX2;
713 
714  if (regions2[2].size() > 0)
715  {
716  for (size_t i = 0; i < regions2[2].size(); i++)
717  oldPointsX2.push_back(regions2[2][i].x);
718 
719  middle2 = floor((double)oldPointsX2.size() / 2);
720  nth_element(
721  oldPointsX2.begin(), oldPointsX2.begin() + middle2,
722  oldPointsX2.end()); // Obtain center element
723  }
724 
725  for (size_t i = 0; i < 3; i++)
726  for (size_t j = 0; j < 3; j++)
727  if (!numPoints[i][j])
728  meanPos[i][j] = TPoint3D(0, 0, 0);
729  else
730  meanPos[i][j] = meanPos[i][j] / numPoints[i][j];
731 
732  if (regions2[0].size() > 0) meanPos[0][0].x = oldPointsX1.at(middle1);
733 
734  if (regions2[2].size() > 0) meanPos[0][2].x = oldPointsX2.at(middle2);
735 
736  //
737  // 6. To check subregions constrains
738  //
739  vector<double> dist(5);
740  size_t res = checkRelativePosition(
741  meanPos[1][0], meanPos[1][2], meanPos[1][1], dist[0]);
743  meanPos[2][0], meanPos[2][2], meanPos[2][1], dist[1]);
745  meanPos[0][0], meanPos[0][2], meanPos[0][1], dist[2]);
747  meanPos[0][0], meanPos[2][2], meanPos[1][1], dist[3]);
749  meanPos[2][0], meanPos[0][2], meanPos[1][1], dist[4]);
750 
751  ofstream f;
752  f.open("dist.txt", ofstream::app);
753  f << sum(dist) << endl;
754  f.close();
755 
756  bool real = false;
757  if (!res)
758  real = true;
759  else if ((res = 1) && (sum(dist) > 0.04))
760  real = true;
761 
762  f.open("tam.txt", ofstream::app);
763  f << meanPos[0][1].distanceTo(meanPos[2][1]) << endl;
764  f.close();
765 
766  // experimental_viewRegions( regions2, meanPos );
767 
768  // cout << endl << meanPos[0][0] << "\t" << meanPos[0][1] << "\t" <<
769  // meanPos[0][2];
770  // cout << endl << meanPos[1][0] << "\t" << meanPos[1][1] << "\t" <<
771  // meanPos[1][2];
772  // cout << endl << meanPos[2][0] << "\t" << meanPos[2][1] << "\t" <<
773  // meanPos[2][2] << endl;
774 
775  // To obtain experimental results
776  {
777  if (m_measure.takeTime) m_timeLog.leave("Check if face plane: regions");
778  }
779 
780  if (real)
781  return true; // Filter passed
782  else
783  {
784  // Uncomment if you want to known what regions was discarted by this
785  // filter
786  /*ofstream f;
787  f.open("deletedSTRUCTURES.txt", ofstream::app);
788  f << m_measure.faceNum << endl;
789  f.close();*/
790 
791  return false; // Filter not passed
792  }
793 
794  MRPT_END
795 }
796 
797 //------------------------------------------------------------------------
798 // checkRelativePosition
799 //------------------------------------------------------------------------
800 
802  const TPoint3D& p1, const TPoint3D& p2, const TPoint3D& p, double& dist)
803 {
804  double x1 = -p1.y;
805  double y1 = p1.x;
806 
807  double x2 = -p2.y;
808  double y2 = p2.x;
809 
810  double x = -p.y;
811  double y = p.x;
812 
813  double yIdeal = y1 + (((x - x1) * (y2 - y1)) / (x2 - x1));
814 
815  //////////////////////////////////
816 
817  /*double xaux = x2;
818  double yaux = y1;
819 
820  cout << "Grados= " << RAD2DEG(acos(
821  (xaux-x1)/(sqrt(pow(x1-x2,2)+pow(y1-y2,2))) )) << endl;*/
822 
823  ///////////////////////////////////////
824 
825  dist = yIdeal - y;
826 
827  if (y < yIdeal)
828  return 0;
829  else
830  return 1;
831 }
832 
834 {
835  obj->thread_checkIfDiagonalSurface();
836 }
837 
839 {
840  for (;;)
841  {
842  m_enter_checkIfDiagonalSurface.get_future().wait();
843 
844  if (m_end_threads) break;
845 
846  // Perform filter
849 
850  m_leave_checkIfDiagonalSurface.set_value();
851  }
852 }
853 
854 //------------------------------------------------------------------------
855 // checkIfDiagonalSurface
856 //------------------------------------------------------------------------
857 
859 {
860  MRPT_START
861 
862  // To obtain experimental results
863  {
865  m_timeLog.enter("Check if face plane: diagonal distances");
866 
868  m_timeLog.enter("Check if face plane: size-distance relation");
869  }
870 
871  const unsigned int faceWidth = face->intensityImage.getWidth();
872  const unsigned int faceHeight = face->intensityImage.getHeight();
873 
874  // const float max_desv = 0.2;
875 
876  unsigned int x1 = ceil(faceWidth * 0.25);
877  unsigned int x2 = floor(faceWidth * 0.75);
878  unsigned int y1 = ceil(faceHeight * 0.15);
879  unsigned int y2 = floor(faceHeight * 0.85);
880 
881  vector<TPoint3D> points;
882  unsigned int cont = (y1 == 0 ? 0 : faceHeight * (y1 - 1));
883  CMatrixBool valids;
884 
885  valids.setSize(faceHeight, faceWidth);
886 
887  int total = 0;
888  double sumDepth = 0;
889 
890  for (unsigned int i = y1; i <= y2; i++)
891  {
892  cont += x1;
893 
894  for (unsigned int j = x1; j <= x2; j++, cont++)
895  {
896  if (*(face->confidenceImage.get_unsafe(j, i, 0)) >
898  {
899  sumDepth += face->points3D_x[cont];
900  total++;
901  points.push_back(TPoint3D(
902  face->points3D_x[cont], face->points3D_y[cont],
903  face->points3D_z[cont]));
904  }
905  }
906  cont += faceWidth - x2 - 1;
907  }
908 
909  double meanDepth = sumDepth / total;
910 
911  /*if ( m_measure.faceNum == 434 )
912  experimental_viewFacePointsScanned( *face );*/
913 
914  // experimental_viewFacePointsScanned( points );
915 
916  bool res = true;
917 
919  {
920  double maxFaceDistance = 0.5 + 1000 / (pow(faceWidth, 1.9));
921 
922  // To obtain experimental results
923  {
924  if (m_measure.takeTime)
925  m_timeLog.leave("Check if face plane: size-distance relation");
926 
928  m_timeLog.leave("Check if face plane: diagonal distances");
929  }
930 
931  /*if ( maxFaceDistance > meanDepth )
932  return true;
933 
934  if ( !m_options.useDiagonalDistanceFilter )
935  return false;*/
936 
937  if (maxFaceDistance < meanDepth)
938  {
939  // Uncomment if you want to analyze the regions discarted by this
940  // filter
941  /*ofstream f;
942  f.open("deletedSIZEDISTANCE.txt", ofstream::app);
943  f << m_measure.faceNum << endl;
944  f.close();*/
945 
946  // if ( !m_options.useDiagonalDistanceFilter )
947  return false;
948  // else
949  // res = false;
950  }
951 
952  if (!m_options.useDiagonalDistanceFilter) return true;
953  }
954 
955  ofstream f;
956  /*f.open("relaciones1.txt", ofstream::app);
957  f << faceWidth << endl;
958  f.close();*/
959 
960  f.open("relaciones2.txt", ofstream::app);
961  f << meanDepth << endl;
962  f.close();
963 
964  // cout << m_measure.faceNum ;
965 
966  // experimental_viewFacePointsScanned( points );
967 
968  points.clear();
969 
970  cont = (y1 == 1 ? 0 : faceHeight * (y1 - 1));
971 
972  for (unsigned int i = y1; i <= y2; i++)
973  {
974  cont += x1;
975 
976  for (unsigned int j = x1; j <= x2; j++, cont++)
977  {
978  if ((*(face->confidenceImage.get_unsafe(j, i, 0)) >
980  //&& ( face->points3D_x[cont] > meanDepth - max_desv )
981  //&& ( face->points3D_x[cont] < meanDepth + max_desv ) )
982  {
983  valids.set_unsafe(i, j, true);
984  points.push_back(TPoint3D(
985  face->points3D_x[cont], face->points3D_y[cont],
986  face->points3D_z[cont]));
987  }
988  else
989  valids.set_unsafe(i, j, false);
990  }
991  cont += faceWidth - x2 - 1;
992  }
993 
994  /*if ( m_measure.faceNum > 838 )
995  experimental_viewFacePointsScanned( points );*/
996 
997  // if ( ( m_measure.faceNum == 225 ) || ( m_measure.faceNum == 226 ) )
998  // experimental_viewFacePointsScanned( points );
999 
1000  double sumDistances = 0;
1001  double distance;
1002  int offsetIndex;
1003 
1004  cont = 0;
1005 
1006  for (unsigned int i = y1; i <= y2; i++)
1007  {
1008  cont += x1;
1009 
1010  for (unsigned int j = x1; j <= x2; j++, cont++)
1011  {
1012  if (valids.get_unsafe(i, j))
1013  {
1014  // experimental_calcDiagDist( face, i, j, faceWidth, faceHeight,
1015  // valids, distance );
1016 
1017  distance = 0;
1018  if ((i + 1 <= y2) && (j + 1 <= x2))
1019  {
1020  if (valids.get_unsafe(i + 1, j + 1))
1021  {
1022  TPoint3D p1(
1023  face->points3D_x[cont], face->points3D_y[cont],
1024  face->points3D_z[cont]);
1025  offsetIndex = cont + faceWidth + 1;
1027  face->points3D_x[offsetIndex],
1028  face->points3D_y[offsetIndex],
1029  face->points3D_z[offsetIndex]));
1030  }
1031  else
1032  {
1033  bool validOffset = true;
1034  int offset = 2;
1035 
1036  while (validOffset)
1037  {
1038  if ((i + offset <= y2) && (j + offset <= x2))
1039  {
1040  if (valids.get_unsafe(i + offset, j + offset))
1041  {
1042  TPoint3D p1(
1043  face->points3D_x[cont],
1044  face->points3D_y[cont],
1045  face->points3D_z[cont]);
1046  offsetIndex = cont + faceWidth + offset;
1048  face->points3D_x[offsetIndex],
1049  face->points3D_y[offsetIndex],
1050  face->points3D_z[offsetIndex]));
1051  break;
1052  }
1053  offset++;
1054  }
1055  else
1056  validOffset = false;
1057  }
1058  }
1059  }
1060 
1061  sumDistances += distance;
1062  }
1063  }
1064  cont += faceWidth - x2 - 1;
1065  }
1066 
1067  // For experimental results
1068  {
1069  if (m_measure.takeMeasures)
1070  m_measure.sumDistances.push_back(sumDistances);
1071 
1072  ofstream fo;
1073  fo.open("distances.txt", ofstream::app);
1074  // f << m_measure.faceNum << " " << sumDistances << endl;
1075  fo << sumDistances << endl;
1076  fo.close();
1077 
1078  fo.open("distances2.txt", ofstream::app);
1079  fo << m_measure.faceNum << " " << sumDistances << endl;
1080  fo.close();
1081  }
1082 
1083  // double yMax = 3 + 3.8 / ( pow( meanDepth, 2 ) );
1084  // double yMax = 3 + 7 /( pow( meanDepth, 2) ) ;
1085  double yMax = 3 + 6 / (pow(meanDepth, 2));
1086  double yMin = 1 + 3.8 / (pow(meanDepth + 1.2, 2));
1087 
1088  // To obtain experimental results
1089  {
1090  if (m_measure.takeTime)
1091  m_timeLog.leave("Check if face plane: diagonal distances");
1092  }
1093 
1094  if (((sumDistances <= yMax) && (sumDistances >= yMin)) && (res))
1095  {
1096  /* Uncomment if you want to analyze the real size of each studied region
1097  / *ofstream f;
1098  f.open("sizes.txt", ofstream::app);
1099  double h = meanDepth/cos(DEG2RAD(faceHeight*0.2361111111111111));
1100  double realHigh = sin(DEG2RAD(faceHeight*0.2361111111111111))*h;
1101  f << realHigh << endl;
1102  f.close();*/
1103 
1104  return true;
1105  }
1106 
1107  // Uncomment if you want to analyze regions discarted by this filter
1108  /*if (( sumDistances > yMax ) || ( sumDistances < yMin ))
1109  {
1110  ofstream f;
1111  f.open("deletedDIAGONAL.txt", ofstream::app);
1112  f << m_measure.faceNum << endl;
1113  f.close();
1114  }*/
1115 
1116  return false;
1117 
1118  MRPT_END
1119 }
1120 
1121 //------------------------------------------------------------------------
1122 // checkIfDiagonalSurface2
1123 //------------------------------------------------------------------------
1124 
1126 {
1127  MRPT_START
1128 
1129  // To obtain experimental results
1130  {
1132  m_timeLog.enter("Check if face plane: diagonal distances");
1133 
1135  m_timeLog.enter("Check if face plane: size-distance relation");
1136  }
1137 
1138  const unsigned int faceWidth = face->intensityImage.getWidth();
1139  const unsigned int faceHeight = face->intensityImage.getHeight();
1140 
1141  CMatrixTemplate<bool> region; // To save the segmented region
1142  experimental_segmentFace(*face, region);
1143 
1144  size_t cont = 0;
1145  size_t total = 0;
1146  float sumDepth = 0;
1147 
1148  vector<TPoint3D> points;
1149 
1150  for (unsigned int row = 0; row < faceHeight; row++)
1151  {
1152  for (unsigned int col = 0; col < faceWidth; col++, cont++)
1153  {
1154  if ((region.get_unsafe(row, col)) &&
1155  (*(face->confidenceImage.get_unsafe(col, row, 0)) >
1157  {
1158  sumDepth += face->points3D_x[cont];
1159  total++;
1160  points.push_back(TPoint3D(
1161  face->points3D_x[cont], face->points3D_y[cont],
1162  face->points3D_z[cont]));
1163  }
1164  }
1165  }
1166 
1167  double meanDepth = sumDepth / total;
1168 
1169  bool res = true;
1170 
1172  {
1173  double maxFaceDistance = 0.5 + 1000 / (pow(faceWidth, 1.9));
1174 
1175  // To obtain experimental results
1176  {
1177  if (m_measure.takeTime)
1178  m_timeLog.leave("Check if face plane: size-distance relation");
1179 
1181  m_timeLog.leave("Check if face plane: diagonal distances");
1182  }
1183 
1184  /*if ( maxFaceDistance > meanDepth )
1185  return true;
1186 
1187  if ( !m_options.useDiagonalDistanceFilter )
1188  return false;*/
1189 
1190  if (maxFaceDistance < meanDepth)
1191  {
1192  // Uncomment if you want to analyze the regions discarted by this
1193  // filter
1194  /*ofstream f;
1195  f.open("deletedSIZEDISTANCE.txt", ofstream::app);
1196  f << m_measure.faceNum << endl;
1197  f.close();*/
1198 
1199  // if ( !m_options.useDiagonalDistanceFilter )
1200  return false;
1201  // else
1202  // res = false;
1203  }
1204 
1205  if (!m_options.useDiagonalDistanceFilter) return true;
1206  }
1207 
1208  ofstream f;
1209  /*f.open("relaciones1.txt", ofstream::app);
1210  f << faceWidth << endl;
1211  f.close();*/
1212 
1213  f.open("relaciones2.txt", ofstream::app);
1214  f << meanDepth << endl;
1215  f.close();
1216 
1217  // cout << m_measure.faceNum ;
1218 
1219  // experimental_viewFacePointsScanned( points );
1220 
1221  points.clear();
1222 
1223  /*if ( m_measure.faceNum > 838 )
1224  experimental_viewFacePointsScanned( points );*/
1225 
1226  // if ( ( m_measure.faceNum == 225 ) || ( m_measure.faceNum == 226 ) )
1227  // experimental_viewFacePointsScanned( points );
1228 
1229  double sumDistances = 0;
1230  double distance;
1231  size_t offsetIndex = 0;
1232 
1233  cont = 0;
1234 
1235  for (unsigned int i = 0; i < faceHeight; i++)
1236  {
1237  for (unsigned int j = 0; j < faceWidth; j++, cont++)
1238  {
1239  if (region.get_unsafe(i, j))
1240  {
1241  distance = 0;
1242  if ((i + 1 < faceHeight) && (j + 1 < faceWidth))
1243  {
1244  if (region.get_unsafe(i + 1, j + 1))
1245  {
1246  TPoint3D p1(
1247  face->points3D_x[cont], face->points3D_y[cont],
1248  face->points3D_z[cont]);
1249  offsetIndex = cont + faceWidth + 1;
1251  face->points3D_x[offsetIndex],
1252  face->points3D_y[offsetIndex],
1253  face->points3D_z[offsetIndex]));
1254  }
1255  else
1256  {
1257  bool validOffset = true;
1258  int offset = 2;
1259 
1260  while (validOffset)
1261  {
1262  if ((i + offset < faceHeight) &&
1263  (j + offset < faceWidth))
1264  {
1265  if (region.get_unsafe(i + offset, j + offset))
1266  {
1267  TPoint3D p1(
1268  face->points3D_x[cont],
1269  face->points3D_y[cont],
1270  face->points3D_z[cont]);
1271  offsetIndex = cont + faceWidth + offset;
1273  face->points3D_x[offsetIndex],
1274  face->points3D_y[offsetIndex],
1275  face->points3D_z[offsetIndex]));
1276  break;
1277  }
1278  offset++;
1279  }
1280  else
1281  validOffset = false;
1282  }
1283  }
1284  }
1285 
1286  sumDistances += distance;
1287  }
1288  }
1289  }
1290 
1291  // For experimental results
1292  {
1293  if (m_measure.takeMeasures)
1294  m_measure.sumDistances.push_back(sumDistances);
1295 
1296  ofstream f;
1297  f.open("distances.txt", ofstream::app);
1298  // f << m_measure.faceNum << " " << sumDistances << endl;
1299  f << sumDistances << endl;
1300  f.close();
1301 
1302  /*f.open("distances2.txt", ofstream::app);
1303  f << m_measure.faceNum << " " << sumDistances << endl;
1304  f.close();*/
1305  }
1306 
1307  // double yMax = 3 + 3.8 / ( pow( meanDepth, 2 ) );
1308  // double yMax = 3 + 7 /( pow( meanDepth, 2) ) ;
1309  double yMax = 3 + 11.8 / (pow(meanDepth, 0.9));
1310  double yMin = 1 + 3.8 / (pow(meanDepth + 7, 6));
1311 
1312  // To obtain experimental results
1313  {
1314  if (m_measure.takeTime)
1315  m_timeLog.leave("Check if face plane: diagonal distances");
1316  }
1317 
1318  if (((sumDistances <= yMax) && (sumDistances >= yMin)) && (res))
1319  {
1320  /* Uncomment if you want to analyze the real size of each studied region
1321  / *ofstream f;
1322  f.open("sizes.txt", ofstream::app);
1323  double h = meanDepth/cos(DEG2RAD(faceHeight*0.2361111111111111));
1324  double realHigh = sin(DEG2RAD(faceHeight*0.2361111111111111))*h;
1325  f << realHigh << endl;
1326  f.close();*/
1327 
1328  return true;
1329  }
1330 
1331  // Uncomment if you want to analyze regions discarted by this filter
1332  /*if (( sumDistances > yMax ) || ( sumDistances < yMin ))
1333  {
1334  ofstream f;
1335  f.open("deletedDIAGONAL.txt", ofstream::app);
1336  f << m_measure.faceNum << endl;
1337  f.close();
1338  }*/
1339 
1340  return false;
1341 
1342  MRPT_END
1343 }
1344 
1345 //------------------------------------------------------------------------
1346 // experimental_viewFacePointsScanned
1347 //------------------------------------------------------------------------
1348 
1351 {
1352  vector<float> xs, ys, zs;
1353 
1354  unsigned int N = face.points3D_x.size();
1355 
1356  xs.resize(N);
1357  ys.resize(N);
1358  zs.resize(N);
1359 
1360  for (unsigned int i = 0; i < N; i++)
1361  {
1362  xs[i] = face.points3D_x[i];
1363  ys[i] = face.points3D_y[i];
1364  zs[i] = face.points3D_z[i];
1365  }
1366 
1368 }
1369 
1370 //------------------------------------------------------------------------
1371 // experimental_ViewFacePointsScanned
1372 //------------------------------------------------------------------------
1373 
1375  const vector<TPoint3D>& points)
1376 {
1377  vector<float> xs, ys, zs;
1378 
1379  unsigned int N = points.size();
1380 
1381  xs.resize(N);
1382  ys.resize(N);
1383  zs.resize(N);
1384 
1385  for (unsigned int i = 0; i < N; i++)
1386  {
1387  xs[i] = points[i].x;
1388  ys[i] = points[i].y;
1389  zs[i] = points[i].z;
1390  }
1391 
1393 }
1394 
1395 //------------------------------------------------------------------------
1396 // experimental_viewFacePointsScanned
1397 //------------------------------------------------------------------------
1398 
1400  const vector<float>& xs, const vector<float>& ys, const vector<float>& zs)
1401 {
1403 
1404  win3D.setWindowTitle("3D Face detected (Scanned points)");
1405 
1406  win3D.resize(400, 300);
1407 
1408  win3D.setCameraAzimuthDeg(140);
1409  win3D.setCameraElevationDeg(20);
1410  win3D.setCameraZoom(6.0);
1411  win3D.setCameraPointingToPoint(2.5, 0, 0);
1412 
1414  mrpt::make_aligned_shared<mrpt::opengl::CPointCloudColoured>();
1415  gl_points->setPointSize(4.5);
1416 
1418 
1419  scene->insert(gl_points);
1420  scene->insert(mrpt::make_aligned_shared<mrpt::opengl::CGridPlaneXY>());
1421 
1422  CColouredPointsMap pntsMap;
1423 
1424  pntsMap.setAllPoints(xs, ys, zs);
1425 
1426  gl_points->loadFromPointsMap(&pntsMap);
1427 
1428  // gl_points->setColor(0,0.7,0.7,1);
1429 
1430  /*static int i = 0;
1431 
1432  if ( i == 2 )
1433  {
1434  mapa.setAllPoints( xs, ys, zs );
1435  i++;
1436  }
1437  else if ( i > 2 )
1438  {
1439  float run_time;
1440  CICP icp;
1441  CICP::TReturnInfo icp_info;
1442 
1443  icp.options.thresholdDist = 0.40;
1444  icp.options.thresholdAng = 0.40;
1445 
1446  CPose3DPDF::Ptr pdf= icp.Align3D(
1447  &mapa, // Map to align
1448  &pntsMap, // Reference map
1449  CPose3D(), // Initial gross estimate
1450  &run_time,
1451  &icp_info);
1452 
1453  cout << "ICP run took " << run_time << " secs." << endl;
1454  cout << "Goodness: " << 100*icp_info.goodness << "%" << endl;
1455  }
1456 
1457  i++;*/
1458 
1459  win3D.unlockAccess3DScene();
1460  win3D.repaint();
1461 
1462  system::pause();
1463 }
1464 
1465 //------------------------------------------------------------------------
1466 // experimental_viewFacePointsAndEigenVects
1467 //------------------------------------------------------------------------
1468 
1470  const vector<CArrayDouble<3>>& pointsVector, const CMatrixDouble& eigenVect,
1471  const CVectorDouble& eigenVal)
1472 {
1473  vector<float> xs, ys, zs;
1474 
1475  const size_t size = pointsVector.size();
1476 
1477  xs.resize(size);
1478  ys.resize(size);
1479  zs.resize(size);
1480 
1481  for (size_t i = 0; i < size; i++)
1482  {
1483  xs[i] = pointsVector[i][0];
1484  ys[i] = pointsVector[i][1];
1485  zs[i] = pointsVector[i][2];
1486  }
1487 
1488  TPoint3D center(sum(xs) / size, sum(ys) / size, sum(zs) / size);
1489 
1491 
1492  win3D.setWindowTitle("3D Face detected (Scanned points)");
1493 
1494  win3D.resize(400, 300);
1495 
1496  win3D.setCameraAzimuthDeg(140);
1497  win3D.setCameraElevationDeg(20);
1498  win3D.setCameraZoom(6.0);
1499  win3D.setCameraPointingToPoint(2.5, 0, 0);
1500 
1502  mrpt::make_aligned_shared<mrpt::opengl::CPointCloudColoured>();
1503  gl_points->setPointSize(4.5);
1504 
1506 
1507  CSphere::Ptr sphere = mrpt::make_aligned_shared<CSphere>(0.005f);
1508  sphere->setLocation(center);
1509  sphere->setColor(TColorf(0, 1, 0));
1510  scene->insert(sphere);
1511 
1512  // TPoint3D E1( eigenVect.get_unsafe(0,0), eigenVect.get_unsafe(1,0),
1513  // eigenVect.get_unsafe(2,0) );
1514  // TPoint3D E2( eigenVect.get_unsafe(0,1), eigenVect.get_unsafe(1,1),
1515  // eigenVect.get_unsafe(2,1) );
1516  // TPoint3D E3( eigenVect.get_unsafe(0,2), eigenVect.get_unsafe(1,2),
1517  // eigenVect.get_unsafe(2,2) );
1518 
1519  TPoint3D E1(
1520  eigenVect.get_unsafe(0, 0), eigenVect.get_unsafe(0, 1),
1521  eigenVect.get_unsafe(0, 2));
1522  TPoint3D E2(
1523  eigenVect.get_unsafe(1, 0), eigenVect.get_unsafe(1, 1),
1524  eigenVect.get_unsafe(1, 2));
1525  TPoint3D E3(
1526  eigenVect.get_unsafe(2, 0), eigenVect.get_unsafe(2, 1),
1527  eigenVect.get_unsafe(2, 2));
1528 
1529  // vector<TSegment3D> sgms;
1530 
1531  TPoint3D p1(center + E1 * eigenVal[0] * 100);
1532  TPoint3D p2(center + E2 * eigenVal[1] * 100);
1533  TPoint3D p3(center + E3 * eigenVal[2] * 100);
1534 
1535  CArrow::Ptr arrow1 = mrpt::make_aligned_shared<CArrow>(
1536  center.x, center.y, center.z, p1.x, p1.y, p1.z);
1537  CArrow::Ptr arrow2 = mrpt::make_aligned_shared<CArrow>(
1538  center.x, center.y, center.z, p2.x, p2.y, p2.z);
1539  CArrow::Ptr arrow3 = mrpt::make_aligned_shared<CArrow>(
1540  center.x, center.y, center.z, p3.x, p3.y, p3.z);
1541 
1542  arrow1->setColor(TColorf(0, 1, 0));
1543  arrow2->setColor(TColorf(1, 0, 0));
1544  arrow3->setColor(TColorf(0, 0, 1));
1545 
1546  scene->insert(arrow1);
1547  scene->insert(arrow2);
1548  scene->insert(arrow3);
1549 
1550  // sgms.push_back( TSegment3D(center,center + E1*eigenVal[0]*100) );
1551  // sgms.push_back( TSegment3D(center,center + E2*eigenVal[1]*100) );
1552  // sgms.push_back( TSegment3D(center,center + E3*eigenVal[2]*100) );
1553  // mrpt::opengl::CSetOfLines::Ptr lines =
1554  // mrpt::make_aligned_shared<mrpt::opengl::CSetOfLines>( sgms );
1555  // lines->setColor(0,0,1,1);
1556  // lines->setLineWidth( 10 );
1557 
1558  // scene->insert( lines );
1559 
1560  scene->insert(gl_points);
1561  scene->insert(mrpt::make_aligned_shared<mrpt::opengl::CGridPlaneXY>());
1562 
1563  CColouredPointsMap pntsMap;
1564 
1565  pntsMap.setAllPoints(xs, ys, zs);
1566 
1567  gl_points->loadFromPointsMap(&pntsMap);
1568 
1569  win3D.unlockAccess3DScene();
1570  win3D.repaint();
1571 
1572  system::pause();
1573 }
1574 
1575 //------------------------------------------------------------------------
1576 // experimental_viewRegions
1577 //------------------------------------------------------------------------
1578 
1580  const vector<TPoint3D> regions[9], const TPoint3D meanPos[3][3])
1581 {
1583 
1584  win3D.setWindowTitle("3D Face detected (Scanned points)");
1585 
1586  win3D.resize(400, 300);
1587 
1588  win3D.setCameraAzimuthDeg(140);
1589  win3D.setCameraElevationDeg(20);
1590  win3D.setCameraZoom(6.0);
1591  win3D.setCameraPointingToPoint(2.5, 0, 0);
1592 
1594  mrpt::make_aligned_shared<mrpt::opengl::CPointCloudColoured>();
1595  gl_points->setPointSize(6);
1596 
1598 
1599  if (meanPos != nullptr)
1600  {
1601  for (size_t i = 0; i < 3; i++)
1602  for (size_t j = 0; j < 3; j++)
1603  {
1604  CSphere::Ptr sphere =
1605  mrpt::make_aligned_shared<CSphere>(0.005f);
1606  sphere->setLocation(meanPos[i][j]);
1607  sphere->setColor(TColorf(0, 1, 0));
1608  scene->insert(sphere);
1609  }
1610  }
1611 
1612  vector<TSegment3D> sgms;
1613  sgms.push_back(TSegment3D(meanPos[0][0], meanPos[0][1]));
1614  sgms.push_back(TSegment3D(meanPos[0][1], meanPos[0][2]));
1615  sgms.push_back(TSegment3D(meanPos[1][0], meanPos[1][1]));
1616  sgms.push_back(TSegment3D(meanPos[1][1], meanPos[1][2]));
1617  sgms.push_back(TSegment3D(meanPos[2][0], meanPos[2][1]));
1618  sgms.push_back(TSegment3D(meanPos[2][1], meanPos[2][2]));
1619  sgms.push_back(TSegment3D(meanPos[0][0], meanPos[1][1]));
1620  sgms.push_back(TSegment3D(meanPos[1][1], meanPos[2][2]));
1621  sgms.push_back(TSegment3D(meanPos[2][0], meanPos[1][1]));
1622  sgms.push_back(TSegment3D(meanPos[1][1], meanPos[0][2]));
1624  mrpt::make_aligned_shared<mrpt::opengl::CSetOfLines>(sgms);
1625  lines->setColor(0, 0, 1, 1);
1626  lines->setLineWidth(10);
1627 
1628  scene->insert(lines);
1629 
1630  scene->insert(gl_points);
1631  scene->insert(mrpt::make_aligned_shared<mrpt::opengl::CGridPlaneXY>());
1632  scene->insert(mrpt::make_aligned_shared<mrpt::opengl::CAxis>(
1633  -5, -5, -5, 5, 5, 5, 2.5, 3, true));
1634 
1635  CColouredPointsMap pntsMap;
1636 
1637  vector<float> xs, ys, zs;
1638 
1639  for (size_t i = 0; i < 9; i++)
1640  for (unsigned int j = 0; j < regions[i].size(); j++)
1641  {
1642  xs.push_back(regions[i][j].x);
1643  ys.push_back(regions[i][j].y);
1644  zs.push_back(regions[i][j].z);
1645  }
1646 
1647  pntsMap.setAllPoints(xs, ys, zs);
1648 
1649  int cont = 0;
1650  float colors[9][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1},
1651  {1, 1, 0}, {1, 0, 1}, {0, 1, 1},
1652  {0.5f, 0.25f, 0}, {0.5f, 0, 0.25f}, {0, 0.35f, 0.5f}};
1653  for (size_t i = 0; i < 9; i++)
1654  {
1655  float R = colors[i][0];
1656  float G = colors[i][1];
1657  float B = colors[i][2];
1658 
1659  for (unsigned int j = 0; j < regions[i].size(); j++, cont++)
1660  pntsMap.setPointColor(cont, R, G, B);
1661  }
1662 
1663  gl_points->loadFromPointsMap(&pntsMap);
1664  // gl_points->setColorA(0.5);
1665 
1666  win3D.unlockAccess3DScene();
1667  win3D.repaint();
1668 
1669  system::pause();
1670 }
1671 
1672 //------------------------------------------------------------------------
1673 // experimental_segmentFace
1674 //------------------------------------------------------------------------
1675 
1678 {
1679  const unsigned int faceWidth = face.intensityImage.getWidth();
1680  const unsigned int faceHeight = face.intensityImage.getHeight();
1681 
1682  region.setSize(faceWidth, faceHeight, true);
1683 
1684  unsigned int x1 = ceil(faceWidth * 0.4);
1685  unsigned int x2 = floor(faceWidth * 0.6);
1686  unsigned int y1 = ceil(faceHeight * 0.4);
1687  unsigned int y2 = floor(faceHeight * 0.6);
1688 
1689  region.setSize(faceHeight, faceWidth);
1690  CMatrixTemplate<size_t> toExpand;
1691  toExpand.setSize(faceHeight, faceWidth, true);
1692 
1693  unsigned int cont = (y1 <= 1 ? 0 : faceHeight * (y1 - 1));
1694 
1695  // int total = 0; // JL: Unused var
1696  // int numPoints = 0; // JL: Unused var
1697 
1699  // Normalize the image
1701  range2D *= 1.0f / 5;
1702  img.setFromMatrix(range2D);
1703 
1704  // INITIALIZATION
1705  for (unsigned int i = y1; i <= y2; i++)
1706  {
1707  cont += x1;
1708 
1709  for (unsigned int j = x1; j <= x2; j++, cont++)
1710  {
1711  if (*(face.confidenceImage.get_unsafe(j, i, 0)) >
1713  {
1714  // unsigned char *c = img.get_unsafe(i,j);
1715  // size_t value = (size_t)*c;
1716  // total += value;
1717  //++numPoints;
1718  toExpand.set_unsafe(i, j, 1);
1719  }
1720  }
1721  cont += faceWidth - x2;
1722  }
1723 
1724  // int mean = total / numPoints;
1725 
1726  // cout << "Mean: " << mean << endl;
1727  // system::pause();
1728 
1729  // UMBRALIZATION
1730  /*
1731  for ( unsigned int row = 0; row < faceWidth; row++ )
1732  {
1733  for ( unsigned int col = 0; col < faceHeight; col++ )
1734  {
1735  unsigned char *c = img.get_unsafe(row,col);
1736  size_t value = (size_t)*c;
1737 
1738  if ( ( value < mean+7 ) && ( value > mean-7 ) )
1739  {
1740  region.set_unsafe( row, col, true );
1741  }else{
1742  img.setPixel( row, col, 0 );
1743  }
1744  }
1745  }
1746  */
1747 
1748  // REGIONS GROWING
1749 
1750  bool newExpanded = true;
1751 
1752  while (newExpanded)
1753  {
1754  newExpanded = false;
1755 
1756  for (size_t row = 0; row < faceHeight; row++)
1757  {
1758  for (size_t col = 0; col < faceWidth; col++)
1759  {
1760  // cout << toExpand.get_unsafe( row, col ) << "" ;
1761 
1762  if (toExpand.get_unsafe(row, col) == 1)
1763  {
1764  region.set_unsafe(row, col, true);
1765 
1766  unsigned char* c = img.get_unsafe(col, row);
1767  int value = (int)*c;
1768 
1769  if ((row > 0) && (toExpand.get_unsafe(row - 1, col) != 2))
1770  {
1771  unsigned char* c = img.get_unsafe(col, row - 1);
1772  int value2 = (int)*c;
1773  if (abs(value - value2) < 2)
1774  {
1775  toExpand.set_unsafe(row - 1, col, 1);
1776  newExpanded = true;
1777  }
1778  }
1779 
1780  if ((row < faceWidth - 1) &&
1781  (toExpand.get_unsafe(row + 1, col) != 2))
1782  {
1783  unsigned char* c = img.get_unsafe(col, row + 1);
1784  int value2 = (int)*c;
1785  if (abs(value - value2) < 2)
1786  {
1787  toExpand.set_unsafe(row + 1, col, 1);
1788  newExpanded = true;
1789  }
1790  }
1791 
1792  if ((col > 0) && (toExpand.get_unsafe(row, col - 1) != 2))
1793  {
1794  unsigned char* c = img.get_unsafe(col - 1, row);
1795  int value2 = (int)*c;
1796  if (abs(value - value2) < 2)
1797  {
1798  toExpand.set_unsafe(row, col - 1, 1);
1799  newExpanded = true;
1800  }
1801  }
1802 
1803  if ((col < faceHeight - 1) &&
1804  (toExpand.get_unsafe(row, col + 1) != 2))
1805  {
1806  unsigned char* c = img.get_unsafe(col + 1, row);
1807  int value2 = (int)*c;
1808  if (abs(value - value2) < 2)
1809  {
1810  toExpand.set_unsafe(row, col + 1, 1);
1811  newExpanded = true;
1812  }
1813  }
1814 
1815  toExpand.set_unsafe(row, col, 2);
1816  }
1817  }
1818  }
1819  }
1820 
1821  for (unsigned int row = 0; row < faceHeight; row++)
1822  {
1823  for (unsigned int col = 0; col < faceWidth; col++)
1824  {
1825  if (!(region.get_unsafe(row, col)))
1826  {
1827  img.setPixel(col, row, 0);
1828  }
1829  }
1830  }
1831 
1832  // Uncomment if you want to see the resultant region segmented
1833  if (m_measure.faceNum >= 314)
1834  {
1835  CDisplayWindow win("Live video");
1836 
1837  win.showImage(img);
1838  system::pause();
1839  }
1840 }
1841 
1842 //------------------------------------------------------------------------
1843 // experimental_calcHist
1844 //------------------------------------------------------------------------
1845 
1847  const CImage& face, const size_t& c1, const size_t& r1, const size_t& c2,
1848  const size_t& r2, CMatrixTemplate<unsigned int>& hist)
1849 {
1850  TImageSize size;
1851  face.getSize(size);
1852  for (size_t row = r1; row <= r2; row++)
1853  for (size_t col = c1; col <= c2; col++)
1854  {
1855  unsigned char* c = face.get_unsafe(col, row);
1856  size_t value = (size_t)*c;
1857  int count = hist.get_unsafe(0, value) + 1;
1858  hist.set_unsafe(0, value, count);
1859  }
1860 }
1861 
1862 //------------------------------------------------------------------------
1863 // experimental_showMeasurements
1864 //------------------------------------------------------------------------
1865 
1867 {
1868  // This method execution time is not critical because it's executed only at
1869  // the end
1870  // or a few times in user application
1871 
1872  ofstream f;
1873  f.open("statistics.txt", ofstream::app);
1874 
1875  if (m_measure.lessEigenVals.size() > 0)
1876  {
1877  double meanEigenVal, stdEigenVal;
1878  double minEigenVal = *min_element(
1880  double maxEigenVal = *max_element(
1882 
1883  meanAndStd(m_measure.lessEigenVals, meanEigenVal, stdEigenVal);
1884 
1885  cout << endl
1886  << "Statistical data about eigen values calculated of regions "
1887  "detected as faces"
1888  << endl;
1889  cout << "Min eigenVal: " << minEigenVal << endl;
1890  cout << "Max eigenVal: " << maxEigenVal << endl;
1891  cout << "Mean eigenVal: " << meanEigenVal << endl;
1892  cout << "Standard Desv: " << stdEigenVal << endl;
1893 
1895  {
1896  f << endl
1897  << "Statistical data about eigen values calculated of regions "
1898  "detected as faces"
1899  << endl;
1900  f << "Min eigenVal: " << minEigenVal << endl;
1901  f << "Max eigenVal: " << maxEigenVal << endl;
1902  f << "Mean eigenVal: " << meanEigenVal << endl;
1903  f << "Standard Desv: " << stdEigenVal << endl;
1904  }
1905  }
1906 
1907  if (m_measure.sumDistances.size() > 0)
1908  {
1909  double meanSumDist, stdSumDist;
1910  double minSumDist = *min_element(
1911  m_measure.sumDistances.begin(), m_measure.sumDistances.end());
1912  double maxSumDist = *max_element(
1913  m_measure.sumDistances.begin(), m_measure.sumDistances.end());
1914 
1915  meanAndStd(m_measure.sumDistances, meanSumDist, stdSumDist);
1916 
1917  cout << endl << "Statistical data about sum of distances" << endl;
1918  cout << "Min sumDistances: " << minSumDist << endl;
1919  cout << "Max sumDistances: " << maxSumDist << endl;
1920  cout << "Mean sumDistances: " << meanSumDist << endl;
1921  cout << "Standard Desv: " << stdSumDist << endl;
1922 
1924  {
1925  f << endl << "Statistical data about sum of distances" << endl;
1926  f << "Min sumDistances: " << minSumDist << endl;
1927  f << "Max sumDistances: " << maxSumDist << endl;
1928  f << "Mean sumDistances: " << meanSumDist << endl;
1929  f << "Standard Desv: " << stdSumDist << endl;
1930  }
1931  }
1932 
1933  if (m_measure.errorEstimations.size() > 0)
1934  {
1935  double meanEstimationErr, stdEstimationErr;
1936  double minEstimationErr = *min_element(
1937  m_measure.errorEstimations.begin(),
1938  m_measure.errorEstimations.end());
1939  double maxEstimationErr = *max_element(
1940  m_measure.errorEstimations.begin(),
1941  m_measure.errorEstimations.end());
1942 
1943  meanAndStd(
1944  m_measure.errorEstimations, meanEstimationErr, stdEstimationErr);
1945 
1946  cout << endl
1947  << "Statistical data about estimation error adjusting a plane of "
1948  "regions detected as faces"
1949  << endl;
1950  cout << "Min estimation: " << minEstimationErr << endl;
1951  cout << "Max estimation: " << maxEstimationErr << endl;
1952  cout << "Mean estimation: " << meanEstimationErr << endl;
1953  cout << "Standard Desv: " << stdEstimationErr << endl;
1954 
1956  {
1957  f << endl
1958  << "Statistical data about estimation error adjusting a plane of "
1959  "regions detected as faces"
1960  << endl;
1961  f << "Min estimation: " << minEstimationErr << endl;
1962  f << "Max estimation: " << maxEstimationErr << endl;
1963  f << "Mean estimation: " << meanEstimationErr << endl;
1964  f << "Standard Desv: " << stdEstimationErr << endl;
1965  }
1966  }
1967 
1968  cout << endl << "Data about number of faces" << endl;
1969  cout << "Possible faces detected: " << m_measure.numPossibleFacesDetected
1970  << endl;
1971  cout << "Real faces detected: " << m_measure.numRealFacesDetected << endl;
1972 
1973  if (m_meanHist.size() > 0)
1974  {
1975  double minHist = *min_element(m_meanHist.begin(), m_meanHist.end());
1976  double maxHist = *max_element(m_meanHist.begin(), m_meanHist.end());
1977  double meanHist;
1978  double stdHist;
1979  meanAndStd(m_meanHist, meanHist, stdHist);
1980 
1981  cout << endl << "Mean hist: " << meanHist << endl;
1982  cout << "Min hist: " << minHist << endl;
1983  cout << "Max hist: " << maxHist << endl;
1984  cout << "Stdv: " << stdHist << endl;
1985  }
1986 
1988  {
1989  f << endl << "Data about number of faces" << endl;
1990  f << "Possible faces detected: " << m_measure.numPossibleFacesDetected
1991  << endl;
1992  f << "Real faces detected: " << m_measure.numRealFacesDetected << endl;
1993  }
1994 
1996  f << endl << m_timeLog.getStatsAsText();
1997 
1998  f.close();
1999 
2001 }
2002 
2003 //------------------------------------------------------------------------
2004 // debug_returnResults
2005 //------------------------------------------------------------------------
2006 
2008  const std::vector<uint32_t>& falsePositives,
2009  const std::vector<uint32_t>& ignore, unsigned int& falsePositivesDeleted,
2010  unsigned int& realFacesDeleted)
2011 {
2012  const unsigned int numDeleted = m_measure.deletedRegions.size();
2013  const unsigned int numFalsePositives = falsePositives.size();
2014  const unsigned int numIgnored = ignore.size();
2015  unsigned int ignoredDetected = 0;
2016 
2017  falsePositivesDeleted = 0;
2018 
2019  for (unsigned int i = 0; i < numDeleted; i++)
2020  {
2021  unsigned int region = m_measure.deletedRegions[i];
2022 
2023  bool falsePositive = false;
2024 
2025  unsigned int j = 0;
2026  while (!falsePositive && (j < numFalsePositives))
2027  {
2028  if (region == falsePositives[j]) falsePositive = true;
2029  j++;
2030  }
2031 
2032  if (falsePositive)
2033  falsePositivesDeleted++;
2034  else
2035  {
2036  bool igno = false;
2037 
2038  j = 0;
2039  while (!igno && (j < numIgnored))
2040  {
2041  if (region == ignore[j]) igno = true;
2042  j++;
2043  }
2044 
2045  if (igno) ignoredDetected++;
2046  }
2047  }
2048 
2049  realFacesDeleted = numDeleted - falsePositivesDeleted - ignoredDetected;
2050 
2051  m_measure.faceNum = 0;
2052  m_measure.deletedRegions.clear();
2053 }
const T & get_unsafe(size_t row, size_t col) const
Fast but unsafe method to read a value from the matrix.
void meanAndStd(VEC &outMeanVector, VEC &outStdVector, const bool unbiased_variance=true) const
Computes a row with the mean values of each column in the matrix and the associated vector with the s...
GLuint GLuint GLsizei count
Definition: glext.h:3528
std::thread m_thread_checkIfFacePlaneCov
Thread that execute checkIfFacePlaneCov filter.
void unlockAccess3DScene()
Unlocks the access to the internal 3D scene.
bool m_end_threads
Indicates to all threads that must finish their execution.
#define MRPT_START
Definition: exceptions.h:262
GLdouble GLdouble z
Definition: glext.h:3872
void getZoneAsObs(CObservation3DRangeScan &obs, const unsigned int &r1, const unsigned int &r2, const unsigned int &c1, const unsigned int &c2)
Extract a ROI of the 3D observation as a new one.
Declares a matrix of booleans (non serializable).
#define MRPT_TRY_END
The end of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an ex...
Definition: exceptions.h:231
CCascadeClassifierDetection cascadeClassifier
bool m_checkIfFaceRegions_res
Save result of checkIfFaceRegions filter.
void debug_returnResults(const std::vector< uint32_t > &falsePositives, const std::vector< uint32_t > &ignore, unsigned int &falsePositivesDeleted, unsigned int &realFacesDeleted)
void setWindowTitle(const std::string &str) override
Changes the window title.
void experimental_viewFacePointsAndEigenVects(const std::vector< mrpt::math::CArrayDouble< 3 >> &pointsVector, const mrpt::math::CMatrixDouble &eigenVect, const mrpt::math::CVectorDouble &eigenVal)
mrpt::opengl::COpenGLScene::Ptr & get3DSceneAndLock()
Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introductio...
void resize(unsigned int width, unsigned int height) override
Resizes the window, stretching the image to fit into the display area.
const double G
static void dummy_checkIfDiagonalSurface(CFaceDetection *obj)
std::thread m_thread_checkIfDiagonalSurface
Thread that execute checkIfDiagonalSurface filter.
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
GLintptr offset
Definition: glext.h:3925
This file implements several operations that operate element-wise on individual or pairs of container...
CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...
Definition: CArrayNumeric.h:25
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement, as from a time-of-flight range camera or any other RGBD sensor.
struct mrpt::detectors::CFaceDetection::TTestsOptions m_testsOptions
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
Definition: eigen_frwds.h:44
std::vector< double > m_meanHist
size_t checkRelativePosition(const mrpt::math::TPoint3D &p1, const mrpt::math::TPoint3D &p2, const mrpt::math::TPoint3D &p, double &dist)
virtual void init(const mrpt::config::CConfigFileBase &cfg)
Initialize cascade classifier detection.
STL namespace.
std::vector< CDetectableObject::Ptr > vector_detectable_object
std::promise< void > m_enter_checkIfFacePlaneCov
Indicates to thread_checkIfFacePlaneCov that exist a new face to analyze.
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
mrpt::obs::CObservation3DRangeScan m_lastFaceDetected
Last face detected.
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
std::string getStatsAsText(const size_t column_width=80) const
Dump all stats to a multi-line text string.
GLsizei const GLfloat * points
Definition: glext.h:5339
mrpt::math::CMatrix rangeImage
If hasRangeImage=true, a matrix of floats with the range data as captured by the camera (in meters) ...
vector< std::vector< uint32_t > > falsePositives
#define MRPT_TRY_START
The start of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an ...
Definition: exceptions.h:224
std::thread m_thread_checkIfFaceRegions
Thread that execute checkIfFaceRegions filter.
std::promise< void > m_leave_checkIfFaceRegions
Indicates to main thread that thread_checkIfFaceRegions has been completed analisis of the last face ...
This class allows loading and storing values and vectors of different types from a configuration text...
This base provides a set of functions for maths stuff.
3D segment, consisting of two points.
bool checkIfDiagonalSurface2(mrpt::obs::CObservation3DRangeScan *face)
void experimental_calcHist(const mrpt::img::CImage &face, const size_t &c1, const size_t &r1, const size_t &c2, const size_t &r2, mrpt::math::CMatrixTemplate< unsigned int > &hist)
const GLubyte * c
Definition: glext.h:6313
double distanceTo(const TPoint3D &p) const
Point-to-point distance.
void setAllPoints(const std::vector< float > &X, const std::vector< float > &Y, const std::vector< float > &Z)
Set all the points at once from vectors with X,Y and Z coordinates.
Definition: CPointsMap.h:653
GLint GLvoid * img
Definition: glext.h:3763
bool checkIfFacePlaneCov(mrpt::obs::CObservation3DRangeScan *face)
This class creates a window as a graphical user interface (GUI) for displaying images to the user...
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
GLuint GLuint end
Definition: glext.h:3528
size_t rows() const
Number of rows in the matrix.
virtual void init(const mrpt::config::CConfigFileBase &cfg)
Initialize the object with parameters loaded from the given config source.
A pair (x,y) of pixel coordinates (integer resolution).
Definition: TPixelCoord.h:37
This namespace contains representation of robot actions and observations.
bool checkIfFaceRegions(mrpt::obs::CObservation3DRangeScan *face)
3D Plane, represented by its equation
void experimental_segmentFace(const mrpt::obs::CObservation3DRangeScan &face, mrpt::math::CMatrixTemplate< bool > &region)
double getRegressionPlane(const std::vector< TPoint3D > &points, TPlane &plane)
Using eigenvalues, gets the best fitting plane for a set of 3D points.
Definition: geometry.cpp:2165
bool checkIfDiagonalSurface(mrpt::obs::CObservation3DRangeScan *face)
double x
X,Y,Z coordinates.
double read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound=false) const
Specific class for face detection.
double leave(const char *func_name)
End of a named section.
A map of 2D/3D points with individual colours (RGB).
std::promise< void > m_leave_checkIfFacePlaneCov
Indicates to main thread that thread_checkIfFacePlaneCov has been completed analisis of the last face...
size_t cols() const
Number of columns in the matrix.
mrpt::gui::CDisplayWindow3D::Ptr win
void set_unsafe(size_t row, size_t col, const T &v)
Fast but unsafe method to write a value in the matrix.
bool hasPoints3D
true means the field points3D contains valid data.
std::promise< void > m_enter_checkIfDiagonalSurface
Indicates to thread_checkIfDiagonalSurface that exist a new face to analyze.
void pause(const std::string &msg=std::string("Press any key to continue...")) noexcept
Shows the message "Press any key to continue" (or other custom message) to the current standard outpu...
Definition: os.cpp:428
struct mrpt::detectors::CFaceDetection::TMeasurement m_measure
void enable(bool enabled=true)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
bool checkIfFacePlane(mrpt::obs::CObservation3DRangeScan *face)
void experimental_viewFacePointsScanned(const std::vector< float > &xs, const std::vector< float > &ys, const std::vector< float > &zs)
const float R
virtual void detectObjects_Impl(const mrpt::obs::CObservation *obs, vector_detectable_object &detected)
Declares a class that represents any robot&#39;s observation.
Definition: CObservation.h:43
mrpt::system::CTimeLogger m_timeLog
bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
#define IS_CLASS(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::rtti::CObject) is of the give...
Definition: CObject.h:102
GLenum GLenum GLvoid * row
Definition: glext.h:3576
#define MRPT_END
Definition: exceptions.h:266
A RGB color - floats in the range [0,1].
Definition: TColor.h:77
static void dummy_checkIfFacePlaneCov(CFaceDetection *obj)
std::promise< void > m_leave_checkIfDiagonalSurface
Indicates to main thread that thread_checkIfDiagonalSurface has been completed analisis of the last f...
void setCameraZoom(float zoom)
Changes the camera parameters programmatically.
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
static void dummy_checkIfFaceRegions(CFaceDetection *obj)
GLenum GLint GLint y
Definition: glext.h:3538
void setSize(size_t row, size_t col, bool zeroNewElements=false)
Changes the size of matrix, maintaining the previous contents.
Eigen::Matrix< typename MATRIX::Scalar, MATRIX::ColsAtCompileTime, MATRIX::ColsAtCompileTime > cov(const MATRIX &v)
Computes the covariance matrix from a list of samples in an NxM matrix, where each row is a sample...
Definition: ops_matrices.h:148
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
GLsizei const GLfloat * value
Definition: glext.h:4117
GLsizeiptr size
Definition: glext.h:3923
std::promise< void > m_enter_checkIfFaceRegions
Indicates to thread_checkIfFaceRegions that exist a new face to analyze.
GLuint res
Definition: glext.h:7268
GLenum GLint x
Definition: glext.h:3538
GLuint start
Definition: glext.h:3528
void repaint()
Repaints the window.
Lightweight 3D point.
std::shared_ptr< CDetectable3D > Ptr
bool m_checkIfDiagonalSurface_res
Save result of checkIfDiagonalSurface filter.
GLfloat GLfloat p
Definition: glext.h:6305
void detectObjects(const mrpt::obs::CObservation::Ptr obs, vector_detectable_object &detected)
struct mrpt::detectors::CFaceDetection::TOptions m_options
bool m_checkIfFacePlaneCov_res
Save result of checkIfFacePlaneCov filter.
double distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
Definition: geometry.cpp:1891
void setCameraAzimuthDeg(float deg)
Changes the camera parameters programmatically.
void enter(const char *func_name)
Start of a named section.
GLenum GLuint GLint GLenum face
Definition: glext.h:8194
void setPointColor(size_t index, float R, float G, float B)
Changes just the color of a given point from the map.
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:130
void experimental_viewRegions(const std::vector< mrpt::math::TPoint3D > regions[9], const mrpt::math::TPoint3D meanPos[3][3])
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically.
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020