diff --git a/gui/OpenFaceOffline/MainWindow.xaml.cs b/gui/OpenFaceOffline/MainWindow.xaml.cs index 0fdebb6..abe79a5 100644 --- a/gui/OpenFaceOffline/MainWindow.xaml.cs +++ b/gui/OpenFaceOffline/MainWindow.xaml.cs @@ -503,11 +503,13 @@ namespace OpenFaceOffline List> lines = null; List> landmarks = null; + List> eye_landmarks = null; List> gaze_lines = null; if (detectionSucceeding) { landmarks = clnf_model.CalculateLandmarks(); + eye_landmarks = clnf_model.CalculateEyeLandmarks(); lines = clnf_model.CalculateBox((float)fx, (float)fy, (float)cx, (float)cy); gaze_lines = face_analyser.CalculateGazeLines(scale, (float)fx, (float)fy, (float)cx, (float)cy); } diff --git a/lib/local/CppInerop/LandmarkDetectorInterop.h b/lib/local/CppInerop/LandmarkDetectorInterop.h index d6eea8d..1059b78 100644 --- a/lib/local/CppInerop/LandmarkDetectorInterop.h +++ b/lib/local/CppInerop/LandmarkDetectorInterop.h @@ -291,6 +291,17 @@ namespace CppInterop { return landmarks; } + System::Collections::Generic::List^>^ CalculateEyeLandmarks() { + vector vecLandmarks = ::LandmarkDetector::CalculateEyeLandmarks(*clnf); + + auto landmarks = gcnew System::Collections::Generic::List^>(); + for (cv::Point2d p : vecLandmarks) { + landmarks->Add(gcnew System::Tuple(p.x, p.y)); + } + + return landmarks; + } + System::Collections::Generic::List^ Calculate3DLandmarks(double fx, double fy, double cx, double cy) { cv::Mat_ shape3D = clnf->GetShape(fx, fy, cx, cy); diff --git a/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp b/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp index 413d589..163db3e 100644 --- a/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp +++ b/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp @@ -1064,6 +1064,30 @@ vector CalculateLandmarks(CLNF& clnf_model) } +// Computing eye landmarks (to be drawn later or in different interfaces) +vector CalculateEyeLandmarks(CLNF& clnf_model) +{ + + int idx = clnf_model.patch_experts.GetViewIdx(clnf_model.params_global, 0); + vector to_return; + // If the model has hierarchical updates draw those too + for (size_t i = 0; i < clnf_model.hierarchical_models.size(); ++i) + { + + if (clnf_model.hierarchical_model_names[i].compare("left_eye_28") == 0 || + clnf_model.hierarchical_model_names[i].compare("right_eye_28") == 0) + { + auto lmks = CalculateLandmarks(clnf_model.hierarchical_models[i].detected_landmarks, clnf_model.hierarchical_models[i].patch_experts.visibilities[0][idx]); + for (auto lmk : lmks) + { + to_return.push_back(lmk); + } + } + } + return to_return; +} + + // Drawing landmarks on a face image void Draw(cv::Mat img, const cv::Mat_& shape2D, const cv::Mat_& visibilities) {