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 + + + + + +