diff --git a/exe/FeatureExtraction/FeatureExtraction.cpp b/exe/FeatureExtraction/FeatureExtraction.cpp index 73eb4d5..2e6fc1c 100644 --- a/exe/FeatureExtraction/FeatureExtraction.cpp +++ b/exe/FeatureExtraction/FeatureExtraction.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #ifndef CONFIG_DIR #define CONFIG_DIR "~" @@ -407,7 +408,7 @@ int main (int argc, char **argv) // Do face alignment cv::Mat sim_warped_img; cv::Mat_ hog_descriptor; - int num_hog_rows, num_hog_cols; + int num_hog_rows = 0, num_hog_cols = 0; // As this can be expensive only compute it if needed by output or visualization if(!output_similarity_align.empty() || output_hog || output_AUs || visualize_align || visualize_hog) diff --git a/lib/local/Recorder/include/RecorderHOG.h b/lib/local/Recorder/include/RecorderHOG.h index 9a31616..06cae80 100644 --- a/lib/local/Recorder/include/RecorderHOG.h +++ b/lib/local/Recorder/include/RecorderHOG.h @@ -60,15 +60,23 @@ namespace Recorder // Adding observations to the recorder void SetObservationHOG(bool success, const cv::Mat_& hog_descriptor, int num_cols, int num_rows, int num_channels); + void Write(); + bool Open(std::string filename); void Close(); - private: std::ofstream hog_file; + // Internals for recording + int num_cols; + int num_rows; + int num_channels; + cv::Mat_ hog_descriptor; + bool good_frame; + }; } #endif \ No newline at end of file diff --git a/lib/local/Recorder/include/RecorderOpenFace.h b/lib/local/Recorder/include/RecorderOpenFace.h index 218aef9..1c4bdc0 100644 --- a/lib/local/Recorder/include/RecorderOpenFace.h +++ b/lib/local/Recorder/include/RecorderOpenFace.h @@ -36,6 +36,7 @@ #include "RecorderCSV.h" #include "RecorderHOG.h" +#include "RecorderOpenFaceParameters.h" // System includes #include @@ -49,22 +50,24 @@ namespace Recorder //=========================================================================== /** - A class for recording CSV file from OpenFace + A class for recording data processed by OpenFace (facial landmarks, head pose, facial action units, aligned face, HOG features, and tracked video */ 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, + RecorderOpenFace(const std::string out_directory, const std::string in_filename, Recorder::RecorderOpenFaceParameter params, + // TODO here int num_face_landmarks, int num_model_modes, int num_eye_landmarks, const std::vector& au_names_class, const std::vector& au_names_reg, const std::string& output_codec, double fps_vid_in); // Simplified constructor that records all, TODO implement 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 + ~RecorderOpenFace(); + + // TODO copy, assignment and move operators? Do not allow // Closing and cleaning up the recorder void Close(); @@ -95,7 +98,7 @@ namespace Recorder // HOG feature related observations void SetObservationHOG(bool good_frame, const cv::Mat_& hog_descriptor, int num_cols, int num_rows, int num_channels); - void SetObservationVisualization(const cv::Mat_ &vis_track); + void SetObservationVisualization(const cv::Mat &vis_track); void WriteObservation(); @@ -109,19 +112,7 @@ namespace Recorder 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; + const RecorderOpenFaceParameters params; // The actual temporary storage for the observations double timestamp; @@ -154,7 +145,7 @@ namespace Recorder std::string video_filename; std::string output_codec; double fps_vid_out; - cv::Mat_ vis_to_out; + cv::Mat vis_to_out; }; } diff --git a/lib/local/Recorder/include/RecorderOpenFaceParameters.h b/lib/local/Recorder/include/RecorderOpenFaceParameters.h new file mode 100644 index 0000000..ea59500 --- /dev/null +++ b/lib/local/Recorder/include/RecorderOpenFaceParameters.h @@ -0,0 +1,93 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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. +// +/////////////////////////////////////////////////////////////////////////////// + +// Parameters of the Face analyser +#ifndef __RECORDER_OPENFACE_PARAM_H +#define __RECORDER_OPENFACE_PARAM_H + +#include +#include + +// Boost includes +#include +#include + +using namespace std; + +namespace Recorder +{ + + struct RecorderOpenFaceParameters + { + public: + // Constructors + RecorderOpenFaceParameters(); + RecorderOpenFaceParameters(vector &arguments); + + + + bool isSequence() const { return is_sequence; } + bool output2DLandmarks() const { return output_2D_landmarks; } + bool output3DLandmarks() const { return output_3D_landmarks; } + bool outputPDMParams() const { return output_model_params; } + bool outputPose() const { return output_pose; } + bool outputAUs() const { return output_AUs; } + bool outputGaze() const { return output_gaze; } + bool outputHOG() const { return output_hog; } + bool outputTrackedVideo() const { return output_tracked_video; } + bool outputAlignedFaces() const { return output_aligned_faces; } + + private: + + // The default values initializer + void init(); + + // 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 // __FACE_ANALYSER_PARAM_H diff --git a/lib/local/Recorder/src/RecorderHOG.cpp b/lib/local/Recorder/src/RecorderHOG.cpp index 08bb442..ac5563f 100644 --- a/lib/local/Recorder/src/RecorderHOG.cpp +++ b/lib/local/Recorder/src/RecorderHOG.cpp @@ -55,10 +55,8 @@ void RecorderHOG::Close() hog_file.close(); } -// Writing to a HOG file -void RecorderHOG::SetObservationHOG(bool good_frame, const cv::Mat_& hog_descriptor, int num_cols, int num_rows, int num_channels) +void RecorderHOG::Write() { - hog_file.write((char*)(&num_cols), 4); hog_file.write((char*)(&num_rows), 4); hog_file.write((char*)(&num_channels), 4); @@ -86,4 +84,14 @@ void RecorderHOG::SetObservationHOG(bool good_frame, const cv::Mat_& hog } } } +} + +// Writing to a HOG file +void RecorderHOG::SetObservationHOG(bool good_frame, const cv::Mat_& hog_descriptor, int num_cols, int num_rows, int num_channels) +{ + this->num_cols = num_cols; + this->num_rows = num_rows; + this->num_channels = num_channels; + this->hog_descriptor = hog_descriptor; + this->good_frame = good_frame; } \ No newline at end of file diff --git a/lib/local/Recorder/src/RecorderOpenFace.cpp b/lib/local/Recorder/src/RecorderOpenFace.cpp index c2e1c1d..956515e 100644 --- a/lib/local/Recorder/src/RecorderOpenFace.cpp +++ b/lib/local/Recorder/src/RecorderOpenFace.cpp @@ -113,7 +113,7 @@ RecorderOpenFace::RecorderOpenFace(const std::string out_directory, const std::s } -void RecorderOpenFace::SetObservationVisualization(const cv::Mat_ &vis_track) +void RecorderOpenFace::SetObservationVisualization(const cv::Mat &vis_track) { if (output_tracked_video) { @@ -147,7 +147,10 @@ void RecorderOpenFace::WriteObservation() landmark_detection_confidence, landmarks_2D, landmarks_3D, pdm_params_local, pdm_params_global, head_pose, gaze_direction0, gaze_direction1, gaze_angle, eye_landmarks, au_intensities, au_occurences); - // TODO HOG + if(output_hog) + { + this->hog_recorder.Write(); + } if(output_tracked_video) { @@ -205,7 +208,18 @@ void RecorderOpenFace::SetObservationGaze(const cv::Point3f& gaze_direction0, co this->eye_landmarks = eye_landmarks; } +RecorderOpenFace::~RecorderOpenFace() +{ + this->Close(); +} + + +void RecorderOpenFace::Close() +{ + hog_recorder.Close(); + csv_recorder.Close(); + video_writer.release(); +} -// TODO the other 4 constructors + destructors?