44 CFaceDetection::CFaceDetection()
46 m_measure.numPossibleFacesDetected = 0;
47 m_measure.numRealFacesDetected = 0;
49 m_measure.faceNum = 0;
57 CFaceDetection::~CFaceDetection()
63 m_enter_checkIfFacePlaneCov.set_value();
64 m_enter_checkIfFaceRegions.set_value();
65 m_enter_checkIfDiagonalSurface.set_value();
67 m_thread_checkIfFaceRegions.join();
68 m_thread_checkIfFacePlaneCov.join();
69 m_thread_checkIfDiagonalSurface.join();
77 m_options.confidenceThreshold =
78 cfg.
read_int(
"FaceDetection",
"confidenceThreshold", 240);
79 m_options.multithread = cfg.
read_bool(
"FaceDetection",
"multithread",
true);
80 m_options.useCovFilter =
81 cfg.
read_bool(
"FaceDetection",
"useCovFilter",
true);
82 m_options.useRegionsFilter =
83 cfg.
read_bool(
"FaceDetection",
"useRegionsFilter",
true);
84 m_options.useSizeDistanceRelationFilter =
85 cfg.
read_bool(
"FaceDetection",
"useSizeDistanceRelationFilter",
true);
86 m_options.useDiagonalDistanceFilter =
87 cfg.
read_bool(
"FaceDetection",
"useDiagonalDistanceFilter",
true);
89 m_testsOptions.planeThreshold =
90 cfg.
read_double(
"FaceDetection",
"planeThreshold", 50);
91 m_testsOptions.planeTest_eigenVal_top =
92 cfg.
read_double(
"FaceDetection",
"planeTest_eigenVal_top", 0.011);
93 m_testsOptions.planeTest_eigenVal_bottom =
94 cfg.
read_double(
"FaceDetection",
"planeTest_eigenVal_bottom", 0.0002);
95 m_testsOptions.regionsTest_sumDistThreshold_top = cfg.
read_double(
96 "FaceDetection",
"regionsTest_sumDistThreshold_top", 0.5);
97 m_testsOptions.regionsTest_sumDistThreshold_bottom = cfg.
read_double(
98 "FaceDetection",
"regionsTest_sumDistThreshold_bottom", 0.04);
100 m_measure.takeTime = cfg.
read_bool(
"FaceDetection",
"takeTime",
false);
101 m_measure.takeMeasures =
102 cfg.
read_bool(
"FaceDetection",
"takeMeasures",
false);
103 m_measure.saveMeasurementsToFile =
104 cfg.
read_bool(
"FaceDetection",
"saveMeasurementsToFile",
false);
107 if (m_options.multithread)
109 if (m_options.useRegionsFilter)
110 m_thread_checkIfFaceRegions =
111 std::thread(dummy_checkIfFaceRegions,
this);
112 if (m_options.useCovFilter)
113 m_thread_checkIfFacePlaneCov =
114 std::thread(dummy_checkIfFacePlaneCov,
this);
115 if (m_options.useSizeDistanceRelationFilter ||
116 m_options.useDiagonalDistanceFilter)
117 m_thread_checkIfDiagonalSurface =
118 std::thread(dummy_checkIfDiagonalSurface,
this);
120 m_checkIfFacePlaneCov_res =
false;
121 m_checkIfFaceRegions_res =
true;
122 m_checkIfDiagonalSurface_res =
true;
125 cascadeClassifier.init(cfg);
131 void CFaceDetection::detectObjects_Impl(
141 if (m_measure.takeTime) m_timeLog.enter(
"Detection time");
144 cascadeClassifier.detectObjects(obs, localDetected);
148 if (m_measure.takeTime) m_timeLog.leave(
"Detection time");
151 m_measure.numPossibleFacesDetected += localDetected.size();
159 if (m_measure.takeTime) m_timeLog.enter(
"Check if real face time");
168 vector<size_t> deleteDetected;
172 for (
unsigned int i = 0; i < localDetected.size(); i++)
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;
183 o.getZoneAsObs(m_lastFaceDetected, r1, r2, c1, c2);
185 if (m_options.multithread)
189 if (m_measure.takeTime)
190 m_timeLog.enter(
"Multithread filters application");
194 if (m_options.useCovFilter)
195 m_enter_checkIfFacePlaneCov.set_value();
196 if (m_options.useRegionsFilter)
197 m_enter_checkIfFaceRegions.set_value();
198 if (m_options.useSizeDistanceRelationFilter ||
199 m_options.useDiagonalDistanceFilter)
200 m_enter_checkIfDiagonalSurface.set_value();
203 if (m_options.useCovFilter)
204 m_leave_checkIfFacePlaneCov.get_future().wait();
205 if (m_options.useRegionsFilter)
206 m_leave_checkIfFaceRegions.get_future().wait();
207 if (m_options.useSizeDistanceRelationFilter ||
208 m_options.useDiagonalDistanceFilter)
209 m_leave_checkIfDiagonalSurface.get_future().wait();
212 if (!m_checkIfFacePlaneCov_res ||
213 !m_checkIfFaceRegions_res ||
214 !m_checkIfDiagonalSurface_res)
215 deleteDetected.push_back(i);
219 if (m_measure.takeTime)
220 m_timeLog.leave(
"Multithread filters application");
229 if (m_measure.takeTime)
230 m_timeLog.enter(
"Secuential filters application");
244 if (m_options.useCovFilter &&
245 !checkIfFacePlaneCov(&m_lastFaceDetected))
247 deleteDetected.push_back(i);
251 m_options.useRegionsFilter &&
252 !checkIfFaceRegions(&m_lastFaceDetected))
254 deleteDetected.push_back(i);
258 (m_options.useSizeDistanceRelationFilter ||
259 m_options.useDiagonalDistanceFilter) &&
260 !checkIfDiagonalSurface(&m_lastFaceDetected))
262 deleteDetected.push_back(i);
272 m_measure.deletedRegions.push_back(m_measure.faceNum);
279 if (m_measure.takeTime)
280 m_timeLog.leave(
"Secuential filters application");
286 for (
unsigned int i = deleteDetected.size(); i > 0; i--)
288 localDetected.begin() + deleteDetected[i - 1]);
292 for (
const auto& i : localDetected)
295 new CDetectable3D(std::dynamic_pointer_cast<CDetectable2D>(i)));
296 detected.push_back(object3d);
301 if (m_measure.takeTime) m_timeLog.leave(
"Check if real face time");
306 detected = localDetected;
312 m_measure.numRealFacesDetected += detected.size();
325 size_t N =
face->points3D_x.size();
329 for (
size_t i = 0; i < N; i++)
331 face->points3D_x.at(i),
face->points3D_y.at(i),
332 face->points3D_z.at(i));
339 if (m_measure.takeMeasures)
340 m_measure.errorEstimations.push_back(
352 obj->thread_checkIfFacePlaneCov();
355 void CFaceDetection::thread_checkIfFacePlaneCov()
359 m_enter_checkIfFacePlaneCov.get_future().wait();
361 if (m_end_threads)
break;
364 m_checkIfFacePlaneCov_res = checkIfFacePlaneCov(&m_lastFaceDetected);
366 m_leave_checkIfFacePlaneCov.set_value();
379 if (m_measure.takeTime)
380 m_timeLog.enter(
"Check if face plane: covariance");
384 const unsigned int faceWidth =
face->intensityImage.getWidth();
385 const unsigned int faceHeight =
face->intensityImage.getHeight();
388 const bool confidence =
face->hasConfidenceImage;
391 vector<CVectorFixedDouble<3>> pointsVector;
394 experimental_segmentFace(*
face, region);
396 for (
unsigned int j = 0; j < faceHeight; j++)
398 for (
unsigned int k = 0; k < faceWidth; k++)
407 m_options.confidenceThreshold) &&
410 int position = faceWidth * j + k;
411 aux[0] =
face->points3D_x[position];
412 aux[1] =
face->points3D_y[position];
413 aux[2] =
face->points3D_z[position];
414 pointsVector.push_back(aux);
420 if (pointsVector.empty())
return false;
427 std::vector<double> eVals;
429 cov = covVector<vector<CVectorFixedDouble<3>>,
CMatrixDouble>(pointsVector);
435 if (m_measure.takeMeasures) m_measure.lessEigenVals.push_back(eVals[0]);
437 if (m_measure.takeTime)
438 m_timeLog.leave(
"Check if face plane: covariance");
447 cout << eVals[0] <<
" " << eVals[1] <<
" " << eVals[2] <<
" > ";
448 cout << eVals[0] / eVals[2] << endl;
453 if (m_measure.faceNum >= 314)
454 experimental_viewFacePointsAndEigenVects(pointsVector, eVects, eVals);
459 if (eVals[0] / eVals[2] > 0.06)
478 obj->thread_checkIfFaceRegions();
481 void CFaceDetection::thread_checkIfFaceRegions()
485 m_enter_checkIfFaceRegions.get_future().wait();
487 if (m_end_threads)
break;
490 m_checkIfFaceRegions_res = checkIfFaceRegions(&m_lastFaceDetected);
492 m_leave_checkIfFaceRegions.set_value();
506 if (m_measure.takeTime) m_timeLog.enter(
"Check if face plane: regions");
510 const unsigned int faceWidth =
face->intensityImage.getWidth();
511 const unsigned int faceHeight =
face->intensityImage.getHeight();
514 unsigned int sectionVSize = faceHeight / 3.0;
534 int numPoints[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
536 vector<TPoint3D> regions2[9];
544 experimental_segmentFace(*
face, region);
553 for (
size_t r = 0;
r < region.
rows();
r++)
554 for (
size_t c = 1;
c < region.
cols();
c++)
556 if ((!(region(
r,
c - 1))) && (region(
r,
c)))
560 else if ((region(
r,
c - 1)) && (!(region(
r,
c))))
566 if (
end == 0)
end = faceWidth - 1;
567 if (
end < 3 * (faceWidth / 4))
568 end = 3 * (faceWidth / 4);
570 if (
start > faceWidth / 4)
start = faceWidth / 4;
575 unsigned int utilWidth = faceWidth -
start - (faceWidth -
end);
576 unsigned int c1 = ceil(utilWidth / 3.0 +
start);
577 unsigned int c2 = ceil(2 * (utilWidth / 3.0) +
start);
586 experimental_calcHist(
587 face->intensityImage,
start, 0,
end, ceil(faceHeight * 0.1), hist);
589 size_t countHist = 0;
590 for (
size_t i = 0; i < 60; i++)
592 countHist += hist(0, i);
596 size_t downLimit = faceHeight - 1;
600 upLimit = floor(faceHeight * 0.1);
601 downLimit = floor(faceHeight * 0.9);
612 unsigned int cont = 0;
614 for (
unsigned int r = 0;
r < faceHeight;
r++)
616 for (
unsigned int c = 0;
c < faceWidth;
c++, cont++)
618 if ((
r >= upLimit) && (
r <= downLimit) && (region(
r,
c)) &&
620 m_options.confidenceThreshold) &&
623 unsigned int row, col;
624 if (
r < sectionVSize + upLimit * 0.3)
626 else if (
r < sectionVSize * 2 - upLimit * 0.15)
639 face->points3D_x[cont],
face->points3D_y[cont],
640 face->points3D_z[cont]);
641 meanPos[
row][col] = meanPos[
row][col] + point;
643 ++numPoints[
row][col];
645 if (
row == 0 && col == 0)
646 regions2[0].emplace_back(
647 face->points3D_x[cont],
face->points3D_y[cont],
648 face->points3D_z[cont]);
649 else if (
row == 0 && col == 1)
650 regions2[1].emplace_back(
651 face->points3D_x[cont],
face->points3D_y[cont],
652 face->points3D_z[cont]);
653 else if (
row == 0 && col == 2)
654 regions2[2].emplace_back(
655 face->points3D_x[cont],
face->points3D_y[cont],
656 face->points3D_z[cont]);
657 else if (
row == 1 && col == 0)
658 regions2[3].emplace_back(
659 face->points3D_x[cont],
face->points3D_y[cont],
660 face->points3D_z[cont]);
661 else if (
row == 1 && col == 1)
662 regions2[4].emplace_back(
663 face->points3D_x[cont],
face->points3D_y[cont],
664 face->points3D_z[cont]);
665 else if (
row == 1 && col == 2)
666 regions2[5].emplace_back(
667 face->points3D_x[cont],
face->points3D_y[cont],
668 face->points3D_z[cont]);
669 else if (
row == 2 && col == 0)
670 regions2[6].emplace_back(
671 face->points3D_x[cont],
face->points3D_y[cont],
672 face->points3D_z[cont]);
673 else if (
row == 2 && col == 1)
674 regions2[7].emplace_back(
675 face->points3D_x[cont],
face->points3D_y[cont],
676 face->points3D_z[cont]);
678 regions2[8].emplace_back(
679 face->points3D_x[cont],
face->points3D_y[cont],
680 face->points3D_z[cont]);
689 vector<double> oldPointsX1;
694 if (regions2[0].
size() > 0)
696 for (
auto& i : regions2[0]) oldPointsX1.push_back(i.x);
698 middle1 = floor((
double)oldPointsX1.size() / 2);
700 oldPointsX1.begin(), oldPointsX1.begin() + middle1,
704 vector<double> oldPointsX2;
706 if (regions2[2].
size() > 0)
708 for (
auto& i : regions2[2]) oldPointsX2.push_back(i.x);
710 middle2 = floor((
double)oldPointsX2.size() / 2);
712 oldPointsX2.begin(), oldPointsX2.begin() + middle2,
716 for (
size_t i = 0; i < 3; i++)
717 for (
size_t j = 0; j < 3; j++)
718 if (!numPoints[i][j])
721 meanPos[i][j] = meanPos[i][j] / numPoints[i][j];
723 if (regions2[0].
size() > 0) meanPos[0][0].
x = oldPointsX1.at(middle1);
725 if (regions2[2].
size() > 0) meanPos[0][2].
x = oldPointsX2.at(middle2);
730 vector<double> dist(5);
731 size_t res = checkRelativePosition(
732 meanPos[1][0], meanPos[1][2], meanPos[1][1], dist[0]);
733 res +=
res && checkRelativePosition(
734 meanPos[2][0], meanPos[2][2], meanPos[2][1], dist[1]);
735 res +=
res && checkRelativePosition(
736 meanPos[0][0], meanPos[0][2], meanPos[0][1], dist[2]);
737 res +=
res && checkRelativePosition(
738 meanPos[0][0], meanPos[2][2], meanPos[1][1], dist[3]);
739 res +=
res && checkRelativePosition(
740 meanPos[2][0], meanPos[0][2], meanPos[1][1], dist[4]);
743 f.open(
"dist.txt", ofstream::app);
744 f <<
sum(dist) << endl;
750 else if ((
res = 1) && (
sum(dist) > 0.04))
753 f.open(
"tam.txt", ofstream::app);
754 f << meanPos[0][1].
distanceTo(meanPos[2][1]) << endl;
768 if (m_measure.takeTime) m_timeLog.leave(
"Check if face plane: regions");
792 size_t CFaceDetection::checkRelativePosition(
804 double yIdeal = y1 + (((
x - x1) * (y2 - y1)) / (x2 - x1));
826 obj->thread_checkIfDiagonalSurface();
829 void CFaceDetection::thread_checkIfDiagonalSurface()
833 m_enter_checkIfDiagonalSurface.get_future().wait();
835 if (m_end_threads)
break;
838 m_checkIfDiagonalSurface_res =
839 checkIfDiagonalSurface(&m_lastFaceDetected);
841 m_leave_checkIfDiagonalSurface.set_value();
855 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
856 m_timeLog.enter(
"Check if face plane: diagonal distances");
858 if (m_options.useSizeDistanceRelationFilter && m_measure.takeTime)
859 m_timeLog.enter(
"Check if face plane: size-distance relation");
862 const unsigned int faceWidth =
face->intensityImage.getWidth();
863 const unsigned int faceHeight =
face->intensityImage.getHeight();
867 unsigned int x1 = ceil(faceWidth * 0.25);
868 unsigned int x2 = floor(faceWidth * 0.75);
869 unsigned int y1 = ceil(faceHeight * 0.15);
870 unsigned int y2 = floor(faceHeight * 0.85);
873 unsigned int cont = (y1 == 0 ? 0 : faceHeight * (y1 - 1));
876 valids.
setSize(faceHeight, faceWidth);
881 for (
unsigned int i = y1; i <= y2; i++)
885 for (
unsigned int j = x1; j <= x2; j++, cont++)
888 m_options.confidenceThreshold)
890 sumDepth +=
face->points3D_x[cont];
893 face->points3D_x[cont],
face->points3D_y[cont],
894 face->points3D_z[cont]);
897 cont += faceWidth - x2 - 1;
900 double meanDepth = sumDepth / total;
909 if (m_options.useSizeDistanceRelationFilter)
911 double maxFaceDistance = 0.5 + 1000 / (pow(faceWidth, 1.9));
915 if (m_measure.takeTime)
916 m_timeLog.leave(
"Check if face plane: size-distance relation");
918 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
919 m_timeLog.leave(
"Check if face plane: diagonal distances");
928 if (maxFaceDistance < meanDepth)
943 if (!m_options.useDiagonalDistanceFilter)
return true;
951 f.open(
"relaciones2.txt", ofstream::app);
952 f << meanDepth << endl;
961 cont = (y1 == 1 ? 0 : faceHeight * (y1 - 1));
963 for (
unsigned int i = y1; i <= y2; i++)
967 for (
unsigned int j = x1; j <= x2; j++, cont++)
970 m_options.confidenceThreshold))
976 face->points3D_x[cont],
face->points3D_y[cont],
977 face->points3D_z[cont]);
980 valids(i, j) =
false;
982 cont += faceWidth - x2 - 1;
991 double sumDistances = 0;
997 for (
unsigned int i = y1; i <= y2; i++)
1001 for (
unsigned int j = x1; j <= x2; j++, cont++)
1009 if ((i + 1 <= y2) && (j + 1 <= x2))
1011 if (valids(i + 1, j + 1))
1014 face->points3D_x[cont],
face->points3D_y[cont],
1015 face->points3D_z[cont]);
1016 offsetIndex = cont + faceWidth + 1;
1018 face->points3D_x[offsetIndex],
1019 face->points3D_y[offsetIndex],
1020 face->points3D_z[offsetIndex]));
1024 bool validOffset =
true;
1034 face->points3D_x[cont],
1035 face->points3D_y[cont],
1036 face->points3D_z[cont]);
1037 offsetIndex = cont + faceWidth +
offset;
1039 face->points3D_x[offsetIndex],
1040 face->points3D_y[offsetIndex],
1041 face->points3D_z[offsetIndex]));
1047 validOffset =
false;
1055 cont += faceWidth - x2 - 1;
1060 if (m_measure.takeMeasures)
1061 m_measure.sumDistances.push_back(sumDistances);
1064 fo.open(
"distances.txt", ofstream::app);
1066 fo << sumDistances << endl;
1069 fo.open(
"distances2.txt", ofstream::app);
1070 fo << m_measure.faceNum <<
" " << sumDistances << endl;
1076 double yMax = 3 + 6 / (pow(meanDepth, 2));
1077 double yMin = 1 + 3.8 / (pow(meanDepth + 1.2, 2));
1081 if (m_measure.takeTime)
1082 m_timeLog.leave(
"Check if face plane: diagonal distances");
1085 if (((sumDistances <= yMax) && (sumDistances >= yMin)) && (
res))
1122 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
1123 m_timeLog.enter(
"Check if face plane: diagonal distances");
1125 if (m_options.useSizeDistanceRelationFilter && m_measure.takeTime)
1126 m_timeLog.enter(
"Check if face plane: size-distance relation");
1129 const unsigned int faceWidth =
face->intensityImage.getWidth();
1130 const unsigned int faceHeight =
face->intensityImage.getHeight();
1133 experimental_segmentFace(*
face, region);
1141 for (
unsigned int row = 0;
row < faceHeight;
row++)
1143 for (
unsigned int col = 0; col < faceWidth; col++, cont++)
1145 if ((region(
row, col)) &&
1147 m_options.confidenceThreshold))
1149 sumDepth +=
face->points3D_x[cont];
1152 face->points3D_x[cont],
face->points3D_y[cont],
1153 face->points3D_z[cont]);
1158 double meanDepth = sumDepth / total;
1162 if (m_options.useSizeDistanceRelationFilter)
1164 double maxFaceDistance = 0.5 + 1000 / (pow(faceWidth, 1.9));
1168 if (m_measure.takeTime)
1169 m_timeLog.leave(
"Check if face plane: size-distance relation");
1171 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
1172 m_timeLog.leave(
"Check if face plane: diagonal distances");
1181 if (maxFaceDistance < meanDepth)
1196 if (!m_options.useDiagonalDistanceFilter)
return true;
1204 f.open(
"relaciones2.txt", ofstream::app);
1205 f << meanDepth << endl;
1220 double sumDistances = 0;
1222 size_t offsetIndex = 0;
1226 for (
unsigned int i = 0; i < faceHeight; i++)
1228 for (
unsigned int j = 0; j < faceWidth; j++, cont++)
1233 if ((i + 1 < faceHeight) && (j + 1 < faceWidth))
1235 if (region(i + 1, j + 1))
1238 face->points3D_x[cont],
face->points3D_y[cont],
1239 face->points3D_z[cont]);
1240 offsetIndex = cont + faceWidth + 1;
1242 face->points3D_x[offsetIndex],
1243 face->points3D_y[offsetIndex],
1244 face->points3D_z[offsetIndex]));
1248 bool validOffset =
true;
1253 if ((i +
offset < faceHeight) &&
1254 (j +
offset < faceWidth))
1259 face->points3D_x[cont],
1260 face->points3D_y[cont],
1261 face->points3D_z[cont]);
1262 offsetIndex = cont + faceWidth +
offset;
1264 face->points3D_x[offsetIndex],
1265 face->points3D_y[offsetIndex],
1266 face->points3D_z[offsetIndex]));
1272 validOffset =
false;
1284 if (m_measure.takeMeasures)
1285 m_measure.sumDistances.push_back(sumDistances);
1288 fo.open(
"distances.txt", ofstream::app);
1290 fo << sumDistances << endl;
1300 double yMax = 3 + 11.8 / (pow(meanDepth, 0.9));
1301 double yMin = 1 + 3.8 / (pow(meanDepth + 7, 6));
1305 if (m_measure.takeTime)
1306 m_timeLog.leave(
"Check if face plane: diagonal distances");
1309 if (((sumDistances <= yMax) && (sumDistances >= yMin)) && (
res))
1340 void CFaceDetection::experimental_viewFacePointsScanned(
1343 vector<float> xs, ys, zs;
1345 unsigned int N =
face.points3D_x.size();
1351 for (
unsigned int i = 0; i < N; i++)
1353 xs[i] =
face.points3D_x[i];
1354 ys[i] =
face.points3D_y[i];
1355 zs[i] =
face.points3D_z[i];
1358 experimental_viewFacePointsScanned(xs, ys, zs);
1365 void CFaceDetection::experimental_viewFacePointsScanned(
1366 const vector<TPoint3D>&
points)
1368 vector<float> xs, ys, zs;
1370 unsigned int N =
points.size();
1376 for (
unsigned int i = 0; i < N; i++)
1383 experimental_viewFacePointsScanned(xs, ys, zs);
1390 void CFaceDetection::experimental_viewFacePointsScanned(
1391 const vector<float>& xs,
const vector<float>& ys,
const vector<float>& zs)
1406 gl_points->setPointSize(4.5);
1410 scene->insert(gl_points);
1417 gl_points->loadFromPointsMap(&pntsMap);
1460 void CFaceDetection::experimental_viewFacePointsAndEigenVects(
1462 const CMatrixDouble& eigenVect,
const std::vector<double>& eigenVal)
1464 vector<float> xs, ys, zs;
1466 const size_t size = pointsVector.size();
1472 for (
size_t i = 0; i <
size; i++)
1474 xs[i] = pointsVector[i][0];
1475 ys[i] = pointsVector[i][1];
1476 zs[i] = pointsVector[i][2];
1494 gl_points->setPointSize(4.5);
1498 CSphere::Ptr sphere = std::make_shared<CSphere>(0.005f);
1499 sphere->setLocation(center);
1500 sphere->setColor(
TColorf(0, 1, 0));
1501 scene->insert(sphere);
1503 TPoint3D E1(eigenVect(0, 0), eigenVect(0, 1), eigenVect(0, 2));
1504 TPoint3D E2(eigenVect(1, 0), eigenVect(1, 1), eigenVect(1, 2));
1505 TPoint3D E3(eigenVect(2, 0), eigenVect(2, 1), eigenVect(2, 2));
1509 TPoint3D p1(center + E1 * eigenVal[0] * 100);
1510 TPoint3D p2(center + E2 * eigenVal[1] * 100);
1511 TPoint3D p3(center + E3 * eigenVal[2] * 100);
1514 center.
x, center.
y, center.
z, p1.
x, p1.
y, p1.
z);
1516 center.
x, center.
y, center.
z, p2.
x, p2.
y, p2.
z);
1518 center.
x, center.
y, center.
z, p3.
x, p3.
y, p3.
z);
1520 arrow1->setColor(
TColorf(0, 1, 0));
1521 arrow2->setColor(
TColorf(1, 0, 0));
1522 arrow3->setColor(
TColorf(0, 0, 1));
1524 scene->insert(arrow1);
1525 scene->insert(arrow2);
1526 scene->insert(arrow3);
1538 scene->insert(gl_points);
1545 gl_points->loadFromPointsMap(&pntsMap);
1557 void CFaceDetection::experimental_viewRegions(
1558 const vector<TPoint3D> regions[9],
const TPoint3D meanPos[3][3])
1573 gl_points->setPointSize(6);
1577 if (meanPos !=
nullptr)
1579 for (
size_t i = 0; i < 3; i++)
1580 for (
size_t j = 0; j < 3; j++)
1582 CSphere::Ptr sphere = std::make_shared<CSphere>(0.005f);
1583 sphere->setLocation(meanPos[i][j]);
1584 sphere->setColor(
TColorf(0, 1, 0));
1585 scene->insert(sphere);
1589 vector<TSegment3D> sgms;
1590 sgms.emplace_back(meanPos[0][0], meanPos[0][1]);
1591 sgms.emplace_back(meanPos[0][1], meanPos[0][2]);
1592 sgms.emplace_back(meanPos[1][0], meanPos[1][1]);
1593 sgms.emplace_back(meanPos[1][1], meanPos[1][2]);
1594 sgms.emplace_back(meanPos[2][0], meanPos[2][1]);
1595 sgms.emplace_back(meanPos[2][1], meanPos[2][2]);
1596 sgms.emplace_back(meanPos[0][0], meanPos[1][1]);
1597 sgms.emplace_back(meanPos[1][1], meanPos[2][2]);
1598 sgms.emplace_back(meanPos[2][0], meanPos[1][1]);
1599 sgms.emplace_back(meanPos[1][1], meanPos[0][2]);
1602 lines->setColor(0, 0, 1, 1);
1603 lines->setLineWidth(10);
1605 scene->insert(lines);
1607 scene->insert(gl_points);
1614 vector<float> xs, ys, zs;
1616 for (
size_t i = 0; i < 9; i++)
1617 for (
const auto& j : regions[i])
1627 float colors[9][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1},
1628 {1, 1, 0}, {1, 0, 1}, {0, 1, 1},
1629 {0.5f, 0.25f, 0}, {0.5f, 0, 0.25f}, {0, 0.35f, 0.5f}};
1630 for (
size_t i = 0; i < 9; i++)
1632 float R = colors[i][0];
1633 float G = colors[i][1];
1634 float B = colors[i][2];
1636 for (
unsigned int j = 0; j < regions[i].size(); j++, cont++)
1640 gl_points->loadFromPointsMap(&pntsMap);
1653 void CFaceDetection::experimental_segmentFace(
1656 const unsigned int faceWidth =
face.intensityImage.getWidth();
1657 const unsigned int faceHeight =
face.intensityImage.getHeight();
1659 region.
setSize(faceWidth, faceHeight,
true);
1661 unsigned int x1 = ceil(faceWidth * 0.4);
1662 unsigned int x2 = floor(faceWidth * 0.6);
1663 unsigned int y1 = ceil(faceHeight * 0.4);
1664 unsigned int y2 = floor(faceHeight * 0.6);
1666 region.
setSize(faceHeight, faceWidth);
1668 toExpand.
setSize(faceHeight, faceWidth,
true);
1670 unsigned int cont = (y1 <= 1 ? 0 : faceHeight * (y1 - 1));
1678 range2D *= 1.0f / 5;
1679 img.setFromMatrix(range2D);
1682 for (
unsigned int i = y1; i <= y2; i++)
1686 for (
unsigned int j = x1; j <= x2; j++, cont++)
1689 m_options.confidenceThreshold)
1694 cont += faceWidth - x2;
1699 bool newExpanded =
true;
1703 newExpanded =
false;
1705 for (
size_t row = 0;
row < faceHeight;
row++)
1707 for (
size_t col = 0; col < faceWidth; col++)
1709 if (toExpand(
row, col) == 1)
1711 region(
row, col) =
true;
1715 if ((
row > 0) && (toExpand(
row - 1, col) != 2))
1718 if (abs(
value - value2) < 2)
1720 toExpand(
row - 1, col) = 1;
1725 if ((
row < faceWidth - 1) && (toExpand(
row + 1, col) != 2))
1728 if (abs(
value - value2) < 2)
1730 toExpand(
row + 1, col) = 1;
1735 if ((col > 0) && (toExpand(
row, col - 1) != 2))
1738 if (abs(
value - value2) < 2)
1740 toExpand(
row, col - 1) = 1;
1745 if ((col < faceHeight - 1) && (toExpand(
row, col + 1) != 2))
1748 if (abs(
value - value2) < 2)
1750 toExpand(
row, col + 1) = 1;
1755 toExpand(
row, col) = 2;
1761 for (
unsigned int row = 0;
row < faceHeight;
row++)
1763 for (
unsigned int col = 0; col < faceWidth; col++)
1765 if (!(region(
row, col)))
1767 img.setPixel(col,
row, 0);
1773 if (m_measure.faceNum >= 314)
1786 void CFaceDetection::experimental_calcHist(
1787 const CImage&
face,
const size_t& c1,
const size_t& r1,
const size_t& c2,
1793 for (
size_t col = c1; col <= c2; col++)
1805 void CFaceDetection::experimental_showMeasurements()
1812 f.open(
"statistics.txt", ofstream::app);
1814 if (m_measure.lessEigenVals.size() > 0)
1816 double meanEigenVal, stdEigenVal;
1817 double minEigenVal = *min_element(
1818 m_measure.lessEigenVals.begin(), m_measure.lessEigenVals.end());
1819 double maxEigenVal = *max_element(
1820 m_measure.lessEigenVals.begin(), m_measure.lessEigenVals.end());
1822 meanAndStd(m_measure.lessEigenVals, meanEigenVal, stdEigenVal);
1825 <<
"Statistical data about eigen values calculated of regions " 1828 cout <<
"Min eigenVal: " << minEigenVal << endl;
1829 cout <<
"Max eigenVal: " << maxEigenVal << endl;
1830 cout <<
"Mean eigenVal: " << meanEigenVal << endl;
1831 cout <<
"Standard Desv: " << stdEigenVal << endl;
1833 if (m_measure.saveMeasurementsToFile)
1836 <<
"Statistical data about eigen values calculated of regions " 1839 f <<
"Min eigenVal: " << minEigenVal << endl;
1840 f <<
"Max eigenVal: " << maxEigenVal << endl;
1841 f <<
"Mean eigenVal: " << meanEigenVal << endl;
1842 f <<
"Standard Desv: " << stdEigenVal << endl;
1846 if (m_measure.sumDistances.size() > 0)
1848 double meanSumDist, stdSumDist;
1849 double minSumDist = *min_element(
1850 m_measure.sumDistances.begin(), m_measure.sumDistances.end());
1851 double maxSumDist = *max_element(
1852 m_measure.sumDistances.begin(), m_measure.sumDistances.end());
1854 meanAndStd(m_measure.sumDistances, meanSumDist, stdSumDist);
1856 cout << endl <<
"Statistical data about sum of distances" << endl;
1857 cout <<
"Min sumDistances: " << minSumDist << endl;
1858 cout <<
"Max sumDistances: " << maxSumDist << endl;
1859 cout <<
"Mean sumDistances: " << meanSumDist << endl;
1860 cout <<
"Standard Desv: " << stdSumDist << endl;
1862 if (m_measure.saveMeasurementsToFile)
1864 f << endl <<
"Statistical data about sum of distances" << endl;
1865 f <<
"Min sumDistances: " << minSumDist << endl;
1866 f <<
"Max sumDistances: " << maxSumDist << endl;
1867 f <<
"Mean sumDistances: " << meanSumDist << endl;
1868 f <<
"Standard Desv: " << stdSumDist << endl;
1872 if (m_measure.errorEstimations.size() > 0)
1874 double meanEstimationErr, stdEstimationErr;
1875 double minEstimationErr = *min_element(
1876 m_measure.errorEstimations.begin(),
1877 m_measure.errorEstimations.end());
1878 double maxEstimationErr = *max_element(
1879 m_measure.errorEstimations.begin(),
1880 m_measure.errorEstimations.end());
1883 m_measure.errorEstimations, meanEstimationErr, stdEstimationErr);
1886 <<
"Statistical data about estimation error adjusting a plane of " 1887 "regions detected as faces" 1889 cout <<
"Min estimation: " << minEstimationErr << endl;
1890 cout <<
"Max estimation: " << maxEstimationErr << endl;
1891 cout <<
"Mean estimation: " << meanEstimationErr << endl;
1892 cout <<
"Standard Desv: " << stdEstimationErr << endl;
1894 if (m_measure.saveMeasurementsToFile)
1897 <<
"Statistical data about estimation error adjusting a plane of " 1898 "regions detected as faces" 1900 f <<
"Min estimation: " << minEstimationErr << endl;
1901 f <<
"Max estimation: " << maxEstimationErr << endl;
1902 f <<
"Mean estimation: " << meanEstimationErr << endl;
1903 f <<
"Standard Desv: " << stdEstimationErr << endl;
1907 cout << endl <<
"Data about number of faces" << endl;
1908 cout <<
"Possible faces detected: " << m_measure.numPossibleFacesDetected
1910 cout <<
"Real faces detected: " << m_measure.numRealFacesDetected << endl;
1912 if (m_meanHist.size() > 0)
1914 double minHist = *min_element(m_meanHist.begin(), m_meanHist.end());
1915 double maxHist = *max_element(m_meanHist.begin(), m_meanHist.end());
1920 cout << endl <<
"Mean hist: " << meanHist << endl;
1921 cout <<
"Min hist: " << minHist << endl;
1922 cout <<
"Max hist: " << maxHist << endl;
1923 cout <<
"Stdv: " << stdHist << endl;
1926 if (m_measure.saveMeasurementsToFile)
1928 f << endl <<
"Data about number of faces" << endl;
1929 f <<
"Possible faces detected: " << m_measure.numPossibleFacesDetected
1931 f <<
"Real faces detected: " << m_measure.numRealFacesDetected << endl;
1934 if (m_measure.takeTime && m_measure.saveMeasurementsToFile)
1935 f << endl << m_timeLog.getStatsAsText();
1946 void CFaceDetection::debug_returnResults(
1948 const std::vector<uint32_t>& ignore,
unsigned int& falsePositivesDeleted,
1949 unsigned int& realFacesDeleted)
1951 const unsigned int numDeleted = m_measure.deletedRegions.size();
1953 const unsigned int numIgnored = ignore.size();
1954 unsigned int ignoredDetected = 0;
1956 falsePositivesDeleted = 0;
1958 for (
unsigned int i = 0; i < numDeleted; i++)
1960 unsigned int region = m_measure.deletedRegions[i];
1962 bool falsePositive =
false;
1965 while (!falsePositive && (j < numFalsePositives))
1972 falsePositivesDeleted++;
1978 while (!igno && (j < numIgnored))
1980 if (region == ignore[j]) igno =
true;
1984 if (igno) ignoredDetected++;
1988 realFacesDeleted = numDeleted - falsePositivesDeleted - ignoredDetected;
1990 m_measure.faceNum = 0;
1991 m_measure.deletedRegions.clear();
bool eig(Derived &eVecs, std::vector< Scalar > &eVals, bool sorted=true) const
Computes the eigenvectors and eigenvalues for a square, general matrix.
GLuint GLuint GLsizei count
void unlockAccess3DScene()
Unlocks the access to the internal 3D scene.
A compile-time fixed-size numeric matrix container.
double x
X,Y,Z coordinates.
static Ptr Create(Args &&... args)
#define MRPT_TRY_END
The end of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an ex...
void setWindowTitle(const std::string &str) override
Changes the window title.
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.
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
This file implements several operations that operate element-wise on individual or pairs of container...
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.
std::vector< CDetectableObject::Ptr > vector_detectable_object
GLsizei GLsizei GLuint * obj
static Ptr Create(Args &&... args)
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
GLsizei const GLfloat * points
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 ...
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.
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.
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.
A pair (x,y) of pixel coordinates (integer resolution).
This namespace contains representation of robot actions and observations.
3D Plane, represented by its equation
#define IS_CLASS(obj, class_name)
True if the given reference to object (derived from mrpt::rtti::CObject) is of the given class...
double getRegressionPlane(const std::vector< TPoint3D > &points, TPlane &plane)
Using eigenvalues, gets the best fitting plane for a set of 3D points.
double read_double(const std::string §ion, const std::string &name, double defaultValue, bool failIfNotFound=false) const
Specific class for face detection.
A map of 2D/3D points with individual colours (RGB).
CMatrixDouble cov(const MATRIX &v)
Computes the covariance matrix from a list of samples in an NxM matrix, where each row is a sample...
mrpt::gui::CDisplayWindow3D::Ptr win
size_type rows() const
Number of rows in the matrix.
size_type cols() const
Number of columns in the matrix.
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...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLdouble GLdouble GLdouble r
void meanAndStd(const VECTORLIKE &v, double &out_mean, double &out_std, bool unbiased=true)
Computes the standard deviation of a vector (or all elements of a matrix)
Declares a class that represents any robot's observation.
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
GLenum GLenum GLvoid * row
void setSize(size_t row, size_t col, bool zeroNewElements=false)
Changes the size of matrix, maintaining the previous contents.
A RGB color - floats in the range [0,1].
void setCameraZoom(float zoom)
Changes the camera parameters programmatically.
The namespace for 3D scene representation and rendering.
Classes for creating GUI windows for 2D and 3D visualization.
GLsizei const GLfloat * value
void repaint()
Repaints the window.
This template class provides the basic functionality for a general 2D any-size, resizable container o...
static Ptr Create(Args &&... args)
double distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
static Ptr Create(Args &&... args)
void setCameraAzimuthDeg(float deg)
Changes the camera parameters programmatically.
GLenum GLuint GLint GLenum face
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.
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically.
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.