diff --git a/EyeRecToo/src/GazeEstimation.cpp b/EyeRecToo/src/GazeEstimation.cpp
index 611c621f3910f3f050a361b27d442fca78325ad3..099bc45991e0754d2a0bd404a4fa5e58903a6386 100644
--- a/EyeRecToo/src/GazeEstimation.cpp
+++ b/EyeRecToo/src/GazeEstimation.cpp
@@ -204,9 +204,14 @@ void GazeEstimation::calibrate()
interpolationHull.clear();
evaluationRegions.clear();
- QString error = "No gaze estimation method available.";
- if (!gazeEstimationMethod)
- return;
+ QString error = "";
+ if (!gazeEstimationMethod) {
+ error = "No gaze estimation method available.";
+ error = "No calibration tuples available.";
+ qInfo() << error;
+ emit calibrationFinished(false, error);
+ return;
+ }
calibrationTuples.clear();
@@ -252,7 +257,21 @@ void GazeEstimation::calibrate()
emit calibrationFinished(false, error);
return;
}
- evaluate();
+ evaluate();
+
+ if ( centralHullCoverage < cfg.minCentralAreaCoverage )
+ error.append("Calibration didn't cover enough of the central area. ");
+ if ( peripheralHullCoverage < cfg.minPeriphericAreaCoverage )
+ error.append("Calibration didn't cover enough of the peripheric area. ");
+ if ( 100*meanEvaluationError > cfg.maxReprojectionError )
+ error.append("Reprojection error is too high. ");
+ if (!error.isEmpty()) {
+ qInfo() << error;
+ emit calibrationFinished(false, error);
+ calibrated = false;
+ return;
+ }
+
autoVisualizationTimer.restart();
emit calibrationFinished(true, "");
}
diff --git a/EyeRecToo/src/GazeEstimation.h b/EyeRecToo/src/GazeEstimation.h
index d0d77f3a1d7451bd427f1ebb4e8051b5500653b0..2c118495108448044d63d5dddeaec61532128378 100644
--- a/EyeRecToo/src/GazeEstimation.h
+++ b/EyeRecToo/src/GazeEstimation.h
@@ -80,8 +80,11 @@ public:
inputType(GazeEstimationMethod::BINOCULAR_MEAN_POR),
gazeEstimationMethod("POLY_X_Y_XY_XX_YY_XYY_YXX_XXYY"),
visualize(true),
- visualizationTimeS(5)
- {}
+ visualizationTimeS(5),
+ minCentralAreaCoverage(0.8f),
+ minPeriphericAreaCoverage(0.1f),
+ maxReprojectionError(4.f)
+ {}
/*
* Gaze Estimation Widget
@@ -113,6 +116,10 @@ public:
double verticalStride;
double rangeFactor;
+ // Quality check
+ float minCentralAreaCoverage;
+ float minPeriphericAreaCoverage;
+ float maxReprojectionError;
void save(QSettings *settings)
{
@@ -133,8 +140,13 @@ public:
settings->setValue("CalibMe/granularity", granularity);
settings->setValue("CalibMe/horizontalStride", horizontalStride);
settings->setValue("CalibMe/verticalStride", verticalStride);
- settings->setValue("CalibMe/rangeFactor", rangeFactor);
- }
+ settings->setValue("CalibMe/rangeFactor", rangeFactor);
+
+ // Quality check
+ settings->setValue("quality/minCentralAreaCoverage", minCentralAreaCoverage);
+ settings->setValue("quality/minPeriphericAreaCoverage", minPeriphericAreaCoverage);
+ settings->setValue("quality/maxReprojectionError", maxReprojectionError);
+ }
void load(QSettings *settings)
{
@@ -155,8 +167,12 @@ public:
set(settings, "CalibMe/granularity", granularity );
set(settings, "CalibMe/horizontalStride", horizontalStride );
set(settings, "CalibMe/verticalStride", verticalStride );
- set(settings, "CalibMe/rangeFactor", rangeFactor );
- }
+ set(settings, "CalibMe/rangeFactor", rangeFactor );
+
+ set(settings, "quality/minCentralAreaCoverage", minCentralAreaCoverage );
+ set(settings, "quality/minPeriphericAreaCoverage", minPeriphericAreaCoverage );
+ set(settings, "quality/maxReprojectionError", maxReprojectionError );
+ }
};
class GazeEstimation : public QObject
diff --git a/EyeRecToo/src/GazeEstimationWidget.cpp b/EyeRecToo/src/GazeEstimationWidget.cpp
index ba5e2a3378bea819d61b179a6a5c4317cf6df50d..8b38aaf6f6518499c7a76385ddf0b4a13e4e23f9 100644
--- a/EyeRecToo/src/GazeEstimationWidget.cpp
+++ b/EyeRecToo/src/GazeEstimationWidget.cpp
@@ -132,7 +132,19 @@ GazeEstimationWidget::GazeEstimationWidget(QWidget *parent) :
ui->visualizationTimeSpinBox->blockSignals(true);
ui->visualizationTimeSpinBox->setValue(cfg.visualizationTimeS);
- ui->visualizationTimeSpinBox->blockSignals(false);
+ ui->visualizationTimeSpinBox->blockSignals(false);
+
+ ui->minCentralCoverage->blockSignals(true);
+ ui->minCentralCoverage->setValue(cfg.minCentralAreaCoverage);
+ ui->minCentralCoverage->blockSignals(false);
+
+ ui->minPeriphericCoverage->blockSignals(true);
+ ui->minPeriphericCoverage->setValue(cfg.minPeriphericAreaCoverage);
+ ui->minPeriphericCoverage->blockSignals(false);
+
+ ui->maxReprojectionError->blockSignals(true);
+ ui->maxReprojectionError->setValue(cfg.maxReprojectionError);
+ ui->maxReprojectionError->blockSignals(false);
statusBarLabel = new QLabel();
ui->statusBar->addPermanentWidget(statusBarLabel, 1000);
@@ -468,3 +480,21 @@ void GazeEstimationWidget::updateStatus(bool status, QString msg)
}
+
+void GazeEstimationWidget::on_minCentralCoverage_editingFinished()
+{
+ cfg.minCentralAreaCoverage = ui->minCentralCoverage->value();
+ updateConfig();
+}
+
+void GazeEstimationWidget::on_minPeriphericCoverage_editingFinished()
+{
+ cfg.minPeriphericAreaCoverage = ui->minPeriphericCoverage->value();
+ updateConfig();
+}
+
+void GazeEstimationWidget::on_maxReprojectionError_editingFinished()
+{
+ cfg.maxReprojectionError = ui->maxReprojectionError->value();
+ updateConfig();
+}
diff --git a/EyeRecToo/src/GazeEstimationWidget.h b/EyeRecToo/src/GazeEstimationWidget.h
index f541b2c51512529d7fd9a9a983fa8063f033d27e..dba6ab0c8f8082f9cd50e354e95fc48aa5c410d9 100644
--- a/EyeRecToo/src/GazeEstimationWidget.h
+++ b/EyeRecToo/src/GazeEstimationWidget.h
@@ -92,6 +92,9 @@ private slots:
void on_visualizationGroupBox_toggled(bool arg1);
void on_visualizationTimeSpinBox_valueChanged(int arg1);
+ void on_minCentralCoverage_editingFinished();
+ void on_minPeriphericCoverage_editingFinished();
+ void on_maxReprojectionError_editingFinished();
};
#endif // GAZEESTIMATIONWIDGET_H
diff --git a/EyeRecToo/src/GazeEstimationWidget.ui b/EyeRecToo/src/GazeEstimationWidget.ui
index 80809f8600822c46327170105b0b6ab49765b3d5..79845fa3f6c90a22d316ac25b656b8eac4e8971d 100644
--- a/EyeRecToo/src/GazeEstimationWidget.ui
+++ b/EyeRecToo/src/GazeEstimationWidget.ui
@@ -7,7 +7,7 @@
0
0
254
- 629
+ 735
@@ -456,6 +456,72 @@
+ -
+
+
+ Success Requirements
+
+
+
-
+
+
+ Min. Central Coverage
+
+
+
+ -
+
+
+ 2
+
+
+ 1.000000000000000
+
+
+ 0.050000000000000
+
+
+
+ -
+
+
+ Min. Peripheric Coverage
+
+
+
+ -
+
+
+ Max. Reprojection Error
+
+
+
+ -
+
+
+ 2
+
+
+ 1.000000000000000
+
+
+ 0.050000000000000
+
+
+
+ -
+
+
+ 99.000000000000000
+
+
+ 0.250000000000000
+
+
+
+
+
+