Optimizations to drift correction and model filter

This commit is contained in:
Jason 2018-08-29 13:58:47 +09:00 committed by GitHub
parent 2e48bedf55
commit 45eeed9306
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -226,7 +226,7 @@ int EyeModelUpdater::get_current_count() {
*/
void EyeModelUpdater::rm_oldest_observation() {
//remove one observation (without going under 80% of max)
if (is_model_built_ && space_bin_searcher_.is_initialized() && fitter_count_ >= fitter_max_count_ * .9f) {
if (is_model_built_ && space_bin_searcher_.is_initialized() && fitter_count_ >= fitter_max_count_ * .5f) {
simple_fitter_.remove_observation();
space_bin_searcher_.rm_oldest_index();
fitter_count_--;
@ -327,7 +327,7 @@ double EyeModelUpdater::compute_reliability(cv::Mat &img, sef::Ellipse2D<double>
void EyeModelUpdater::render(cv::Mat &img, sef::Ellipse2D<double> &el, std::vector<cv::Point2f> &inlier_pts){
if (simple_fitter_.eye){
//if (simple_fitter_.eye){
const float displayscale = 1.0f;
// Unproject the current 2D ellipse observation to a 3D disk
@ -348,79 +348,86 @@ void EyeModelUpdater::render(cv::Mat &img, sef::Ellipse2D<double> &el, std::vect
// 3D gaze vector
singleeyefitter::EyeModelFitter::Circle c_end = curr_circle;
c_end.centre = curr_circle.centre + (10.0)*curr_circle.normal; // Unit: mm
//std::cout << "x: " << c_end.centre.x() << std::endl;
//std::cout << "y: " << c_end.centre.y() << std::endl;
//std::cout << "z: " << c_end.centre.z() << std::endl;
//std::cout << "eye center x: " << simple_fitter_.eye.centre[0] << std::endl;
//std::cout << "eye center y: " << simple_fitter_.eye.centre[1] << std::endl;
//std::cout << "eye center z: " << simple_fitter_.eye.centre[2] << std::endl;
//std::cout << "radius: " << c_end.radius << std::endl;
//write coordinates to file
//std::ofstream myfile("C:\\Users\\O\\Documents\\Visual Studio 2013\\Projects\\EyeTrackerRealTime\\coordinates.txt");
////std::ofstream myfile;
////myfile.open("C:\\Documents\\Osaka\\Research\\Presence 2017\\testcoordinates.txt", std::ios_base::app);
//myfile << "" << c_end.centre.x() << "," << c_end.centre.y() << "," << c_end.centre.z()
// << "," << simple_fitter_.eye.centre[0] << "," << simple_fitter_.eye.centre[1] << "," << simple_fitter_.eye.centre[2] <<
// std::endl;
//myfile.close();
singleeyefitter::Ellipse2D<double> e_end(sef::project(c_end, focal_length_));
cv::RotatedRect rr_end = eye_tracker::toImgCoord(singleeyefitter::toRotatedRect(e_end), img, displayscale);
cv::line(img, cv::Point(rr_pupil.center), cv::Point(rr_end.center), cv::Vec3b(0, 255, 128), 2, CV_AA);
}
}
//else if (curr_circle) {
// // 3D pupil
// singleeyefitter::Ellipse2D<double> pupil_el(sef::project(curr_circle, focal_length_));
// cv::RotatedRect rr_pupil = eye_tracker::toImgCoord(singleeyefitter::toRotatedRect(pupil_el), img, displayscale);
// cv::ellipse(img, rr_pupil, cv::Vec3b(0, 10, 248), 5, CV_AA);
// //cv::line(img, rr_eye.center, rr_pupil.center, cv::Vec3b(255, 128, 0), 1, CV_AA);
//}
//}
}
singleeyefitter::EyeModelFitter::Sphere EyeModelUpdater::eyeModelFilter(
singleeyefitter::EyeModelFitter::Sphere eye,
std::vector<singleeyefitter::EyeModelFitter::Sphere> &eyes, int filterLength) {
std::vector<singleeyefitter::EyeModelFitter::Sphere> &eyes,
int filterLength,
bool ignoreNewEye,
singleeyefitter::EyeModelFitter::Sphere originalCalibratedEye) {
int max = filterLength; //max number of elements to average
double radiiAverage = 0;
singleeyefitter::EyeModelFitter::Sphere filteredEyeModel;
singleeyefitter::EyeModelFitter::Sphere eyeTemp(eye);
eyes.push_back(eyeTemp);//add the newest eye model to the vector
std::cout << "Adding x of : " + std::to_string(eyes[eyes.size()-1].centre(0)) << std::endl;
//std::cout << "raw radius: " << eyeTemp.radius << std::endl;
if (eyes.size() > max) {//remove oldest element if > max
eyes.erase(eyes.begin());
}
//temp arrays for sorting
std::vector<singleeyefitter::EyeModelFitter::Sphere> temp(eyes);
std::vector<double> xs;
std::vector<double> ys;
std::vector<double> zs;
std::vector<double> radii;
//add data to all arrays from eye spheres
for (int i = 0; i < temp.size(); i++) {
xs.push_back(eyes[i].centre[0]);
ys.push_back(eyes[i].centre[1]);
zs.push_back(eyes[i].centre[2]);
radii.push_back(eyes[i].radius);
radiiAverage += eyes[i].radius / temp.size();
}
double radiiAverage = 0;
singleeyefitter::EyeModelFitter::Sphere filteredEyeModel;
singleeyefitter::EyeModelFitter::Sphere eyeTemp(eye);
float filterFactor = 3;
//sort each coordinate and radii
std::sort(xs.begin(), xs.begin() + xs.size());
std::sort(ys.begin(), ys.begin() + ys.size());
std::sort(zs.begin(), zs.begin() + zs.size());
std::sort(radii.begin(), radii.begin() + radii.size());
//for (int i = 0; i < radii.size(); i++) {
// std::cout << "radius " << i << ": " << radii[i] << std::endl;
//}
//set return sphere to median values
filteredEyeModel.centre[0] = xs[(int)xs.size() / 2];
filteredEyeModel.centre[1] = ys[(int)ys.size() / 2];
filteredEyeModel.centre[2] = zs[(int)zs.size() / 2];
filteredEyeModel.radius = radiiAverage;// radii[(int)radii.size() / 2];
//return median Sphere
std::cout << "Returning x of : " + std::to_string(filteredEyeModel.centre(0)) << std::endl;
//check to see if new eye model is way different than originals and ignore if so
if (ignoreNewEye == false && (
std::abs(eye.centre.x() - originalCalibratedEye.centre.x()) > filterFactor ||
std::abs(eye.centre.y() - originalCalibratedEye.centre.y()) > filterFactor ||
std::abs(eye.centre.z() - originalCalibratedEye.centre.z()) > filterFactor)){
ignoreNewEye = true;
}
return filteredEyeModel;
if (!ignoreNewEye) {
eyes.push_back(eyeTemp);//add the newest eye model to the vector
}
if (eyes.size() > max) {//remove oldest element if > max
eyes.erase(eyes.begin());
}
//temp arrays for sorting
std::vector<singleeyefitter::EyeModelFitter::Sphere> temp(eyes);
std::vector<double> xs;
std::vector<double> ys;
std::vector<double> zs;
std::vector<double> radii;
//add data to all arrays from eye spheres
for (int i = 0; i < temp.size(); i++) {
xs.push_back(eyes[i].centre[0]);
ys.push_back(eyes[i].centre[1]);
zs.push_back(eyes[i].centre[2]);
radii.push_back(eyes[i].radius);
radiiAverage += eyes[i].radius / temp.size();
}
//sort each coordinate and radii
std::sort(xs.begin(), xs.begin() + xs.size());
std::sort(ys.begin(), ys.begin() + ys.size());
std::sort(zs.begin(), zs.begin() + zs.size());
std::sort(radii.begin(), radii.begin() + radii.size());
//set return sphere to median values
if (xs.size() > 0) {
filteredEyeModel.centre[0] = xs[(int)xs.size() / 2];
filteredEyeModel.centre[1] = ys[(int)ys.size() / 2];
filteredEyeModel.centre[2] = zs[(int)zs.size() / 2];
filteredEyeModel.radius = radiiAverage;// radii[(int)radii.size() / 2];
}
else {
filteredEyeModel.centre[0] = 0;
filteredEyeModel.centre[1] = 0;
filteredEyeModel.centre[2] = 0;
filteredEyeModel.radius = 0;// radii[(int)radii.size() / 2];
}
return filteredEyeModel;
}
void EyeModelUpdater::reset(){