From b9378f8e5ee2ab93423e51b3399f71a3301cc671 Mon Sep 17 00:00:00 2001 From: Tadas Baltrusaitis Date: Wed, 1 Nov 2017 19:39:49 +0000 Subject: [PATCH] Starting work on a separate recorder, this will allow for a nicer separation of executables and utilities and make it much easier to integrate with the GUI as it will not rely on it's own recorder. --- OpenFace.sln | 11 ++ exe/Recording/Recording.vcxproj | 3 + lib/local/Recorder/Recorder.vcxproj | 156 ++++++++++++++++++ lib/local/Recorder/include/RecorderCSV.h | 80 +++++++++ lib/local/Recorder/include/RecorderHOG.h | 68 ++++++++ lib/local/Recorder/include/RecorderOpenFace.h | 108 ++++++++++++ lib/local/Recorder/src/RecorderCSV.cpp | 147 +++++++++++++++++ lib/local/Recorder/src/RecorderOpenFace.cpp | 102 ++++++++++++ 8 files changed, 675 insertions(+) create mode 100644 lib/local/Recorder/Recorder.vcxproj create mode 100644 lib/local/Recorder/include/RecorderCSV.h create mode 100644 lib/local/Recorder/include/RecorderHOG.h create mode 100644 lib/local/Recorder/include/RecorderOpenFace.h create mode 100644 lib/local/Recorder/src/RecorderCSV.cpp create mode 100644 lib/local/Recorder/src/RecorderOpenFace.cpp diff --git a/OpenFace.sln b/OpenFace.sln index 4b49708..9c19ba7 100644 --- a/OpenFace.sln +++ b/OpenFace.sln @@ -25,6 +25,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FaceLandmarkImg", "exe\Face EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GazeAnalyser", "lib\local\GazeAnalyser\GazeAnalyser.vcxproj", "{5F915541-F531-434F-9C81-79F5DB58012B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Recorder", "lib\local\Recorder\Recorder.vcxproj", "{8E741EA2-9386-4CF2-815E-6F9B08991EAC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -105,6 +107,14 @@ Global {5F915541-F531-434F-9C81-79F5DB58012B}.Release|Win32.Build.0 = Release|Win32 {5F915541-F531-434F-9C81-79F5DB58012B}.Release|x64.ActiveCfg = Release|x64 {5F915541-F531-434F-9C81-79F5DB58012B}.Release|x64.Build.0 = Release|x64 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|Win32.ActiveCfg = Debug|Win32 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|Win32.Build.0 = Debug|Win32 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|x64.ActiveCfg = Debug|x64 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Debug|x64.Build.0 = Debug|x64 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|Win32.ActiveCfg = Release|Win32 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|Win32.Build.0 = Release|Win32 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|x64.ActiveCfg = Release|x64 + {8E741EA2-9386-4CF2-815E-6F9B08991EAC}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -119,5 +129,6 @@ Global {34032CF2-1B99-4A25-9050-E9C13DD4CD0A} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631} {DDC3535E-526C-44EC-9DF4-739E2D3A323B} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631} {5F915541-F531-434F-9C81-79F5DB58012B} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D} + {8E741EA2-9386-4CF2-815E-6F9B08991EAC} = {99FEBA13-BDDF-4076-B57E-D8EF4076E20D} EndGlobalSection EndGlobal diff --git a/exe/Recording/Recording.vcxproj b/exe/Recording/Recording.vcxproj index 5f04e4c..ffd4bbd 100644 --- a/exe/Recording/Recording.vcxproj +++ b/exe/Recording/Recording.vcxproj @@ -86,6 +86,7 @@ Level3 Disabled true + ./include;%(AdditionalIncludeDirectories) true @@ -110,6 +111,7 @@ false Cdecl true + ./include;%(AdditionalIncludeDirectories) true @@ -128,6 +130,7 @@ false Cdecl true + ./include;%(AdditionalIncludeDirectories) true diff --git a/lib/local/Recorder/Recorder.vcxproj b/lib/local/Recorder/Recorder.vcxproj new file mode 100644 index 0000000..13029d5 --- /dev/null +++ b/lib/local/Recorder/Recorder.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {8E741EA2-9386-4CF2-815E-6F9B08991EAC} + Win32Proj + Recorder + 8.1 + + + + StaticLibrary + true + v140 + Unicode + + + StaticLibrary + false + v140 + true + Unicode + + + StaticLibrary + true + v140 + Unicode + + + StaticLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ./include;%(AdditionalIncludeDirectories) + + + Windows + + + + + + + Level3 + Disabled + _DEBUG;_LIB;%(PreprocessorDefinitions) + ./include;%(AdditionalIncludeDirectories) + + + Windows + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ./include;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + ./include;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/local/Recorder/include/RecorderCSV.h b/lib/local/Recorder/include/RecorderCSV.h new file mode 100644 index 0000000..9b58426 --- /dev/null +++ b/lib/local/Recorder/include/RecorderCSV.h @@ -0,0 +1,80 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, Tadas Baltrusaitis all rights reserved. +// +// ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY +// +// BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT. +// IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE. +// +// License can be found in OpenFace-license.txt +// +// * Any publications arising from the use of this software, including but +// not limited to academic journal and conference publications, technical +// reports and manuals, must cite at least one of the following works: +// +// OpenFace: an open source facial behavior analysis toolkit +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency +// in IEEE Winter Conference on Applications of Computer Vision, 2016 +// +// Rendering of Eyes for Eye-Shape Registration and Gaze Estimation +// Erroll Wood, Tadas Baltrušaitis, Xucong Zhang, Yusuke Sugano, Peter Robinson, and Andreas Bulling +// in IEEE International. Conference on Computer Vision (ICCV), 2015 +// +// Cross-dataset learning and person-speci?c normalisation for automatic Action Unit detection +// Tadas Baltrušaitis, Marwa Mahmoud, and Peter Robinson +// in Facial Expression Recognition and Analysis Challenge, +// IEEE International Conference on Automatic Face and Gesture Recognition, 2015 +// +// Constrained Local Neural Fields for robust facial landmark detection in the wild. +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency. +// in IEEE Int. Conference on Computer Vision Workshops, 300 Faces in-the-Wild Challenge, 2013. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __RECORDER_CSV_h_ +#define __RECORDER_CSV_h_ + +// System includes +#include +#include +#include + +namespace Recorder +{ + + //=========================================================================== + /** + A class for recording CSV file from OpenFace + */ + class RecorderCSV { + + public: + + // The constructor for the recorder, need to specify if we are recording a sequence or not + RecorderCSV(); + + // Opening the file and preparing the header for it + bool open(std::string output_file_name, bool output_2D_landmarks, bool output_3D_landmarks, bool output_model_params, bool output_pose, bool output_AUs, bool output_gaze, + int num_face_landmarks, int num_model_modes, int num_eye_landmarks, std::vector au_names_class, std::vector au_names_reg); + + // Closing the file and cleaning up + void close(); + + void writeLine(); + + // TODO have set functions? + + private: + + // The actual output file stream that will be written + std::ofstream output_file; + + // If we are recording results from a sequence each row refers to a frame, if we are recording an image each row is a face + bool is_sequence; + + // Internal storage of OF outputs + + + }; +} +#endif \ No newline at end of file diff --git a/lib/local/Recorder/include/RecorderHOG.h b/lib/local/Recorder/include/RecorderHOG.h new file mode 100644 index 0000000..45797c9 --- /dev/null +++ b/lib/local/Recorder/include/RecorderHOG.h @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, Tadas Baltrusaitis all rights reserved. +// +// ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY +// +// BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT. +// IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE. +// +// License can be found in OpenFace-license.txt +// +// * Any publications arising from the use of this software, including but +// not limited to academic journal and conference publications, technical +// reports and manuals, must cite at least one of the following works: +// +// OpenFace: an open source facial behavior analysis toolkit +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency +// in IEEE Winter Conference on Applications of Computer Vision, 2016 +// +// Rendering of Eyes for Eye-Shape Registration and Gaze Estimation +// Erroll Wood, Tadas Baltrušaitis, Xucong Zhang, Yusuke Sugano, Peter Robinson, and Andreas Bulling +// in IEEE International. Conference on Computer Vision (ICCV), 2015 +// +// Cross-dataset learning and person-speci?c normalisation for automatic Action Unit detection +// Tadas Baltrušaitis, Marwa Mahmoud, and Peter Robinson +// in Facial Expression Recognition and Analysis Challenge, +// IEEE International Conference on Automatic Face and Gesture Recognition, 2015 +// +// Constrained Local Neural Fields for robust facial landmark detection in the wild. +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency. +// in IEEE Int. Conference on Computer Vision Workshops, 300 Faces in-the-Wild Challenge, 2013. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __RECORDER_HOG_h_ +#define __RECORDER_HOG_h_ + +// System includes +#include +#include + +namespace Recorder +{ + + //=========================================================================== + /** + A class for recording CSV file from OpenFace + */ + class RecorderHOG { + + public: + + // The constructor for the recorder, by default does not do anything + RecorderHOG() {}; + + + // Adding observations to the recorder + void AddObservationHOG(cv::Mat_ aligned_HOG, bool success); + + void Open(std::string filename); + + void Close(); + + private: + std::ofstream hog_file; + + }; +} +#endif \ No newline at end of file diff --git a/lib/local/Recorder/include/RecorderOpenFace.h b/lib/local/Recorder/include/RecorderOpenFace.h new file mode 100644 index 0000000..451b9db --- /dev/null +++ b/lib/local/Recorder/include/RecorderOpenFace.h @@ -0,0 +1,108 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, Tadas Baltrusaitis all rights reserved. +// +// ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY +// +// BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT. +// IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE. +// +// License can be found in OpenFace-license.txt +// +// * Any publications arising from the use of this software, including but +// not limited to academic journal and conference publications, technical +// reports and manuals, must cite at least one of the following works: +// +// OpenFace: an open source facial behavior analysis toolkit +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency +// in IEEE Winter Conference on Applications of Computer Vision, 2016 +// +// Rendering of Eyes for Eye-Shape Registration and Gaze Estimation +// Erroll Wood, Tadas Baltrušaitis, Xucong Zhang, Yusuke Sugano, Peter Robinson, and Andreas Bulling +// in IEEE International. Conference on Computer Vision (ICCV), 2015 +// +// Cross-dataset learning and person-speci?c normalisation for automatic Action Unit detection +// Tadas Baltrušaitis, Marwa Mahmoud, and Peter Robinson +// in Facial Expression Recognition and Analysis Challenge, +// IEEE International Conference on Automatic Face and Gesture Recognition, 2015 +// +// Constrained Local Neural Fields for robust facial landmark detection in the wild. +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency. +// in IEEE Int. Conference on Computer Vision Workshops, 300 Faces in-the-Wild Challenge, 2013. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __RECORDER_OPENFACE_h_ +#define __RECORDER_OPENFACE_h_ + +#include "RecorderCSV.h" +#include "RecorderHOG.h" + +// System includes +#include +#include + +namespace Recorder +{ + + //=========================================================================== + /** + A class for recording CSV file from OpenFace + */ + class RecorderOpenFace { + + public: + + // The constructor for the recorder, need to specify if we are recording a sequence or not + RecorderOpenFace(const std::string out_directory, const std::string in_filename, bool sequence, bool output_2D_landmarks, bool output_3D_landmarks, bool output_model_params, bool output_pose, + bool output_AUs, bool output_gaze, bool output_hog, bool output_tracked_video, bool output_aligned_faces, int num_face_landmarks, int num_model_modes, int num_eye_landmarks, + const std::vector& au_names_class, const std::vector& au_names_reg); + + // Simplified constructor that records all + RecorderOpenFace(const std::string out_directory, const std::string in_filename, bool sequence, int num_face_landmarks, int num_model_modes, int num_eye_landmarks, + const std::vector& au_names_class, const std::vector& au_names_reg); + + // TODO copy, move, destructors + + // Closing and cleaning up the recorder + void Close(); + + // Adding observations to the recorder + void AddObservationLandmarks(const cv::Mat_& landmarks_2D, const cv::Mat_& landmarks_3D); + void AddObservationLandmarkParameters(const cv::Vec6d& params_global, const cv::Mat_& params_local); + void AddObservationPose(const cv::Vec6d& pose); + void AddObservationActionUnits(const std::vector >& au_intensities, + const std::vector >& au_occurences); + void AddObservationGaze(const cv::Point3f& gazeDirection0, const cv::Point3f& gazeDirection1, + const cv::Vec2d& gaze_angle, const cv::Mat_& eye_landmarks); + void AddObservationFaceAlign(const cv::Mat& aligned_face); + void AddObservationHOG(const cv::Mat_& aligned_HOG); + void AddObservationSuccess(double confidence, bool success); + void AddObservationTimestamp(double timestamp); + + private: + + // Keep track of the file and output root location + std::string record_root; + std::string filename; + + // The actual output file stream that will be written + RecorderCSV csv_recorder; + RecorderHOG hog_recorder; + + // If we are recording results from a sequence each row refers to a frame, if we are recording an image each row is a face + bool is_sequence; + + // Keep track of what we are recording + bool output_2D_landmarks; + bool output_3D_landmarks; + bool output_model_params; + bool output_pose; + bool output_AUs; + bool output_gaze; + bool output_hog; + bool output_tracked_video; + bool output_aligned_faces; + + }; +} +#endif \ No newline at end of file diff --git a/lib/local/Recorder/src/RecorderCSV.cpp b/lib/local/Recorder/src/RecorderCSV.cpp new file mode 100644 index 0000000..93d2b1a --- /dev/null +++ b/lib/local/Recorder/src/RecorderCSV.cpp @@ -0,0 +1,147 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, Tadas Baltrusaitis, all rights reserved. +// +// ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY +// +// BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT. +// IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE. +// +// License can be found in OpenFace-license.txt +// +// * Any publications arising from the use of this software, including but +// not limited to academic journal and conference publications, technical +// reports and manuals, must cite at least one of the following works: +// +// OpenFace: an open source facial behavior analysis toolkit +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency +// in IEEE Winter Conference on Applications of Computer Vision, 2016 +// +// Rendering of Eyes for Eye-Shape Registration and Gaze Estimation +// Erroll Wood, Tadas Baltrušaitis, Xucong Zhang, Yusuke Sugano, Peter Robinson, and Andreas Bulling +// in IEEE International. Conference on Computer Vision (ICCV), 2015 +// +// Cross-dataset learning and person-speci?c normalisation for automatic Action Unit detection +// Tadas Baltrušaitis, Marwa Mahmoud, and Peter Robinson +// in Facial Expression Recognition and Analysis Challenge, +// IEEE International Conference on Automatic Face and Gesture Recognition, 2015 +// +// Constrained Local Neural Fields for robust facial landmark detection in the wild. +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency. +// in IEEE Int. Conference on Computer Vision Workshops, 300 Faces in-the-Wild Challenge, 2013. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "RecorderCSV.h" + +// For sorting +#include + +using namespace Recorder; + +// Default constructor initializes the variables +RecorderCSV::RecorderCSV():output_file(){}; + +// TODO the other 4 constructors + destructors? + +// Opening the file and preparing the header for it +bool RecorderCSV::open(std::string output_file_name, bool output_2D_landmarks, bool output_3D_landmarks, bool output_model_params, bool output_pose, bool output_AUs, bool output_gaze, + int num_face_landmarks, int num_model_modes, int num_eye_landmarks, std::vector au_names_class, std::vector au_names_reg) +{ + output_file.open(output_file_name, std::ios_base::out); + + // Different headers if we are writing out the results on a sequence or an individual image + if(this->is_sequence) + { + output_file << "frame, timestamp, confidence, success"; + } + else + { + output_file << "face, confidence"; + } + + if (output_gaze) + { + output_file << ", gaze_0_x, gaze_0_y, gaze_0_z, gaze_1_x, gaze_1_y, gaze_1_z, gaze_angle_x, gaze_angle_y"; + + for (int i = 0; i < num_eye_landmarks; ++i) + { + output_file << ", eye_lmk_x_" << i; + } + for (int i = 0; i < num_eye_landmarks; ++i) + { + output_file << ", eye_lmk_y_" << i; + } + } + + if (output_pose) + { + output_file << ", pose_Tx, pose_Ty, pose_Tz, pose_Rx, pose_Ry, pose_Rz"; + } + + if (output_2D_landmarks) + { + for (int i = 0; i < num_face_landmarks; ++i) + { + output_file << ", x_" << i; + } + for (int i = 0; i < num_face_landmarks; ++i) + { + output_file << ", y_" << i; + } + } + + if (output_3D_landmarks) + { + for (int i = 0; i < num_face_landmarks; ++i) + { + output_file << ", X_" << i; + } + for (int i = 0; i < num_face_landmarks; ++i) + { + output_file << ", Y_" << i; + } + for (int i = 0; i < num_face_landmarks; ++i) + { + output_file << ", Z_" << i; + } + } + + // Outputting model parameters (rigid and non-rigid), the first parameters are the 6 rigid shape parameters, they are followed by the non rigid shape parameters + if (output_model_params) + { + output_file << ", p_scale, p_rx, p_ry, p_rz, p_tx, p_ty"; + for (int i = 0; i < num_model_modes; ++i) + { + output_file << ", p_" << i; + } + } + + if (output_AUs) + { + std::sort(au_names_reg.begin(), au_names_reg.end()); + for (std::string reg_name : au_names_reg) + { + output_file << ", " << reg_name << "_r"; + } + + std::sort(au_names_class.begin(), au_names_class.end()); + for (std::string class_name : au_names_class) + { + output_file << ", " << class_name << "_c"; + } + } + + output_file << std::endl; + +} + +// TODO check if the stream is open +//void writeLine(int frame_count, double time_stamp, bool detection_success, +// cv::Point3f gazeDirection0, cv::Point3f gazeDirection1, cv::Vec2d gaze_angle, cv::Vec6d& pose_estimate, double fx, double fy, double cx, double cy, +// const FaceAnalysis::FaceAnalyser& face_analyser); + +// Closing the file and cleaning up +void RecorderCSV::close() +{ + output_file.close(); +} diff --git a/lib/local/Recorder/src/RecorderOpenFace.cpp b/lib/local/Recorder/src/RecorderOpenFace.cpp new file mode 100644 index 0000000..144c895 --- /dev/null +++ b/lib/local/Recorder/src/RecorderOpenFace.cpp @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, Tadas Baltrusaitis, all rights reserved. +// +// ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY +// +// BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT. +// IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE. +// +// License can be found in OpenFace-license.txt +// +// * Any publications arising from the use of this software, including but +// not limited to academic journal and conference publications, technical +// reports and manuals, must cite at least one of the following works: +// +// OpenFace: an open source facial behavior analysis toolkit +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency +// in IEEE Winter Conference on Applications of Computer Vision, 2016 +// +// Rendering of Eyes for Eye-Shape Registration and Gaze Estimation +// Erroll Wood, Tadas Baltrušaitis, Xucong Zhang, Yusuke Sugano, Peter Robinson, and Andreas Bulling +// in IEEE International. Conference on Computer Vision (ICCV), 2015 +// +// Cross-dataset learning and person-speci?c normalisation for automatic Action Unit detection +// Tadas Baltrušaitis, Marwa Mahmoud, and Peter Robinson +// in Facial Expression Recognition and Analysis Challenge, +// IEEE International Conference on Automatic Face and Gesture Recognition, 2015 +// +// Constrained Local Neural Fields for robust facial landmark detection in the wild. +// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency. +// in IEEE Int. Conference on Computer Vision Workshops, 300 Faces in-the-Wild Challenge, 2013. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "RecorderOpenFace.h" + +// For sorting +#include + +// File manipulation +#include +#include +#include + +// Boost includes for file system manipulation +#include +#include +#include + +using namespace boost::filesystem; + +using namespace Recorder; + +void create_directory(std::string output_path) +{ + + // Creating the right directory structure + auto p = path(output_path); + + if (!boost::filesystem::exists(p)) + { + bool success = boost::filesystem::create_directories(p); + + if (!success) + { + std::cout << "Failed to create a directory..." << p.string() << std::endl; + } + } +} + + +RecorderOpenFace::RecorderOpenFace(const std::string out_directory, const std::string in_filename, bool sequence, bool output_2D_landmarks, bool output_3D_landmarks, bool output_model_params, bool output_pose, + bool output_AUs, bool output_gaze, bool output_hog, bool output_tracked_video, bool output_aligned_faces, int num_face_landmarks, int num_model_modes, int num_eye_landmarks, + const std::vector& au_names_class, const std::vector& au_names_reg): + is_sequence(sequence), output_2D_landmarks(output_2D_landmarks), output_3D_landmarks(output_3D_landmarks), output_aligned_faces(output_aligned_faces), + output_AUs(output_AUs), output_gaze(output_gaze), output_hog(output_hog), output_model_params(output_model_params), + output_pose(output_pose), output_tracked_video(output_tracked_video) +{ + + // From the filename, strip out the name without directory and extension + filename = path(in_filename).replace_extension("").filename().string(); + record_root = out_directory; + + // Construct the directories required for the output + create_directory(record_root); + + // Create the required individual recorders, CSV, HOG, aligned, video + std::string csv_filename = (path(record_root) / path(filename).replace_extension(".csv")).string(); + csv_recorder.open(csv_filename, output_2D_landmarks, output_3D_landmarks, output_model_params, output_pose, + output_AUs, output_gaze, num_face_landmarks, num_model_modes, num_eye_landmarks, au_names_class, au_names_reg); + + // Consruct HOG recorder here + std::string hog_filename = (path(record_root) / path(filename).replace_extension(".hog")).string(); + hog_recorder.Open(hog_filename); + + // TODO construct a video recorder + + // Prepare image recording + +} + +// TODO the other 4 constructors + destructors? +