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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019