2017-11-01 20:39:49 +01:00
///////////////////////////////////////////////////////////////////////////////
// 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<72> 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<72> 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<72> 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<72> 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"
2017-11-03 17:40:07 +01:00
# include "RecorderOpenFaceParameters.h"
2017-11-01 20:39:49 +01:00
// System includes
# include <vector>
2017-11-03 09:34:55 +01:00
// OpenCV includes
2017-11-01 20:39:49 +01:00
# include <opencv2/core/core.hpp>
2017-11-03 09:34:55 +01:00
# include <opencv2/highgui/highgui.hpp>
2017-11-01 20:39:49 +01:00
2017-11-08 10:02:50 +01:00
namespace Utilities
2017-11-01 20:39:49 +01:00
{
//===========================================================================
/**
2017-11-03 17:40:07 +01:00
A class for recording data processed by OpenFace ( facial landmarks , head pose , facial action units , aligned face , HOG features , and tracked video
2017-11-01 20:39:49 +01:00
*/
class RecorderOpenFace {
public :
2017-12-08 18:22:30 +01:00
// The constructor for the recorder, need to specify if we are recording a sequence or not, in_filename should be just the name and not contain extensions
2018-01-18 09:08:29 +01:00
RecorderOpenFace ( const std : : string in_filename , const RecorderOpenFaceParameters & parameters , std : : vector < std : : string > & arguments ) ;
RecorderOpenFace ( const std : : string in_filename , const RecorderOpenFaceParameters & parameters , std : : string output_directory ) ;
2017-11-09 19:37:26 +01:00
2017-11-03 17:40:07 +01:00
~ RecorderOpenFace ( ) ;
2017-11-01 20:39:49 +01:00
// Closing and cleaning up the recorder
void Close ( ) ;
// Adding observations to the recorder
2017-11-02 10:06:53 +01:00
// Required observations for video/image-sequence
void SetObservationTimestamp ( double timestamp ) ;
2018-02-23 09:25:19 +01:00
// Required observations for video/image-sequence
void SetObservationFrameNumber ( double frame_number ) ;
// If in multiple face mode, identifying which face was tracked
void SetObservationFaceID ( int face_id ) ;
2017-11-02 10:06:53 +01:00
// All observations relevant to facial landmarks
void SetObservationLandmarks ( const cv : : Mat_ < double > & landmarks_2D , const cv : : Mat_ < double > & landmarks_3D ,
const cv : : Vec6d & params_global , const cv : : Mat_ < double > & params_local , double confidence , bool success ) ;
// Pose related observations
void SetObservationPose ( const cv : : Vec6d & pose ) ;
// AU related observations
void SetObservationActionUnits ( const std : : vector < std : : pair < std : : string , double > > & au_intensities ,
2017-11-01 20:39:49 +01:00
const std : : vector < std : : pair < std : : string , double > > & au_occurences ) ;
2017-11-02 10:06:53 +01:00
// Gaze related observations
void SetObservationGaze ( const cv : : Point3f & gazeDirection0 , const cv : : Point3f & gazeDirection1 ,
2017-11-11 22:13:29 +01:00
const cv : : Vec2d & gaze_angle , const std : : vector < cv : : Point2d > & eye_landmarks2D , const std : : vector < cv : : Point3d > & eye_landmarks3D ) ;
2017-11-02 10:06:53 +01:00
// Face alignment related observations
void SetObservationFaceAlign ( const cv : : Mat & aligned_face ) ;
// HOG feature related observations
void SetObservationHOG ( bool good_frame , const cv : : Mat_ < double > & hog_descriptor , int num_cols , int num_rows , int num_channels ) ;
2017-11-03 17:40:07 +01:00
void SetObservationVisualization ( const cv : : Mat & vis_track ) ;
2017-11-03 09:34:55 +01:00
2017-11-02 10:06:53 +01:00
void WriteObservation ( ) ;
2017-11-01 20:39:49 +01:00
2017-11-05 09:14:01 +01:00
std : : string GetCSVFile ( ) { return csv_filename ; }
2017-11-01 20:39:49 +01:00
private :
2017-12-15 20:56:58 +01:00
// Blocking copy, assignment and move operators, as it does not make sense to save to the same location
RecorderOpenFace & operator = ( const RecorderOpenFace & other ) ;
RecorderOpenFace & operator = ( const RecorderOpenFace & & other ) ;
RecorderOpenFace ( const RecorderOpenFace & & other ) ;
RecorderOpenFace ( const RecorderOpenFace & other ) ;
2018-01-18 09:08:29 +01:00
void PrepareRecording ( const std : : string & in_filename ) ;
2018-01-16 09:58:51 +01:00
2017-11-05 09:14:01 +01:00
// Keeping track of what to output and how to output it
const RecorderOpenFaceParameters params ;
2017-11-01 20:39:49 +01:00
// Keep track of the file and output root location
2017-11-17 08:54:22 +01:00
std : : string record_root ;
std : : string default_record_directory = " processed " ; // By default we are writing in the processed directory in the working directory, if no output parameters provided
2018-01-18 09:08:29 +01:00
std : : string out_name ; // Short name, based on which other names are constructed
2017-11-05 08:45:19 +01:00
std : : string csv_filename ;
2017-11-05 09:51:27 +01:00
std : : string aligned_output_directory ;
2017-11-12 22:40:30 +01:00
std : : ofstream metadata_file ;
2017-11-01 20:39:49 +01:00
// The actual output file stream that will be written
RecorderCSV csv_recorder ;
RecorderHOG hog_recorder ;
2017-11-02 10:06:53 +01:00
// The actual temporary storage for the observations
2018-02-23 09:25:19 +01:00
2017-11-02 10:06:53 +01:00
double timestamp ;
2018-02-23 09:25:19 +01:00
int face_id ;
int frame_number ;
2017-11-02 10:06:53 +01:00
// Facial landmark related observations
cv : : Mat_ < double > landmarks_2D ;
cv : : Mat_ < double > landmarks_3D ;
2017-11-03 09:34:55 +01:00
cv : : Vec6d pdm_params_global ;
cv : : Mat_ < double > pdm_params_local ;
2017-11-02 10:06:53 +01:00
double landmark_detection_confidence ;
bool landmark_detection_success ;
// Head pose related observations
cv : : Vec6d head_pose ;
// Action Unit related observations
std : : vector < std : : pair < std : : string , double > > au_intensities ;
std : : vector < std : : pair < std : : string , double > > au_occurences ;
// Gaze related observations
2017-11-03 09:34:55 +01:00
cv : : Point3f gaze_direction0 ;
cv : : Point3f gaze_direction1 ;
2017-11-02 10:08:24 +01:00
cv : : Vec2d gaze_angle ;
2017-11-11 22:13:29 +01:00
std : : vector < cv : : Point2d > eye_landmarks2D ;
std : : vector < cv : : Point3d > eye_landmarks3D ;
2017-11-02 10:06:53 +01:00
2018-02-23 09:25:19 +01:00
int m_frame_number ; // TODO this should be set
int m_face_id ; // TODO this should be set
2017-11-02 21:11:58 +01:00
2017-11-03 09:34:55 +01:00
// For video writing
cv : : VideoWriter video_writer ;
2017-11-16 21:50:08 +01:00
std : : string media_filename ;
2017-11-03 17:40:07 +01:00
cv : : Mat vis_to_out ;
2017-11-03 09:34:55 +01:00
2017-11-05 09:51:27 +01:00
// For aligned face writing
cv : : Mat aligned_face ;
2017-11-01 20:39:49 +01:00
} ;
}
# endif