#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ImageListener.h" using namespace affdex; /** * TOdo: make sure this handles logging to json on onImageResults() */ class LoggingImageListener : public ImageListener { std::mutex mMutex; std::deque > > mDataArray; double mCaptureLastTS; double mCaptureFPS; double mProcessLastTS; double mProcessFPS; std::ofstream &fStream; std::chrono::time_point mStartT; const bool mDrawDisplay; const int spacing = 10; const float font_size = 0.5f; const int font = cv::FONT_HERSHEY_COMPLEX_SMALL; std::vector expressions; std::vector emotions; std::vector emojis; std::vector headAngles; std::map glassesMap; std::map genderMap; std::map ageMap; std::map ethnicityMap; public: LoggingImageListener(std::ofstream &csv, const bool draw_display) : fStream(csv), mDrawDisplay(draw_display), mStartT(std::chrono::system_clock::now()), mCaptureLastTS(-1.0f), mCaptureFPS(-1.0f), mProcessLastTS(-1.0f), mProcessFPS(-1.0f) { expressions = { "smile", "innerBrowRaise", "browRaise", "browFurrow", "noseWrinkle", "upperLipRaise", "lipCornerDepressor", "chinRaise", "lipPucker", "lipPress", "lipSuck", "mouthOpen", "smirk", "eyeClosure", "attention", "eyeWiden", "cheekRaise", "lidTighten", "dimpler", "lipStretch", "jawDrop" }; emotions = { "joy", "fear", "disgust", "sadness", "anger", "surprise", "contempt", "valence", "engagement" }; headAngles = { "pitch", "yaw", "roll" }; emojis = std::vector { "relaxed", "smiley", "laughing", "kissing", "disappointed", "rage", "smirk", "wink", "stuckOutTongueWinkingEye", "stuckOutTongue", "flushed", "scream" }; genderMap = std::map { { affdex::Gender::Male, "male" }, { affdex::Gender::Female, "female" }, { affdex::Gender::Unknown, "unknown" }, }; glassesMap = std::map { { affdex::Glasses::Yes, "yes" }, { affdex::Glasses::No, "no" } }; ageMap = std::map { { affdex::Age::AGE_UNKNOWN, "unknown"}, { affdex::Age::AGE_UNDER_18, "under 18" }, { affdex::Age::AGE_18_24, "18-24" }, { affdex::Age::AGE_25_34, "25-34" }, { affdex::Age::AGE_35_44, "35-44" }, { affdex::Age::AGE_45_54, "45-54" }, { affdex::Age::AGE_55_64, "55-64" }, { affdex::Age::AGE_65_PLUS, "65 plus" } }; ethnicityMap = std::map { { affdex::Ethnicity::UNKNOWN, "unknown"}, { affdex::Ethnicity::CAUCASIAN, "caucasian" }, { affdex::Ethnicity::BLACK_AFRICAN, "black african" }, { affdex::Ethnicity::SOUTH_ASIAN, "south asian" }, { affdex::Ethnicity::EAST_ASIAN, "east asian" }, { affdex::Ethnicity::HISPANIC, "hispanic" } }; } void onImageResults(std::map faces, Frame image) override { std::lock_guard lg(mMutex); mDataArray.push_back(std::pair>(image, faces)); std::chrono::time_point now = std::chrono::system_clock::now(); std::chrono::milliseconds milliseconds = std::chrono::duration_cast(now - mStartT); double seconds = milliseconds.count() / 1000.f; mProcessFPS = 1.0f / (seconds - mProcessLastTS); mProcessLastTS = seconds; }; void onImageCapture(Frame image) override { std::lock_guard lg(mMutex); mCaptureFPS = 1.0f / (image.getTimestamp() - mCaptureLastTS); mCaptureLastTS = image.getTimestamp(); }; };