27 #include <Eigen/Dense>
45 CFaceDetection::CFaceDetection()
47 m_measure.numPossibleFacesDetected = 0;
48 m_measure.numRealFacesDetected = 0;
50 m_measure.faceNum = 0;
58 CFaceDetection::~CFaceDetection()
64 m_enter_checkIfFacePlaneCov.set_value();
65 m_enter_checkIfFaceRegions.set_value();
66 m_enter_checkIfDiagonalSurface.set_value();
68 m_thread_checkIfFaceRegions.join();
69 m_thread_checkIfFacePlaneCov.join();
70 m_thread_checkIfDiagonalSurface.join();
78 m_options.confidenceThreshold =
79 cfg.
read_int(
"FaceDetection",
"confidenceThreshold", 240);
80 m_options.multithread = cfg.
read_bool(
"FaceDetection",
"multithread",
true);
81 m_options.useCovFilter =
82 cfg.
read_bool(
"FaceDetection",
"useCovFilter",
true);
83 m_options.useRegionsFilter =
84 cfg.
read_bool(
"FaceDetection",
"useRegionsFilter",
true);
85 m_options.useSizeDistanceRelationFilter =
86 cfg.
read_bool(
"FaceDetection",
"useSizeDistanceRelationFilter",
true);
87 m_options.useDiagonalDistanceFilter =
88 cfg.
read_bool(
"FaceDetection",
"useDiagonalDistanceFilter",
true);
90 m_testsOptions.planeThreshold =
91 cfg.
read_double(
"FaceDetection",
"planeThreshold", 50);
92 m_testsOptions.planeTest_eigenVal_top =
93 cfg.
read_double(
"FaceDetection",
"planeTest_eigenVal_top", 0.011);
94 m_testsOptions.planeTest_eigenVal_bottom =
95 cfg.
read_double(
"FaceDetection",
"planeTest_eigenVal_bottom", 0.0002);
96 m_testsOptions.regionsTest_sumDistThreshold_top = cfg.
read_double(
97 "FaceDetection",
"regionsTest_sumDistThreshold_top", 0.5);
98 m_testsOptions.regionsTest_sumDistThreshold_bottom = cfg.
read_double(
99 "FaceDetection",
"regionsTest_sumDistThreshold_bottom", 0.04);
101 m_measure.takeTime = cfg.
read_bool(
"FaceDetection",
"takeTime",
false);
102 m_measure.takeMeasures =
103 cfg.
read_bool(
"FaceDetection",
"takeMeasures",
false);
104 m_measure.saveMeasurementsToFile =
105 cfg.
read_bool(
"FaceDetection",
"saveMeasurementsToFile",
false);
108 if (m_options.multithread)
110 if (m_options.useRegionsFilter)
111 m_thread_checkIfFaceRegions =
112 std::thread(dummy_checkIfFaceRegions,
this);
113 if (m_options.useCovFilter)
114 m_thread_checkIfFacePlaneCov =
115 std::thread(dummy_checkIfFacePlaneCov,
this);
116 if (m_options.useSizeDistanceRelationFilter ||
117 m_options.useDiagonalDistanceFilter)
118 m_thread_checkIfDiagonalSurface =
119 std::thread(dummy_checkIfDiagonalSurface,
this);
121 m_checkIfFacePlaneCov_res =
false;
122 m_checkIfFaceRegions_res =
true;
123 m_checkIfDiagonalSurface_res =
true;
126 cascadeClassifier.init(cfg);
132 void CFaceDetection::detectObjects_Impl(
142 if (m_measure.takeTime) m_timeLog.enter(
"Detection time");
145 cascadeClassifier.detectObjects(obs, localDetected);
149 if (m_measure.takeTime) m_timeLog.leave(
"Detection time");
152 m_measure.numPossibleFacesDetected += localDetected.size();
160 if (m_measure.takeTime) m_timeLog.enter(
"Check if real face time");
169 vector<size_t> deleteDetected;
173 for (
unsigned int i = 0; i < localDetected.size(); i++)
176 std::dynamic_pointer_cast<CDetectable2D>(localDetected[i]);
179 unsigned int r1 = rec->m_y;
180 unsigned int r2 = rec->m_y + rec->m_height;
181 unsigned int c1 = rec->m_x;
182 unsigned int c2 = rec->m_x + rec->m_width;
184 o.getZoneAsObs(m_lastFaceDetected, r1, r2, c1, c2);
186 if (m_options.multithread)
190 if (m_measure.takeTime)
191 m_timeLog.enter(
"Multithread filters application");
195 if (m_options.useCovFilter)
196 m_enter_checkIfFacePlaneCov.set_value();
197 if (m_options.useRegionsFilter)
198 m_enter_checkIfFaceRegions.set_value();
199 if (m_options.useSizeDistanceRelationFilter ||
200 m_options.useDiagonalDistanceFilter)
201 m_enter_checkIfDiagonalSurface.set_value();
204 if (m_options.useCovFilter)
205 m_leave_checkIfFacePlaneCov.get_future().wait();
206 if (m_options.useRegionsFilter)
207 m_leave_checkIfFaceRegions.get_future().wait();
208 if (m_options.useSizeDistanceRelationFilter ||
209 m_options.useDiagonalDistanceFilter)
210 m_leave_checkIfDiagonalSurface.get_future().wait();
213 if (!m_checkIfFacePlaneCov_res ||
214 !m_checkIfFaceRegions_res ||
215 !m_checkIfDiagonalSurface_res)
216 deleteDetected.push_back(i);
220 if (m_measure.takeTime)
221 m_timeLog.leave(
"Multithread filters application");
230 if (m_measure.takeTime)
231 m_timeLog.enter(
"Secuential filters application");
245 if (m_options.useCovFilter &&
246 !checkIfFacePlaneCov(&m_lastFaceDetected))
248 deleteDetected.push_back(i);
252 m_options.useRegionsFilter &&
253 !checkIfFaceRegions(&m_lastFaceDetected))
255 deleteDetected.push_back(i);
259 (m_options.useSizeDistanceRelationFilter ||
260 m_options.useDiagonalDistanceFilter) &&
261 !checkIfDiagonalSurface(&m_lastFaceDetected))
263 deleteDetected.push_back(i);
273 m_measure.deletedRegions.push_back(m_measure.faceNum);
280 if (m_measure.takeTime)
281 m_timeLog.leave(
"Secuential filters application");
287 for (
unsigned int i = deleteDetected.size(); i > 0; i--)
289 localDetected.begin() + deleteDetected[i - 1]);
293 for (
const auto& i : localDetected)
295 auto object3d = std::make_shared<CDetectable3D>(
296 std::dynamic_pointer_cast<CDetectable2D>(i));
297 detected.push_back(object3d);
302 if (m_measure.takeTime) m_timeLog.leave(
"Check if real face time");
307 detected = localDetected;
313 m_measure.numRealFacesDetected += detected.size();
324 vector<TPoint3D> points;
330 for (
size_t i = 0; i < N; i++)
340 if (m_measure.takeMeasures)
341 m_measure.errorEstimations.push_back(
356 void CFaceDetection::thread_checkIfFacePlaneCov()
360 m_enter_checkIfFacePlaneCov.get_future().wait();
362 if (m_end_threads)
break;
365 m_checkIfFacePlaneCov_res = checkIfFacePlaneCov(&m_lastFaceDetected);
367 m_leave_checkIfFacePlaneCov.set_value();
380 if (m_measure.takeTime)
381 m_timeLog.enter(
"Check if face plane: covariance");
392 vector<CVectorFixedDouble<3>> pointsVector;
395 experimental_segmentFace(*face, region);
397 for (
unsigned int j = 0; j < faceHeight; j++)
399 for (
unsigned int k = 0; k < faceWidth; k++)
408 m_options.confidenceThreshold) &&
411 int position = faceWidth * j + k;
415 pointsVector.push_back(aux);
421 if (pointsVector.empty())
return false;
428 std::vector<double> eVals;
430 cov = covVector<vector<CVectorFixedDouble<3>>,
CMatrixDouble>(pointsVector);
436 if (m_measure.takeMeasures) m_measure.lessEigenVals.push_back(eVals[0]);
438 if (m_measure.takeTime)
439 m_timeLog.leave(
"Check if face plane: covariance");
448 cout << eVals[0] <<
" " << eVals[1] <<
" " << eVals[2] <<
" > ";
449 cout << eVals[0] / eVals[2] << endl;
454 if (m_measure.faceNum >= 314)
455 experimental_viewFacePointsAndEigenVects(pointsVector, eVects, eVals);
460 if (eVals[0] / eVals[2] > 0.06)
482 void CFaceDetection::thread_checkIfFaceRegions()
486 m_enter_checkIfFaceRegions.get_future().wait();
488 if (m_end_threads)
break;
491 m_checkIfFaceRegions_res = checkIfFaceRegions(&m_lastFaceDetected);
493 m_leave_checkIfFaceRegions.set_value();
507 if (m_measure.takeTime) m_timeLog.enter(
"Check if face plane: regions");
515 unsigned int sectionVSize = faceHeight / 3.0;
529 vector<TPoint3D> points;
535 int numPoints[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
537 vector<TPoint3D> regions2[9];
545 experimental_segmentFace(*face, region);
552 size_t start = faceWidth,
end = 0;
554 for (
size_t r = 0; r < region.
rows(); r++)
555 for (
size_t c = 1; c < region.
cols(); c++)
557 if ((!(region(r, c - 1))) && (region(r, c)))
559 if (c < start) start = c;
561 else if ((region(r, c - 1)) && (!(region(r, c))))
564 if ((c >
end) && (region(r, c)))
end = c;
567 if (
end == 0)
end = faceWidth - 1;
568 if (
end < 3 * (faceWidth / 4))
569 end = 3 * (faceWidth / 4);
570 if (start == faceWidth) start = 0;
571 if (start > faceWidth / 4) start = faceWidth / 4;
576 unsigned int utilWidth = faceWidth - start - (faceWidth -
end);
577 unsigned int c1 = ceil(utilWidth / 3.0 + start);
578 unsigned int c2 = ceil(2 * (utilWidth / 3.0) + start);
587 experimental_calcHist(
590 size_t countHist = 0;
591 for (
size_t i = 0; i < 60; i++)
593 countHist += hist(0, i);
597 size_t downLimit = faceHeight - 1;
601 upLimit = floor(faceHeight * 0.1);
602 downLimit = floor(faceHeight * 0.9);
613 unsigned int cont = 0;
615 for (
unsigned int r = 0; r < faceHeight; r++)
617 for (
unsigned int c = 0; c < faceWidth; c++, cont++)
619 if ((r >= upLimit) && (r <= downLimit) && (region(r, c)) &&
621 m_options.confidenceThreshold) &&
624 unsigned int row, col;
625 if (r < sectionVSize + upLimit * 0.3)
627 else if (r < sectionVSize * 2 - upLimit * 0.15)
642 meanPos[row][col] = meanPos[row][col] + point;
644 ++numPoints[row][col];
646 if (row == 0 && col == 0)
647 regions2[0].emplace_back(
650 else if (row == 0 && col == 1)
651 regions2[1].emplace_back(
654 else if (row == 0 && col == 2)
655 regions2[2].emplace_back(
658 else if (row == 1 && col == 0)
659 regions2[3].emplace_back(
662 else if (row == 1 && col == 1)
663 regions2[4].emplace_back(
666 else if (row == 1 && col == 2)
667 regions2[5].emplace_back(
670 else if (row == 2 && col == 0)
671 regions2[6].emplace_back(
674 else if (row == 2 && col == 1)
675 regions2[7].emplace_back(
679 regions2[8].emplace_back(
690 vector<double> oldPointsX1;
695 if (regions2[0].
size() > 0)
697 for (
auto& i : regions2[0]) oldPointsX1.push_back(i.x);
699 middle1 = floor((
double)oldPointsX1.size() / 2);
701 oldPointsX1.begin(), oldPointsX1.begin() + middle1,
705 vector<double> oldPointsX2;
707 if (regions2[2].
size() > 0)
709 for (
auto& i : regions2[2]) oldPointsX2.push_back(i.x);
711 middle2 = floor((
double)oldPointsX2.size() / 2);
713 oldPointsX2.begin(), oldPointsX2.begin() + middle2,
717 for (
size_t i = 0; i < 3; i++)
718 for (
size_t j = 0; j < 3; j++)
719 if (!numPoints[i][j])
722 meanPos[i][j] = meanPos[i][j] / numPoints[i][j];
724 if (regions2[0].
size() > 0) meanPos[0][0].
x = oldPointsX1.at(middle1);
726 if (regions2[2].
size() > 0) meanPos[0][2].
x = oldPointsX2.at(middle2);
731 vector<double> dist(5);
732 size_t res = checkRelativePosition(
733 meanPos[1][0], meanPos[1][2], meanPos[1][1], dist[0]);
734 res += res && checkRelativePosition(
735 meanPos[2][0], meanPos[2][2], meanPos[2][1], dist[1]);
736 res += res && checkRelativePosition(
737 meanPos[0][0], meanPos[0][2], meanPos[0][1], dist[2]);
738 res += res && checkRelativePosition(
739 meanPos[0][0], meanPos[2][2], meanPos[1][1], dist[3]);
740 res += res && checkRelativePosition(
741 meanPos[2][0], meanPos[0][2], meanPos[1][1], dist[4]);
744 f.open(
"dist.txt", ofstream::app);
745 f <<
sum(dist) << endl;
751 else if ((res = 1) && (
sum(dist) > 0.04))
754 f.open(
"tam.txt", ofstream::app);
755 f << meanPos[0][1].
distanceTo(meanPos[2][1]) << endl;
769 if (m_measure.takeTime) m_timeLog.leave(
"Check if face plane: regions");
793 size_t CFaceDetection::checkRelativePosition(
805 double yIdeal = y1 + (((x - x1) * (y2 - y1)) / (x2 - x1));
830 void CFaceDetection::thread_checkIfDiagonalSurface()
834 m_enter_checkIfDiagonalSurface.get_future().wait();
836 if (m_end_threads)
break;
839 m_checkIfDiagonalSurface_res =
840 checkIfDiagonalSurface(&m_lastFaceDetected);
842 m_leave_checkIfDiagonalSurface.set_value();
856 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
857 m_timeLog.enter(
"Check if face plane: diagonal distances");
859 if (m_options.useSizeDistanceRelationFilter && m_measure.takeTime)
860 m_timeLog.enter(
"Check if face plane: size-distance relation");
868 unsigned int x1 = ceil(faceWidth * 0.25);
869 unsigned int x2 = floor(faceWidth * 0.75);
870 unsigned int y1 = ceil(faceHeight * 0.15);
871 unsigned int y2 = floor(faceHeight * 0.85);
873 vector<TPoint3D> points;
874 unsigned int cont = (y1 == 0 ? 0 : faceHeight * (y1 - 1));
877 valids.
setSize(faceHeight, faceWidth);
882 for (
unsigned int i = y1; i <= y2; i++)
886 for (
unsigned int j = x1; j <= x2; j++, cont++)
889 m_options.confidenceThreshold)
898 cont += faceWidth - x2 - 1;
901 double meanDepth = sumDepth / total;
910 if (m_options.useSizeDistanceRelationFilter)
912 double maxFaceDistance = 0.5 + 1000 / (pow(faceWidth, 1.9));
916 if (m_measure.takeTime)
917 m_timeLog.leave(
"Check if face plane: size-distance relation");
919 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
920 m_timeLog.leave(
"Check if face plane: diagonal distances");
929 if (maxFaceDistance < meanDepth)
944 if (!m_options.useDiagonalDistanceFilter)
return true;
952 f.open(
"relaciones2.txt", ofstream::app);
953 f << meanDepth << endl;
962 cont = (y1 == 1 ? 0 : faceHeight * (y1 - 1));
964 for (
unsigned int i = y1; i <= y2; i++)
968 for (
unsigned int j = x1; j <= x2; j++, cont++)
971 m_options.confidenceThreshold))
981 valids(i, j) =
false;
983 cont += faceWidth - x2 - 1;
992 double sumDistances = 0;
998 for (
unsigned int i = y1; i <= y2; i++)
1002 for (
unsigned int j = x1; j <= x2; j++, cont++)
1010 if ((i + 1 <= y2) && (j + 1 <= x2))
1012 if (valids(i + 1, j + 1))
1017 offsetIndex = cont + faceWidth + 1;
1025 bool validOffset =
true;
1030 if ((i + offset <= y2) && (j + offset <= x2))
1032 if (valids(i + offset, j + offset))
1038 offsetIndex = cont + faceWidth + offset;
1048 validOffset =
false;
1056 cont += faceWidth - x2 - 1;
1061 if (m_measure.takeMeasures)
1062 m_measure.sumDistances.push_back(sumDistances);
1065 fo.open(
"distances.txt", ofstream::app);
1067 fo << sumDistances << endl;
1070 fo.open(
"distances2.txt", ofstream::app);
1071 fo << m_measure.faceNum <<
" " << sumDistances << endl;
1077 double yMax = 3 + 6 / (pow(meanDepth, 2));
1078 double yMin = 1 + 3.8 / (pow(meanDepth + 1.2, 2));
1082 if (m_measure.takeTime)
1083 m_timeLog.leave(
"Check if face plane: diagonal distances");
1086 if (((sumDistances <= yMax) && (sumDistances >= yMin)) && (res))
1123 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
1124 m_timeLog.enter(
"Check if face plane: diagonal distances");
1126 if (m_options.useSizeDistanceRelationFilter && m_measure.takeTime)
1127 m_timeLog.enter(
"Check if face plane: size-distance relation");
1134 experimental_segmentFace(*face, region);
1140 vector<TPoint3D> points;
1142 for (
unsigned int row = 0; row < faceHeight; row++)
1144 for (
unsigned int col = 0; col < faceWidth; col++, cont++)
1146 if ((region(row, col)) &&
1148 m_options.confidenceThreshold))
1152 points.emplace_back(
1159 double meanDepth = sumDepth / total;
1163 if (m_options.useSizeDistanceRelationFilter)
1165 double maxFaceDistance = 0.5 + 1000 / (pow(faceWidth, 1.9));
1169 if (m_measure.takeTime)
1170 m_timeLog.leave(
"Check if face plane: size-distance relation");
1172 if (m_options.useDiagonalDistanceFilter && m_measure.takeTime)
1173 m_timeLog.leave(
"Check if face plane: diagonal distances");
1182 if (maxFaceDistance < meanDepth)
1197 if (!m_options.useDiagonalDistanceFilter)
return true;
1205 f.open(
"relaciones2.txt", ofstream::app);
1206 f << meanDepth << endl;
1221 double sumDistances = 0;
1223 size_t offsetIndex = 0;
1227 for (
unsigned int i = 0; i < faceHeight; i++)
1229 for (
unsigned int j = 0; j < faceWidth; j++, cont++)
1234 if ((i + 1 < faceHeight) && (j + 1 < faceWidth))
1236 if (region(i + 1, j + 1))
1241 offsetIndex = cont + faceWidth + 1;
1249 bool validOffset =
true;
1254 if ((i + offset < faceHeight) &&
1255 (j + offset < faceWidth))
1257 if (region(i + offset, j + offset))
1263 offsetIndex = cont + faceWidth + offset;
1273 validOffset =
false;
1285 if (m_measure.takeMeasures)
1286 m_measure.sumDistances.push_back(sumDistances);
1289 fo.open(
"distances.txt", ofstream::app);
1291 fo << sumDistances << endl;
1301 double yMax = 3 + 11.8 / (pow(meanDepth, 0.9));
1302 double yMin = 1 + 3.8 / (pow(meanDepth + 7, 6));
1306 if (m_measure.takeTime)
1307 m_timeLog.leave(
"Check if face plane: diagonal distances");
1310 if (((sumDistances <= yMax) && (sumDistances >= yMin)) && (res))
1341 void CFaceDetection::experimental_viewFacePointsScanned(
1344 vector<float> xs, ys, zs;
1352 for (
unsigned int i = 0; i < N; i++)
1359 experimental_viewFacePointsScanned(xs, ys, zs);
1366 void CFaceDetection::experimental_viewFacePointsScanned(
1367 const vector<TPoint3D>& points)
1369 vector<float> xs, ys, zs;
1371 unsigned int N = points.size();
1377 for (
unsigned int i = 0; i < N; i++)
1379 xs[i] = points[i].x;
1380 ys[i] = points[i].y;
1381 zs[i] = points[i].z;
1384 experimental_viewFacePointsScanned(xs, ys, zs);
1391 void CFaceDetection::experimental_viewFacePointsScanned(
1392 const vector<float>& xs,
const vector<float>& ys,
const vector<float>& zs)
1407 gl_points->setPointSize(4.5);
1411 scene->insert(gl_points);
1418 gl_points->loadFromPointsMap(&pntsMap);
1461 void CFaceDetection::experimental_viewFacePointsAndEigenVects(
1463 const CMatrixDouble& eigenVect,
const std::vector<double>& eigenVal)
1465 vector<float> xs, ys, zs;
1467 const size_t size = pointsVector.size();
1473 for (
size_t i = 0; i <
size; i++)
1475 xs[i] = pointsVector[i][0];
1476 ys[i] = pointsVector[i][1];
1477 zs[i] = pointsVector[i][2];
1495 gl_points->setPointSize(4.5);
1499 CSphere::Ptr sphere = std::make_shared<CSphere>(0.005f);
1500 sphere->setLocation(center);
1501 sphere->setColor(
TColorf(0, 1, 0));
1502 scene->insert(sphere);
1504 TPoint3D E1(eigenVect(0, 0), eigenVect(0, 1), eigenVect(0, 2));
1505 TPoint3D E2(eigenVect(1, 0), eigenVect(1, 1), eigenVect(1, 2));
1506 TPoint3D E3(eigenVect(2, 0), eigenVect(2, 1), eigenVect(2, 2));
1510 TPoint3D p1(center + E1 * eigenVal[0] * 100);
1511 TPoint3D p2(center + E2 * eigenVal[1] * 100);
1512 TPoint3D p3(center + E3 * eigenVal[2] * 100);
1515 center.
x, center.
y, center.
z, p1.
x, p1.
y, p1.
z);
1517 center.
x, center.
y, center.
z, p2.
x, p2.
y, p2.
z);
1519 center.
x, center.
y, center.
z, p3.
x, p3.
y, p3.
z);
1521 arrow1->setColor(
TColorf(0, 1, 0));
1522 arrow2->setColor(
TColorf(1, 0, 0));
1523 arrow3->setColor(
TColorf(0, 0, 1));
1525 scene->insert(arrow1);
1526 scene->insert(arrow2);
1527 scene->insert(arrow3);
1539 scene->insert(gl_points);
1546 gl_points->loadFromPointsMap(&pntsMap);
1558 void CFaceDetection::experimental_viewRegions(
1559 const vector<TPoint3D> regions[9],
const TPoint3D meanPos[3][3])
1574 gl_points->setPointSize(6);
1578 if (meanPos !=
nullptr)
1580 for (
size_t i = 0; i < 3; i++)
1581 for (
size_t j = 0; j < 3; j++)
1583 CSphere::Ptr sphere = std::make_shared<CSphere>(0.005f);
1584 sphere->setLocation(meanPos[i][j]);
1585 sphere->setColor(
TColorf(0, 1, 0));
1586 scene->insert(sphere);
1590 vector<TSegment3D> sgms;
1591 sgms.emplace_back(meanPos[0][0], meanPos[0][1]);
1592 sgms.emplace_back(meanPos[0][1], meanPos[0][2]);
1593 sgms.emplace_back(meanPos[1][0], meanPos[1][1]);
1594 sgms.emplace_back(meanPos[1][1], meanPos[1][2]);
1595 sgms.emplace_back(meanPos[2][0], meanPos[2][1]);
1596 sgms.emplace_back(meanPos[2][1], meanPos[2][2]);
1597 sgms.emplace_back(meanPos[0][0], meanPos[1][1]);
1598 sgms.emplace_back(meanPos[1][1], meanPos[2][2]);
1599 sgms.emplace_back(meanPos[2][0], meanPos[1][1]);
1600 sgms.emplace_back(meanPos[1][1], meanPos[0][2]);
1603 lines->setColor(0, 0, 1, 1);
1604 lines->setLineWidth(10);
1606 scene->insert(lines);
1608 scene->insert(gl_points);
1615 vector<float> xs, ys, zs;
1617 for (
size_t i = 0; i < 9; i++)
1618 for (
const auto& j : regions[i])
1628 float colors[9][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1},
1629 {1, 1, 0}, {1, 0, 1}, {0, 1, 1},
1630 {0.5f, 0.25f, 0}, {0.5f, 0, 0.25f}, {0, 0.35f, 0.5f}};
1631 for (
size_t i = 0; i < 9; i++)
1633 float R = colors[i][0];
1634 float G = colors[i][1];
1635 float B = colors[i][2];
1637 for (
unsigned int j = 0; j < regions[i].size(); j++, cont++)
1641 gl_points->loadFromPointsMap(&pntsMap);
1654 void CFaceDetection::experimental_segmentFace(
1660 region.
setSize(faceWidth, faceHeight,
true);
1662 unsigned int x1 = ceil(faceWidth * 0.4);
1663 unsigned int x2 = floor(faceWidth * 0.6);
1664 unsigned int y1 = ceil(faceHeight * 0.4);
1665 unsigned int y2 = floor(faceHeight * 0.6);
1667 region.
setSize(faceHeight, faceWidth);
1669 toExpand.
setSize(faceHeight, faceWidth,
true);
1671 unsigned int cont = (y1 <= 1 ? 0 : faceHeight * (y1 - 1));
1678 const Eigen::MatrixXf range2D =
1679 m_lastFaceDetected.rangeImage.asEigen().cast<
float>() *
1680 m_lastFaceDetected.rangeUnits * (1.0f / 5);
1684 for (
unsigned int i = y1; i <= y2; i++)
1688 for (
unsigned int j = x1; j <= x2; j++, cont++)
1691 m_options.confidenceThreshold)
1696 cont += faceWidth - x2;
1701 bool newExpanded =
true;
1705 newExpanded =
false;
1707 for (
size_t row = 0; row < faceHeight; row++)
1709 for (
size_t col = 0; col < faceWidth; col++)
1711 if (toExpand(row, col) == 1)
1713 region(row, col) =
true;
1715 int value = img.
at<uint8_t>(col, row);
1717 if ((row > 0) && (toExpand(row - 1, col) != 2))
1719 int value2 = img.
at<uint8_t>(col, row - 1);
1720 if (std::abs(value - value2) < 2)
1722 toExpand(row - 1, col) = 1;
1727 if ((row < faceWidth - 1) && (toExpand(row + 1, col) != 2))
1729 int value2 = img.
at<uint8_t>(col, row + 1);
1730 if (std::abs(value - value2) < 2)
1732 toExpand(row + 1, col) = 1;
1737 if ((col > 0) && (toExpand(row, col - 1) != 2))
1739 int value2 = img.
at<uint8_t>(col - 1, row);
1740 if (std::abs(value - value2) < 2)
1742 toExpand(row, col - 1) = 1;
1747 if ((col < faceHeight - 1) && (toExpand(row, col + 1) != 2))
1749 int value2 = img.
at<uint8_t>(col + 1, row);
1750 if (std::abs(value - value2) < 2)
1752 toExpand(row, col + 1) = 1;
1757 toExpand(row, col) = 2;
1763 for (
unsigned int row = 0; row < faceHeight; row++)
1765 for (
unsigned int col = 0; col < faceWidth; col++)
1767 if (!(region(row, col)))
1775 if (m_measure.faceNum >= 314)
1788 void CFaceDetection::experimental_calcHist(
1789 const CImage& face,
size_t c1,
size_t r1,
size_t c2,
size_t r2,
1794 for (
size_t row = r1; row <= r2; row++)
1795 for (
size_t col = c1; col <= c2; col++)
1797 auto value = face.
at<uint8_t>(col, row);
1798 int count = hist(0, value) + 1;
1799 hist(0, value) = count;
1807 void CFaceDetection::experimental_showMeasurements()
1814 f.open(
"statistics.txt", ofstream::app);
1816 if (m_measure.lessEigenVals.size() > 0)
1818 double meanEigenVal, stdEigenVal;
1819 double minEigenVal = *min_element(
1820 m_measure.lessEigenVals.begin(), m_measure.lessEigenVals.end());
1821 double maxEigenVal = *max_element(
1822 m_measure.lessEigenVals.begin(), m_measure.lessEigenVals.end());
1824 meanAndStd(m_measure.lessEigenVals, meanEigenVal, stdEigenVal);
1827 <<
"Statistical data about eigen values calculated of regions "
1830 cout <<
"Min eigenVal: " << minEigenVal << endl;
1831 cout <<
"Max eigenVal: " << maxEigenVal << endl;
1832 cout <<
"Mean eigenVal: " << meanEigenVal << endl;
1833 cout <<
"Standard Desv: " << stdEigenVal << endl;
1835 if (m_measure.saveMeasurementsToFile)
1838 <<
"Statistical data about eigen values calculated of regions "
1841 f <<
"Min eigenVal: " << minEigenVal << endl;
1842 f <<
"Max eigenVal: " << maxEigenVal << endl;
1843 f <<
"Mean eigenVal: " << meanEigenVal << endl;
1844 f <<
"Standard Desv: " << stdEigenVal << endl;
1848 if (m_measure.sumDistances.size() > 0)
1850 double meanSumDist, stdSumDist;
1851 double minSumDist = *min_element(
1852 m_measure.sumDistances.begin(), m_measure.sumDistances.end());
1853 double maxSumDist = *max_element(
1854 m_measure.sumDistances.begin(), m_measure.sumDistances.end());
1856 meanAndStd(m_measure.sumDistances, meanSumDist, stdSumDist);
1858 cout << endl <<
"Statistical data about sum of distances" << endl;
1859 cout <<
"Min sumDistances: " << minSumDist << endl;
1860 cout <<
"Max sumDistances: " << maxSumDist << endl;
1861 cout <<
"Mean sumDistances: " << meanSumDist << endl;
1862 cout <<
"Standard Desv: " << stdSumDist << endl;
1864 if (m_measure.saveMeasurementsToFile)
1866 f << endl <<
"Statistical data about sum of distances" << endl;
1867 f <<
"Min sumDistances: " << minSumDist << endl;
1868 f <<
"Max sumDistances: " << maxSumDist << endl;
1869 f <<
"Mean sumDistances: " << meanSumDist << endl;
1870 f <<
"Standard Desv: " << stdSumDist << endl;
1874 if (m_measure.errorEstimations.size() > 0)
1876 double meanEstimationErr, stdEstimationErr;
1877 double minEstimationErr = *min_element(
1878 m_measure.errorEstimations.begin(),
1879 m_measure.errorEstimations.end());
1880 double maxEstimationErr = *max_element(
1881 m_measure.errorEstimations.begin(),
1882 m_measure.errorEstimations.end());
1885 m_measure.errorEstimations, meanEstimationErr, stdEstimationErr);
1888 <<
"Statistical data about estimation error adjusting a plane of "
1889 "regions detected as faces"
1891 cout <<
"Min estimation: " << minEstimationErr << endl;
1892 cout <<
"Max estimation: " << maxEstimationErr << endl;
1893 cout <<
"Mean estimation: " << meanEstimationErr << endl;
1894 cout <<
"Standard Desv: " << stdEstimationErr << endl;
1896 if (m_measure.saveMeasurementsToFile)
1899 <<
"Statistical data about estimation error adjusting a plane of "
1900 "regions detected as faces"
1902 f <<
"Min estimation: " << minEstimationErr << endl;
1903 f <<
"Max estimation: " << maxEstimationErr << endl;
1904 f <<
"Mean estimation: " << meanEstimationErr << endl;
1905 f <<
"Standard Desv: " << stdEstimationErr << endl;
1909 cout << endl <<
"Data about number of faces" << endl;
1910 cout <<
"Possible faces detected: " << m_measure.numPossibleFacesDetected
1912 cout <<
"Real faces detected: " << m_measure.numRealFacesDetected << endl;
1914 if (m_meanHist.size() > 0)
1916 double minHist = *min_element(m_meanHist.begin(), m_meanHist.end());
1917 double maxHist = *max_element(m_meanHist.begin(), m_meanHist.end());
1922 cout << endl <<
"Mean hist: " << meanHist << endl;
1923 cout <<
"Min hist: " << minHist << endl;
1924 cout <<
"Max hist: " << maxHist << endl;
1925 cout <<
"Stdv: " << stdHist << endl;
1928 if (m_measure.saveMeasurementsToFile)
1930 f << endl <<
"Data about number of faces" << endl;
1931 f <<
"Possible faces detected: " << m_measure.numPossibleFacesDetected
1933 f <<
"Real faces detected: " << m_measure.numRealFacesDetected << endl;
1936 if (m_measure.takeTime && m_measure.saveMeasurementsToFile)
1937 f << endl << m_timeLog.getStatsAsText();
1948 void CFaceDetection::debug_returnResults(
1950 const std::vector<uint32_t>& ignore,
unsigned int& falsePositivesDeleted,
1951 unsigned int& realFacesDeleted)
1953 const unsigned int numDeleted = m_measure.deletedRegions.size();
1955 const unsigned int numIgnored = ignore.size();
1956 unsigned int ignoredDetected = 0;
1958 falsePositivesDeleted = 0;
1960 for (
unsigned int i = 0; i < numDeleted; i++)
1962 unsigned int region = m_measure.deletedRegions[i];
1964 bool falsePositive =
false;
1967 while (!falsePositive && (j < numFalsePositives))
1974 falsePositivesDeleted++;
1980 while (!igno && (j < numIgnored))
1982 if (region == ignore[j]) igno =
true;
1986 if (igno) ignoredDetected++;
1990 realFacesDeleted = numDeleted - falsePositivesDeleted - ignoredDetected;
1992 m_measure.faceNum = 0;
1993 m_measure.deletedRegions.clear();