mirror of
https://github.com/YutaItoh/3D-Eye-Tracker.git
synced 2025-11-04 15:39:41 +08:00
Optimizations to drift correction and model filter
This commit is contained in:
parent
2e48bedf55
commit
45eeed9306
@ -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(){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user