From 4b85fe21ac75464081bb6fff514d4c180fd2ce9c Mon Sep 17 00:00:00 2001 From: Tadas Baltrusaitis Date: Sun, 22 Oct 2017 10:03:23 +0100 Subject: [PATCH] Reporting a gaze angle that makes more sense. --- exe/FeatureExtraction/FeatureExtraction.cpp | 2 +- gui/OpenFaceOffline/Recorder.cs | 4 ++-- lib/local/CppInerop/GazeAnalyserInterop.h | 4 +--- lib/local/GazeAnalyser/include/GazeEstimation.h | 6 +++--- lib/local/GazeAnalyser/src/GazeEstimation.cpp | 13 ++++--------- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/exe/FeatureExtraction/FeatureExtraction.cpp b/exe/FeatureExtraction/FeatureExtraction.cpp index 2b9f7ae..c79e06f 100644 --- a/exe/FeatureExtraction/FeatureExtraction.cpp +++ b/exe/FeatureExtraction/FeatureExtraction.cpp @@ -496,7 +496,7 @@ int main (int argc, char **argv) { GazeAnalysis::EstimateGaze(face_model, gazeDirection0, fx, fy, cx, cy, true); GazeAnalysis::EstimateGaze(face_model, gazeDirection1, fx, fy, cx, cy, false); - gazeAngle = GazeAnalysis::GetGazeAngle(gazeDirection0, gazeDirection1, pose_estimate); + gazeAngle = GazeAnalysis::GetGazeAngle(gazeDirection0, gazeDirection1); } // Do face alignment diff --git a/gui/OpenFaceOffline/Recorder.cs b/gui/OpenFaceOffline/Recorder.cs index 4f2b865..e01f693 100644 --- a/gui/OpenFaceOffline/Recorder.cs +++ b/gui/OpenFaceOffline/Recorder.cs @@ -200,7 +200,7 @@ namespace OpenFaceOffline List pose = new List(); clnf_model.GetPose(pose, fx, fy, cx, cy); - + output_features_file.Write(String.Format("{0}, {1}, {2:F3}, {3}", frame_ind, time_stamp, confidence, success ? 1 : 0)); if (output_gaze) @@ -222,7 +222,7 @@ namespace OpenFaceOffline } if (output_pose) - output_features_file.Write(String.Format(", {0:F3}, {1:F3}, {2:F3}, {3:F3}, {4:F3}, {5:F3}", pose[0], pose[1], pose[2], pose[3], pose[4], pose[5])); + output_features_file.Write(String.Format(", {0:F4}, {1:F4}, {2:F4}, {3:F4}, {4:F4}, {5:F4}", pose[0], pose[1], pose[2], pose[3], pose[4], pose[5])); if (output_2D_landmarks) { diff --git a/lib/local/CppInerop/GazeAnalyserInterop.h b/lib/local/CppInerop/GazeAnalyserInterop.h index 3b3cbd1..f81e16d 100644 --- a/lib/local/CppInerop/GazeAnalyserInterop.h +++ b/lib/local/CppInerop/GazeAnalyserInterop.h @@ -109,10 +109,8 @@ namespace GazeAnalyser_Interop { // Estimate the gaze angle WRT to head pose here System::Collections::Generic::List^ pose_list = gcnew System::Collections::Generic::List(); - clnf->GetPose(pose_list, fx, fy, cx, cy); - cv::Vec6d pose(pose_list[0], pose_list[1], pose_list[2], pose_list[3], pose_list[4], pose_list[5]); - *gazeAngle = GazeAnalysis::GetGazeAngle(*gazeDirection0, *gazeDirection1, pose); + *gazeAngle = GazeAnalysis::GetGazeAngle(*gazeDirection0, *gazeDirection1); // Grab pupil locations int part_left = -1; diff --git a/lib/local/GazeAnalyser/include/GazeEstimation.h b/lib/local/GazeAnalyser/include/GazeEstimation.h index 2f30282..ce6f0af 100644 --- a/lib/local/GazeAnalyser/include/GazeEstimation.h +++ b/lib/local/GazeAnalyser/include/GazeEstimation.h @@ -45,9 +45,9 @@ namespace GazeAnalysis void EstimateGaze(const LandmarkDetector::CLNF& clnf_model, cv::Point3f& gaze_absolute, float fx, float fy, float cx, float cy, bool left_eye); void DrawGaze(cv::Mat img, const LandmarkDetector::CLNF& clnf_model, cv::Point3f gazeVecAxisLeft, cv::Point3f gazeVecAxisRight, float fx, float fy, float cx, float cy); - // Getting the gaze angle in radians with respect to head pose (need to call EstimateGaze first) - cv::Vec2d GetGazeAngle(cv::Point3f& gaze_vector_1, cv::Point3f& gaze_vector_2, cv::Vec6d head_pose); - + // Getting the gaze angle in radians with respect to the world coordinates (camera plane), when looking ahead straight at camera plane the gaze angle will be (0,0) + cv::Vec2d GetGazeAngle(cv::Point3f& gaze_vector_1, cv::Point3f& gaze_vector_2); + // Some utilities cv::Point3f GetPupilPosition(cv::Mat_ eyeLdmks3d); diff --git a/lib/local/GazeAnalyser/src/GazeEstimation.cpp b/lib/local/GazeAnalyser/src/GazeEstimation.cpp index b0889f6..ea2c894 100644 --- a/lib/local/GazeAnalyser/src/GazeEstimation.cpp +++ b/lib/local/GazeAnalyser/src/GazeEstimation.cpp @@ -136,18 +136,13 @@ void GazeAnalysis::EstimateGaze(const LandmarkDetector::CLNF& clnf_model, cv::Po gaze_absolute = gazeVecAxis / norm(gazeVecAxis); } -cv::Vec2d GazeAnalysis::GetGazeAngle(cv::Point3f& gaze_vector_1, cv::Point3f& gaze_vector_2, cv::Vec6d head_pose) +cv::Vec2d GazeAnalysis::GetGazeAngle(cv::Point3f& gaze_vector_1, cv::Point3f& gaze_vector_2) { - cv::Vec3d eulerAngles(head_pose(3), head_pose(4), head_pose(5)); - cv::Matx33d rotMat = LandmarkDetector::Euler2RotationMatrix(eulerAngles); - cv::Point3f gaze_point = (gaze_vector_1 + gaze_vector_2) / 2; - cv::Vec3d gaze(gaze_point.x, gaze_point.y, gaze_point.z); + cv::Point3f gaze_vector = (gaze_vector_1 + gaze_vector_2) / 2; - gaze = rotMat * gaze; - - double x_angle = atan2(gaze[0], -gaze[2]); - double y_angle = atan2(gaze[1], -gaze[2]); + double x_angle = atan2(gaze_vector.x, -gaze_vector.z); + double y_angle = atan2(gaze_vector.y, -gaze_vector.z); return cv::Vec2d(x_angle, y_angle);