Commit 6a4b6aac authored by Thiago C. Santini's avatar Thiago C. Santini

Integrates the calibration methods

parent 5a0bef49
......@@ -2,6 +2,14 @@
Calibration::Calibration()
{
QString methodName = settings.value("calibration/method").toString();
if ( methodName == "polyfit" ) {
method = new PolyFit(PolyFit::POLY_1_X_Y_XX_YY_XY_XXYY);
} else {
method = new Homography();
}
collecting = false;
calibrating = false;
calibrated = false;
......@@ -112,28 +120,21 @@ bool Calibration::calibrate()
}
#endif
int minPointsForCalibration = settings.value("calibration/minPointsForCalibration").toInt();
if (fieldPoints.size() < minPointsForCalibration) {
QMessageBox::warning(NULL, "Calibration failed.",
QString("Not enough calibration points.\nGot %1\nRequired: %2\nPlease start again.").arg(fieldPoints.size()).arg(minPointsForCalibration),
QMessageBox::Ok, QMessageBox::NoButton);
success = false;
}
else {
calibrationMatrix = cv::findHomography(pupilEstimates, fieldPoints, cv::RANSAC);
if ( calibrationMatrix.empty() )
calibrationMatrix = cv::findHomography(pupilEstimates, fieldPoints);
if (calibrationMatrix.empty()) {
QMessageBox::warning(NULL, "Calibration failed.", "Could not find perspective transformation.\nPlease start again.", QMessageBox::Ok, QMessageBox::NoButton);
success = false;
}
QString errorMsg;
}
success = method->calibrate(
vector<Point2d>(pupilEstimates.begin(), pupilEstimates.end()),
vector<Point2d>(pupilEstimates.begin(), pupilEstimates.end()),
vector<Point2d>(fieldPoints.begin(), fieldPoints.end()),
errorMsg
);
if (!success)
if (!success) {
QMessageBox::warning(NULL, "Calibration failed.",
errorMsg,
QMessageBox::Ok, QMessageBox::NoButton);
reset();
}
return success;
}
......
......@@ -14,6 +14,10 @@
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "CalibrationMethod.h"
#include "PolyFit.h"
#include "Homography.h"
#include "settings.h"
#include "utils.h"
......@@ -42,6 +46,7 @@ public:
bool calibrated;
bool calibrating;
bool recording;
CalibrationMethod *method;
private slots:
void endCollection();
......
......@@ -25,11 +25,7 @@ void ImageProcessing::project(JournalEntry &journalEntry)
journalEntry.fieldProjection = cv::Point(0,0);
return;
} else {
std::vector<cv::Point2f> fieldEstimation;
std::vector<cv::Point2f> pupil;
pupil.push_back(cv::Point2f(journalEntry.pupil.center.x, journalEntry.pupil.center.y));
cv::perspectiveTransform(pupil, fieldEstimation, calibration->calibrationMatrix);
journalEntry.fieldProjection = fieldEstimation[0];
journalEntry.fieldProjection = calibration->method->evaluate(journalEntry.pupil.center, journalEntry.pupil.center);
}
}
......
......@@ -3,6 +3,14 @@
PolyFit::PolyFit(PlType plType)
{
this->plType = plType;
switch (plType) {
case POLY_1_X_Y_XX_YY_XY_XXYY:
unknowns = 7;
break;
default:
break;
}
}
PolyFit::~PolyFit()
......@@ -15,6 +23,11 @@ bool PolyFit::calibrate(vector<Point2d> leftPupil, vector<Point2d> rightPupil, v
// Ax = b
// x = A^{-1} b
if ( field.size() < unknowns ) {
errorMsg = QString("Not enough calibration points.\nGot %1\nRequired: %2\nPlease start again.").arg(field.size()).arg(unknowns);
return false;
}
// Possible terms; not using more than third order atm
Mat x, y , xx, yy, xy, xxyy, zx, zy, A, iA;
......@@ -34,10 +47,8 @@ bool PolyFit::calibrate(vector<Point2d> leftPupil, vector<Point2d> rightPupil, v
// TODO: depending on the polynom and number of calibration points, we can have an overdetermined system.
// Right now, we simply drop the extra equations, but we can select the set of equations that minimize error in the future.
int unknowns;
switch (plType) {
case POLY_1_X_Y_XX_YY_XY_XXYY:
unknowns = 7;
// A.col(0) was initialized with one
x.copyTo(A.col(1));
y.copyTo(A.col(2));
......@@ -51,12 +62,6 @@ bool PolyFit::calibrate(vector<Point2d> leftPupil, vector<Point2d> rightPupil, v
break;
}
if ( x.rows < unknowns ) {
errorMsg = QString("Not enough calibration points.\nGot %1\nRequired: %2\nPlease start again.").arg(x.rows).arg(unknowns);
return false;
}
A = A(Rect2d(0,0,unknowns,unknowns));
zx = zx(Rect2d(0,0,1,unknowns));
zy = zy(Rect2d(0,0,1,unknowns));
......
......@@ -30,6 +30,7 @@ private:
PlType plType;
Mat1d cx;
Mat1d cy;
int unknowns;
};
#endif // POLYFIT_H
......@@ -147,6 +147,9 @@ int main(int argc, char *argv[])
* GUI placement and start the main event loop
********************************************************************/
qDebug() << "Pupil detection method:" << settings.value("general/PupilDetector").toString();
qDebug() << "Calibration method:" << settings.value("calibration/method").toString();
QRect screenGeometry = QApplication::desktop()->screenGeometry();
int x = (screenGeometry.width() - gui.width()) / 2;
int y = (screenGeometry.height() - gui.height()) / 2;
......
......@@ -48,9 +48,9 @@ void updateSettings()
testUpdate("outputTimestamp/format", "yyyyMMddHHmmss");
testUpdate("outputTimestamp/tz", "UTC+01:00");
testUpdate("calibration/minPointsForCalibration", 4);
testUpdate("calibration/minSamplesPerPoint", 5);
testUpdate("calibration/pointSamplingTimeMs", 500);
testUpdate("calibration/method", "polyfit");
testUpdate("general/outputDirectory", "output");
testUpdate("general/pupilDetector", "else");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment