From cdeb071732fd74b876906113c5ed54dede98af1d Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Fri, 18 Mar 2016 14:28:55 -0400 Subject: [PATCH 01/10] Add CMakeLists files to generate and compile the sample applications on Ubuntu 14.04 --- CMakeLists.txt | 162 ++++++++++++++++++++++++++++++ README.md | 32 +++++- opencv-webcam-demo/CMakeLists.txt | 34 +++++++ video-demo/CMakeLists.txt | 34 +++++++ 4 files changed, 258 insertions(+), 4 deletions(-) create mode 100755 CMakeLists.txt create mode 100755 opencv-webcam-demo/CMakeLists.txt create mode 100755 video-demo/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..cb46788 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,162 @@ +cmake_minimum_required(VERSION 2.6) + +set(rootProject cpp-sdk-samples) +project(${rootProject}) + +# CMake includes +include(cmake_modules/Macros.cmake) # Some custom macros we have writtens + +# ------------------- +# CMAKE - ENVIRONMENT +# -------------------- +set(CXX_COMPILER_WARNINGS "-Wreturn-type" CACHE STRING "Compiler warnings to use") +set(CMAKE_VERBOSE ON CACHE BOOL "Verbose mode") +# Setup "Profile" build type +set(CMAKE_CXX_FLAGS_PROFILE "-O3 -pg") +set(CMAKE_C_FLAGS_PROFILE "-O3 -pg") +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "-pg") +set(CMAKE_MODULE_LINKER_FLAGS_PROFILE "-pg") + +# Setup additional compiler warnings +status("Setting up compiler warnings") +if( MSVC ) + # Force to always compile with W4 + if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" ) + string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) + else() + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" ) + endif() +elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + # Update if necessary + set( CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS} ${CXX_COMPILER_WARNINGS}" ) +endif() + +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + status("Updating compiler to make use of C++14") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") +endif() + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(bitness 64) # We have a 64-bit machine +else() + set(bitness 32) # We have a 32-bit machine +endif() +status("Bitness detected: ${bitness}") + + +# Setup install locations +if( NOT RUNTIME_INSTALL_DIRECTORY ) + set( RUNTIME_INSTALL_DIRECTORY "bin" CACHE STRING "Install sub-directory of CMAKE_INSTALL_PREFIX for RUNTIME targets (binaries, and *.dll on windows)." ) +endif( NOT RUNTIME_INSTALL_DIRECTORY ) + +# -------------------- +# LOCATE DEPENDENCIES +# -------------------- + +# OpenCV +# ---------------------------------------------------------------------------- +# find_package OpenCV to get OpenCV_FOUND, OpenCV_INCLUDE_DIRS, OpenCV_LIBS, OpenCV_LINK_LIBRARIES +# ---------------------------------------------------------------------------- +set( OPENCV_COMPONENTS ml highgui core imgproc objdetect ) +if( DEFINED OpenCV_DIR ) # Force the user to tell us which OpenCV they want (otherwise find_package can find the wrong one, cache it and changes to OpenCV_DIR are ignored) + find_package(OpenCV REQUIRED PATHS ${OpenCV_DIR}) + if( NOT OpenCV_FOUND) + message(SEND_ERROR "Failed to find OpenCV. Double check that \"OpenCV_DIR\" to the root build directory of OpenCV.") + endif(NOT OpenCV_FOUND) +else( DEFINED OpenCV_DIR ) + set( OpenCV_DIR "" CACHE PATH "Root directory for opencv BUILD directory." ) + message(FATAL_ERROR "\"OpenCV_DIR\" not set. Please explicitly provide the path to the root build directory of OpenCV.") +endif( DEFINED OpenCV_DIR ) + +# Boost package +# ---------------------------------------------------------------------------- +# BOOST_ROOT is needed by BoostConfig.cmake configuration file to +# look for the Boost includes / libraries: +# Boost_FOUND, Boost_INCLUDE_DIRS, Boost_LIBRARY_DIRS, Boost_LIBRARIES,Boost_VERSION +set(Boost_USE_MULTITHREADED ON) +set( BOOST_COMPONENTS system filesystem date_time regex thread timer chrono serialization log log_setup program_options) + +set( BOOST_MIN_VERSION "1.55.0" CACHE STRING "Minimum version of boost you would like to link against (e.g. C:/BOOST_1_55_0 is 1.55.0" ) +status("") +if( ANDROID ) + find_host_package( Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS ${BOOST_COMPONENTS} ) +else( ANDROID ) + find_package( Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS ${BOOST_COMPONENTS} ) +endif() +if( NOT Boost_FOUND ) + if( NOT DEFINED BOOST_ROOT ) + set( BOOST_ROOT "" CACHE PATH "Root directory for Boost." ) + endif( NOT DEFINED BOOST_ROOT ) + message( FATAL_ERROR "Failed to find Boost (or missing components). Double check that \"BOOST_ROOT\" is properly set") +endif( NOT Boost_FOUND ) + + + +# Affdex package +# ---------------------------------------------------------------------------- + +set (AFFDEX_FOUND FALSE) + +if( DEFINED AFFDEX_DIR ) + find_path(AFFDEX_INCLUDE_DIR FrameDetector.h + HINTS "${AFFDEX_DIR}/include" ) + + find_library(AFFDEX_LIBRARY NAMES affdex-native + HINTS "${AFFDEX_DIR}/lib" ) + + set(AFFDEX_INCLUDE_DIRS "${AFFDEX_INCLUDE_DIR}") + set(AFFDEX_LIBRARIES "${AFFDEX_LIBRARY}") + + if (AFFDEX_INCLUDE_DIR AND AFFDEX_LIBRARY) + set(AFFDEX_FOUND TRUE) + endif (AFFDEX_INCLUDE_DIR AND AFFDEX_LIBRARY) + + set(AFFDEX_DATA_DIR "${AFFDEX_DIR}/data") + + + if (NOT AFFDEX_FOUND) + message(FATAL_ERROR "Unable to find the Affdex found") + endif (NOT AFFDEX_FOUND) + +else (DEFINED AFFDEX_DIR) + message(FATAL_ERROR "Please define AFFDEX_DIR") +endif (DEFINED AFFDEX_DIR) + + +add_subdirectory(opencv-webcam-demo) +add_subdirectory(video-demo) + +# -------------------- +# SUMMARY +# -------------------- +status("${CMAKE_INCLUDE_DIRECTORIES}") +status( "------- SUMMARY ------- " ) +status( "Boost version found = ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION} (${Boost_VERSION})" ) +foreach( comp ${BOOST_COMPONENTS} ) + string( TOUPPER ${comp} COMP ) + status( " - ${comp}" 1 THEN "${Boost_${COMP}_LIBRARY}" ) +endforeach( comp ) + +status("") +status("Affdex") +foreach( lib ${AFFDEX_LIBRARIES} ) + status( "${lib}") +endforeach( lib ) + +status("") +status( "OpenCV version found = ${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH} (${OpenCV_VERSION})" ) +status( "OpenCV_LIB_DIR = ${OpenCV_DIR}/lib" ) +foreach( lib ${OpenCV_LIBRARIES} ) + foreach( comp ${OPENCV_COMPONENTS} ) + if( ${lib} MATCHES ${comp} ) + status( " - ${comp}" 1 THEN "${lib}" ) + endif( ${lib} MATCHES ${comp} ) + endforeach( comp ) +endforeach( lib ) + +status("") +status( "Apps identified for building:" ) +foreach( app ${${rootProject}_APPS} ) + status( " - ${app}" ) +endforeach( app ${${rootProject}_APPS} ) \ No newline at end of file diff --git a/README.md b/README.md index 19f2d96..51cc580 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -#Sample Apps for Affdex SDK for Windows +#Sample Apps for Affdex C++ SDK for Windows / Linux -Welcome to our repository on GitHub! Here you will find example code to get you started with our Affdex SDK 3.0 for Windows and begin emotion-enabling you own app! Documentation for the Windows SDK is at Affectiva's Developer Portal. +Welcome to our repository on GitHub! Here you will find example code to get you started with our Affdex SDK 3.0 and begin emotion-enabling you own app! Documentation for the SDKs is available on the Affectiva's Developer Portal. [![Build status](https://ci.appveyor.com/api/projects/status/pn2y9h8a3nnkiw41?svg=true)] (https://ci.appveyor.com/project/ahamino/win-sdk-samples) @@ -8,22 +8,46 @@ Welcome to our repository on GitHub! Here you will find example code to get you Dependencies ------------ +*Windows* - Affdex SDK 3.0 (32 bit) - Visual Studio 2013 or higher +*Linux* +- Ubuntu 14.04 or higher or CentOS 7 or higher +- Affdex SDK 3.0 +- CMake 2.8 or higher +- GCC 4.8 or higher -*Additional dependencies for the C++ projects* +*Additional dependencies* - OpenCV 3.1 - Boost 1.59 Installation ------------ -- Download Affdex SDK for windows [from here](http://developer.affectiva.com/downloads) + +- Download Affdex SDK [from here](http://developer.affectiva.com/downloads) - Sign up for an evaluation license [by submitting this form](http://www.affectiva.com/45-day-free-trial/) + +*Windows* - Install the SDK using MSI installer. - The additional dependencies get installed automatically by NuGet. +*Ubuntu* + +```bashrc +sudo apt-get install build-essential libopencv-dev libboost-dev cmake +wget http://developer.affectiva.com/downloads/linux +mkdir affdex-sdk +tar -xzvf affdex-cpp-sdk-3.0-linux-64bit.tar.gz -C affdex-sdk +export AFFDEX_DATA_DIR=affdex-sdk/data +git clone https://github.com/Affectiva/win-sdk-samples.git +mkdir build +cd build +cmake -DOpenCV_DIR=/usr/local/ -DAFFDEX_DIR=../affdex-sdk ../win-sdk-samples +make +``` + OpenCV-webcam-demo (c++) ------------------ diff --git a/opencv-webcam-demo/CMakeLists.txt b/opencv-webcam-demo/CMakeLists.txt new file mode 100755 index 0000000..ab707c3 --- /dev/null +++ b/opencv-webcam-demo/CMakeLists.txt @@ -0,0 +1,34 @@ +# -------------- +# CMake file opencv-webcam-demo +# -------------- + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +set(subProject opencv-webcam-demo) + +PROJECT(${subProject}) + +file(GLOB SRCS *.c*) +file(GLOB HDRS *.h*) + +if( ${CMAKE_VERSION} VERSION_GREATER 2.8.11 ) + get_filename_component(PARENT_DIR ${PROJECT_SOURCE_DIR} DIRECTORY) # PATH was updated to DIRECTORY in 2.8.12 +else() + get_filename_component(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH) +endif() +set(COMMON_HDRS "${PARENT_DIR}/common/") +file(GLOB COMMON_HDRS_FILES ${COMMON_HDRS}/*.h*) + +add_executable(${subProject} ${SRCS} ${HDRS} ${COMMON_HDRS_FILES}) + +target_include_directories(${subProject} PRIVATE ${Boost_INCLUDE_DIRS} ${AFFDEX_INCLUDE_DIR} ${COMMON_HDRS}) + +target_link_libraries( ${subProject} ${AFFDEX_LIBRARIES} ${OpenCV_LIBS} ${Boost_LIBRARIES} ) + +#Add to the apps list +list( APPEND ${rootProject}_APPS ${subProject} ) +set( ${rootProject}_APPS ${${rootProject}_APPS} PARENT_SCOPE ) + +# Installation steps +install( TARGETS ${subProject} + RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY} ) \ No newline at end of file diff --git a/video-demo/CMakeLists.txt b/video-demo/CMakeLists.txt new file mode 100755 index 0000000..3ed20b9 --- /dev/null +++ b/video-demo/CMakeLists.txt @@ -0,0 +1,34 @@ +# -------------- +# CMake file video-demo +# -------------- + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +set(subProject video-demo) + +PROJECT(${subProject}) + +file(GLOB SRCS *.c*) +file(GLOB HDRS *.h*) + +if( ${CMAKE_VERSION} VERSION_GREATER 2.8.11 ) + get_filename_component(PARENT_DIR ${PROJECT_SOURCE_DIR} DIRECTORY) # PATH was updated to DIRECTORY in 2.8.12 +else() + get_filename_component(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH) +endif() +set(COMMON_HDRS "${PARENT_DIR}/common/") +file(GLOB COMMON_HDRS_FILES ${COMMON_HDRS}/*.h*) + +add_executable(${subProject} ${SRCS} ${HDRS} ${COMMON_HDRS_FILES}) + +target_include_directories(${subProject} PRIVATE ${Boost_INCLUDE_DIRS} ${AFFDEX_INCLUDE_DIR} ${COMMON_HDRS}) + +target_link_libraries( ${subProject} ${AFFDEX_LIBRARIES} ${OpenCV_LIBS} ${Boost_LIBRARIES} ) + +#Add to the apps list +list( APPEND ${rootProject}_APPS ${subProject} ) +set( ${rootProject}_APPS ${${rootProject}_APPS} PARENT_SCOPE ) + +# Installation steps +install( TARGETS ${subProject} + RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY} ) \ No newline at end of file From 1c529efd07cbce645cd592cafebbb0d9af7e7ebf Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Fri, 18 Mar 2016 14:31:27 -0400 Subject: [PATCH 02/10] Add custom module --- cmake_modules/Macros.cmake | 106 +++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 cmake_modules/Macros.cmake diff --git a/cmake_modules/Macros.cmake b/cmake_modules/Macros.cmake new file mode 100644 index 0000000..eaef629 --- /dev/null +++ b/cmake_modules/Macros.cmake @@ -0,0 +1,106 @@ +# Extracting the subdirectories from a given folder +# +# Usage: +# SUBDIRLIST( SUBDIRS "path/to/base/dir" ) +# +# Source: http://stackoverflow.com/questions/7787823/cmake-how-to-get-the-name-of-all-subdirectories-of-a-directory + +MACRO(SUBDIRLIST result curdir) + FILE(GLOB children RELATIVE ${curdir} ${curdir}/*) + SET(dirlist "") + FOREACH(child ${children}) + IF(IS_DIRECTORY ${curdir}/${child}) + SET(dirlist ${dirlist} ${child}) + ENDIF() + ENDFOREACH() + SET(${result} ${dirlist}) +ENDMACRO() + +# Search packages for host system instead of packages for target system +# in case of cross compilation thess macro should be defined by toolchain file +# adopted from OpenCV +if(NOT COMMAND find_host_package) + macro(find_host_package) + find_package(${ARGN}) + endmacro() +endif() +if(NOT COMMAND find_host_program) + macro(find_host_program) + find_program(${ARGN}) + endmacro() +endif() + +macro(check_environment_variables) + foreach(_var ${ARGN}) + if(NOT DEFINED ${_var} AND DEFINED ENV{${_var}}) + set(__value "$ENV{${_var}}") + file(TO_CMAKE_PATH "${__value}" __value) # Assume that we receive paths + set(${_var} "${__value}") + message(STATUS "Update variable ${_var} from environment: ${${_var}}") + endif() + endforeach() +endmacro() + +# Status convinience function. +# adopted from OpenCV +function(output_status msg) + message(STATUS "${msg}") + string(REPLACE "\\" "\\\\" msg "${msg}") + string(REPLACE "\"" "\\\"" msg "${msg}") +endfunction() + +# Status report function. +# Automatically align right column and selects text based on condition. +# Usage: +# status() +# status( [ ...]) +# status( THEN ELSE ) +# adopted from OpenCV +function(status text) + set(status_cond) + set(status_then) + set(status_else) + + set(status_current_name "cond") + foreach(arg ${ARGN}) + if(arg STREQUAL "THEN") + set(status_current_name "then") + elseif(arg STREQUAL "ELSE") + set(status_current_name "else") + else() + list(APPEND status_${status_current_name} ${arg}) + endif() + endforeach() + + if(DEFINED status_cond) + set(status_placeholder_length 18) + string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder) + string(LENGTH "${text}" status_text_length) + if(status_text_length LESS status_placeholder_length) + string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text) + elseif(DEFINED status_then OR DEFINED status_else) + output_status("${text}") + set(status_text "${status_placeholder}") + else() + set(status_text "${text}") + endif() + + if(DEFINED status_then OR DEFINED status_else) + if(${status_cond}) + string(REPLACE ";" " " status_then "${status_then}") + string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}") + output_status("${status_text} ${status_then}") + else() + string(REPLACE ";" " " status_else "${status_else}") + string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}") + output_status("${status_text} ${status_else}") + endif() + else() + string(REPLACE ";" " " status_cond "${status_cond}") + string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}") + output_status("${status_text} ${status_cond}") + endif() + else() + output_status("${text}") + endif() +endfunction() From f6fc7b19f16ea1799dcf94cc355ac91d11e8d184 Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Fri, 18 Mar 2016 14:56:35 -0400 Subject: [PATCH 03/10] Fix installation instructions for boost on ubuntu 14.04 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 51cc580..1cea792 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Installation *Ubuntu* ```bashrc -sudo apt-get install build-essential libopencv-dev libboost-dev cmake +sudo apt-get install build-essential libopencv-dev libboost1.55-all-dev cmake wget http://developer.affectiva.com/downloads/linux mkdir affdex-sdk tar -xzvf affdex-cpp-sdk-3.0-linux-64bit.tar.gz -C affdex-sdk From 961aa8de97525a671108cf59e774f7e866f59d84 Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Fri, 18 Mar 2016 16:35:54 -0400 Subject: [PATCH 04/10] Add travis.yml file for linux builds --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..07e56a4 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +dist: trusty +language: cpp +compiler: + - gcc-4.8 +before_script: + - sudo apt-get install -y gcc-4.8 g++-4.8 libopencv-dev libboost1.55-all-dev cmake + - wget http://affdex-sdk-dist.s3-website-us-east-1.amazonaws.com/linux/download_sdk.html -O /tmp/affdex-sdk.tar.gz + - mkdir /tmp/affdex-sdk + - tar -xzvf /tmp/affdex-sdk.tar.gz -C /tmp/affdex-sdk + - mkdir build + - cd build + - cmake -DBOOST_ROOT=/usr/ -DOpenCV_DIR=/usr/ -DAFFDEX_DIR=/tmp/affdex-sdk .. +script: + - make From 4b4e1e05baaf8ff8dbbb423ef7f5f94fffde68ec Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Fri, 25 Mar 2016 13:52:08 -0400 Subject: [PATCH 05/10] Add ld_library_path export --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1cea792..e811c3a 100644 --- a/README.md +++ b/README.md @@ -38,14 +38,15 @@ Installation ```bashrc sudo apt-get install build-essential libopencv-dev libboost1.55-all-dev cmake wget http://developer.affectiva.com/downloads/linux -mkdir affdex-sdk -tar -xzvf affdex-cpp-sdk-3.0-linux-64bit.tar.gz -C affdex-sdk -export AFFDEX_DATA_DIR=affdex-sdk/data -git clone https://github.com/Affectiva/win-sdk-samples.git -mkdir build -cd build -cmake -DOpenCV_DIR=/usr/local/ -DAFFDEX_DIR=../affdex-sdk ../win-sdk-samples +mkdir $HOME/affdex-sdk +tar -xzvf affdex-cpp-sdk-3.0-linux-64bit.tar.gz -C $HOME/affdex-sdk +export AFFDEX_DATA_DIR=$HOME/affdex-sdk/data +git clone https://github.com/Affectiva/cpp-sdk-samples.git $HOME/sdk-samples +mkdir $HOME/build +cd $HOME/build +cmake -DOpenCV_DIR=/usr/ -DBOOST_ROOT=/usr/ -DAFFDEX_DIR=$HOME/affdex-sdk $HOME/sdk-samples make +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/affdex-sdk/lib ``` From 0d8c63f95994ab30160ee67dcaee9a85295a7134 Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Tue, 5 Apr 2016 11:13:23 -0400 Subject: [PATCH 06/10] Add emojis to the output file --- common/PlottingImageListener.hpp | 140 +++++++++++++--------- opencv-webcam-demo/opencv-webcam-demo.cpp | 1 + video-demo/video-demo.cpp | 43 +++---- 3 files changed, 107 insertions(+), 77 deletions(-) diff --git a/common/PlottingImageListener.hpp b/common/PlottingImageListener.hpp index cbf3638..02d2eec 100644 --- a/common/PlottingImageListener.hpp +++ b/common/PlottingImageListener.hpp @@ -24,10 +24,10 @@ using namespace affdex; class PlottingImageListener : public ImageListener { - + std::mutex mMutex; std::deque > > mDataArray; - + double mCaptureLastTS; double mCaptureFPS; double mProcessLastTS; @@ -38,17 +38,18 @@ class PlottingImageListener : public ImageListener 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; - + public: - - + + PlottingImageListener(std::ofstream &csv, const bool draw_display) : fStream(csv), mDrawDisplay(draw_display), mStartT(std::chrono::system_clock::now()), mCaptureLastTS(-1.0f), mCaptureFPS(-1.0f), @@ -59,35 +60,45 @@ public: "upperLipRaise", "lipCornerDepressor", "chinRaise", "lipPucker", "lipPress", "lipSuck", "mouthOpen", "smirk", "eyeClosure", "attention" }; - + 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, "glasses" }, { affdex::Glasses::No, "no glasses" } }; - - fStream << "TimeStamp,faceId,interocularDistance,glasses,gender,"; + + fStream << "TimeStamp,faceId,interocularDistance,glasses,gender,dominantEmoji,"; for (std::string angle : headAngles) fStream << angle << ","; for (std::string emotion : emotions) fStream << emotion << ","; for (std::string expression : expressions) fStream << expression << ","; + for (std::string emoji : emojis) fStream << emoji << ","; fStream << std::endl; fStream.precision(4); fStream << std::fixed; } - + FeaturePoint minPoint(VecFeaturePoint points) { VecFeaturePoint::iterator it = points.begin(); @@ -99,7 +110,7 @@ public: } return ret; }; - + FeaturePoint maxPoint( VecFeaturePoint points) { VecFeaturePoint::iterator it = points.begin(); @@ -111,27 +122,27 @@ public: } return ret; }; - - + + double getProcessingFrameRate() { std::lock_guard lg(mMutex); return mProcessFPS; } - + double getCaptureFrameRate() { std::lock_guard lg(mMutex); return mCaptureFPS; } - + int getDataSize() { std::lock_guard lg(mMutex); return mDataArray.size(); - + } - + std::pair> getData() { std::lock_guard lg(mMutex); @@ -139,7 +150,7 @@ public: mDataArray.pop_front(); return dpoint; } - + void onImageResults(std::map faces, Frame image) override { std::lock_guard lg(mMutex); @@ -150,58 +161,68 @@ public: 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(); }; - + void outputToFile(const std::map faces, const double timeStamp) { if (faces.empty()) { - fStream << timeStamp << "nan,nan,no glasses,unknown,"; + fStream << timeStamp << "nan,nan,no glasses,unknown, unknown,"; for (std::string angle : headAngles) fStream << "nan,"; for (std::string emotion : emotions) fStream << "nan,"; for (std::string expression : expressions) fStream << "nan,"; + for (std::string emoji : emojis) fStream << "nan,"; fStream << std::endl; } for (auto & face_id_pair : faces) { Face f = face_id_pair.second; - + fStream << timeStamp << "," << f.id << "," << f.measurements.interocularDistance << "," << glassesMap[f.appearance.glasses] << "," - << genderMap[f.appearance.gender] << ","; - + << genderMap[f.appearance.gender] << "," + << affdex::EmojiToString(f.emojis.dominantEmoji) << ","; + float *values = (float *)&f.measurements.orientation; for (std::string angle : headAngles) { fStream << (*values) << ","; values++; } - + values = (float *)&f.emotions; for (std::string emotion : emotions) { fStream << (*values) << ","; values++; } - + values = (float *)&f.expressions; for (std::string expression : expressions) { fStream << (*values) << ","; values++; } + + values = (float *)&f.emojis; + for (std::string emoji : emojis) + { + fStream << (*values) << ","; + values++; + } + fStream << std::endl; } } - + void drawValues(const float * first, const std::vector names, const int x, int &padding, const cv::Scalar clr, cv::Mat img) @@ -217,18 +238,18 @@ public: first++; } } - + void draw(const std::map faces, Frame image) { std::shared_ptr imgdata = image.getBGRByteArray(); cv::Mat img = cv::Mat(image.getHeight(), image.getWidth(), CV_8UC3, imgdata.get()); - + const int left_margin = 30; - - - cv::Scalar clr = cv::Scalar(255, 255, 255); + + + cv::Scalar clr = cv::Scalar(0, 0, 255); cv::Scalar header_clr = cv::Scalar(255, 0, 0); - + for (auto & face_id_pair : faces) { Face f = face_id_pair.second; @@ -239,49 +260,56 @@ public: } FeaturePoint tl = minPoint(points); FeaturePoint br = maxPoint(points); - + //Output the results of the different classifiers. int padding = tl.y + 10; - + cv::putText(img, "APPEARANCE", cv::Point(br.x, padding += (spacing * 2)), font, font_size, header_clr); cv::putText(img, genderMap[f.appearance.gender], cv::Point(br.x, padding += spacing), font, font_size, clr); cv::putText(img, glassesMap[f.appearance.glasses], cv::Point(br.x, padding += spacing), font, font_size, clr); - - - + + + Orientation headAngles = f.measurements.orientation; - + char strAngles[100]; sprintf(strAngles, "Pitch: %3.2f Yaw: %3.2f Roll: %3.2f Interocular: %3.2f", headAngles.pitch, headAngles.yaw, headAngles.roll, f.measurements.interocularDistance); - - - + + + char fId[10]; sprintf(fId, "ID: %i", f.id); cv::putText(img, fId, cv::Point(br.x, padding += spacing), font, font_size, clr); - + cv::putText(img, "MEASUREMENTS", cv::Point(br.x, padding += (spacing * 2)), font, font_size, header_clr); - + cv::putText(img, strAngles, cv::Point(br.x, padding += spacing), font, font_size, clr); - + + cv::putText(img, "EMOJIS", cv::Point(br.x, padding += (spacing * 2)), font, font_size, header_clr); + + cv::putText(img, "dominantEmoji: " + affdex::EmojiToString(f.emojis.dominantEmoji), + cv::Point(br.x, padding += spacing), font, font_size, clr); + + drawValues((float *)&f.emojis, emojis, br.x, padding, clr, img); + cv::putText(img, "EXPRESSIONS", cv::Point(br.x, padding += (spacing * 2)), font, font_size, header_clr); - + drawValues((float *)&f.expressions, expressions, br.x, padding, clr, img); - + cv::putText(img, "EMOTIONS", cv::Point(br.x, padding += (spacing * 2)), font, font_size, header_clr); - + drawValues((float *)&f.emotions, emotions, br.x, padding, clr, img); - + } char fps_str[50]; sprintf(fps_str, "capture fps: %2.0f", mCaptureFPS); cv::putText(img, fps_str, cv::Point(img.cols - 110, img.rows - left_margin - spacing), font, font_size, clr); sprintf(fps_str, "process fps: %2.0f", mProcessFPS); cv::putText(img, fps_str, cv::Point(img.cols - 110, img.rows - left_margin), font, font_size, clr); - + cv::imshow("analyze video", img); cv::waitKey(5); } - + }; diff --git a/opencv-webcam-demo/opencv-webcam-demo.cpp b/opencv-webcam-demo/opencv-webcam-demo.cpp index 9d6c05b..e32f744 100644 --- a/opencv-webcam-demo/opencv-webcam-demo.cpp +++ b/opencv-webcam-demo/opencv-webcam-demo.cpp @@ -126,6 +126,7 @@ int main(int argsc, char ** argsv) //Initialize detectors frameDetector->setDetectAllEmotions(true); frameDetector->setDetectAllExpressions(true); + frameDetector->setDetectAllEmojis(true); frameDetector->setDetectGender(true); frameDetector->setDetectGlasses(true); frameDetector->setClassifierPath(DATA_FOLDER); diff --git a/video-demo/video-demo.cpp b/video-demo/video-demo.cpp index 4e9d29d..72b5ac9 100644 --- a/video-demo/video-demo.cpp +++ b/video-demo/video-demo.cpp @@ -35,11 +35,11 @@ int main(int argsc, char ** argsv) bool loop = false; unsigned int nFaces = 1; int faceDetectorMode = (int)FaceDetectorMode::SMALL_FACES; - + const int precision = 2; std::cerr.precision(precision); std::cout.precision(precision); - + namespace po = boost::program_options; // abbreviate namespace po::options_description description("Project for demoing the Windows SDK VideoDetector class (processing video files)."); description.add_options() @@ -76,7 +76,7 @@ int main(int argsc, char ** argsv) std::cerr << "For help, use the -h option." << std::endl << std::endl; return 1; } - + // Parse and check the data folder (with assets) if (!boost::filesystem::exists(DATA_FOLDER)) { @@ -89,20 +89,20 @@ int main(int argsc, char ** argsv) { //Initialize the video file detector VideoDetector videoDetector(process_framerate, nFaces, (affdex::FaceDetectorMode) faceDetectorMode); - + //Initialize out file boost::filesystem::path csvPath(videoPath); csvPath.replace_extension(".csv"); std::ofstream csvFileStream(csvPath.c_str()); - + if (!csvFileStream.is_open()) { std::cerr << "Unable to open csv file " << csvPath << std::endl; return 1; } - - - + + + std::cout << "Max num of faces set to: " << videoDetector.getMaxNumberFaces() << std::endl; std::string mode; switch (videoDetector.getFaceDetectorMode()) @@ -116,13 +116,14 @@ int main(int argsc, char ** argsv) default: break; } - + std::cout << "Face detector mode set to: " << mode << std::endl; shared_ptr listenPtr(new PlottingImageListener(csvFileStream, draw_display)); - + //Activate all the detectors videoDetector.setDetectAllEmotions(true); videoDetector.setDetectAllExpressions(true); + videoDetector.setDetectAllEmojis(true); videoDetector.setDetectGender(true); videoDetector.setDetectGlasses(true); //Set the location of the data folder and license file @@ -130,16 +131,16 @@ int main(int argsc, char ** argsv) videoDetector.setLicensePath(LICENSE_PATH); //Add callback functions implementations videoDetector.setImageListener(listenPtr.get()); - - + + videoDetector.start(); //Initialize the detectors .. call only once - + do { shared_ptr videoListenPtr = std::make_shared(); videoDetector.setProcessStatusListener(videoListenPtr.get()); videoDetector.process(videoPath); //Process a video - + //For each frame processed while (videoListenPtr->isRunning()) { @@ -148,34 +149,34 @@ int main(int argsc, char ** argsv) std::pair > dataPoint = listenPtr->getData(); Frame frame = dataPoint.first; std::map faces = dataPoint.second; - - + + //Draw on the GUI if (draw_display) { listenPtr->draw(faces, frame); } - + std::cerr << "timestamp: " << frame.getTimestamp() << " cfps: " << listenPtr->getCaptureFrameRate() << " pfps: " << listenPtr->getProcessingFrameRate() << " faces: "<< faces.size() << endl; - + //Output metrics to file listenPtr->outputToFile(faces, frame.getTimestamp()); } } } while(loop); - + videoDetector.stop(); csvFileStream.close(); - + std::cout << "Output written to file: " << csvPath << std::endl; } catch (AffdexException ex) { std::cerr << ex.what(); } - + return 0; } From 549e446f2140ef9e8dfc9022ba34c2507abbb1f8 Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Tue, 5 Apr 2016 11:25:50 -0400 Subject: [PATCH 07/10] Add to video-demo the ability to process photos as well as images --- video-demo/video-demo.cpp | 126 +++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 51 deletions(-) diff --git a/video-demo/video-demo.cpp b/video-demo/video-demo.cpp index 72b5ac9..695ff1a 100644 --- a/video-demo/video-demo.cpp +++ b/video-demo/video-demo.cpp @@ -3,13 +3,14 @@ #include #include -#include +#include #include #include #include #include #include "VideoDetector.h" +#include "PhotoDetector.h" #include "AffdexException.h" #include "AFaceListener.hpp" @@ -20,13 +21,17 @@ using namespace std; using namespace affdex; -/// -/// Project demos how to use the Affdex Windows SDK VideoDetector -/// int main(int argsc, char ** argsv) { - - //Defaults, overridden by the command line parameters + + + + std::map VIDEO_EXTS = { {boost::filesystem::path(".avi"), 1}, + {boost::filesystem::path(".mov"), 1}, + {boost::filesystem::path(".flv"), 1}, + {boost::filesystem::path(".webm"), 1}, + {boost::filesystem::path(".wmv"), 1}, + {boost::filesystem::path(".mp4"), 1} }; affdex::path DATA_FOLDER; affdex::path LICENSE_PATH; affdex::path videoPath; @@ -34,12 +39,12 @@ int main(int argsc, char ** argsv) bool draw_display = true; bool loop = false; unsigned int nFaces = 1; - int faceDetectorMode = (int)FaceDetectorMode::SMALL_FACES; - + int faceDetectorMode = (int)FaceDetectorMode::LARGE_FACES; + const int precision = 2; std::cerr.precision(precision); std::cout.precision(precision); - + namespace po = boost::program_options; // abbreviate namespace po::options_description description("Project for demoing the Windows SDK VideoDetector class (processing video files)."); description.add_options() @@ -76,7 +81,7 @@ int main(int argsc, char ** argsv) std::cerr << "For help, use the -h option." << std::endl << std::endl; return 1; } - + // Parse and check the data folder (with assets) if (!boost::filesystem::exists(DATA_FOLDER)) { @@ -87,25 +92,37 @@ int main(int argsc, char ** argsv) } try { - //Initialize the video file detector - VideoDetector videoDetector(process_framerate, nFaces, (affdex::FaceDetectorMode) faceDetectorMode); - + std::shared_ptr detector; + //Initialize out file boost::filesystem::path csvPath(videoPath); + boost::filesystem::path fileExt = csvPath.extension(); csvPath.replace_extension(".csv"); std::ofstream csvFileStream(csvPath.c_str()); - + if (!csvFileStream.is_open()) { std::cerr << "Unable to open csv file " << csvPath << std::endl; return 1; } - - - - std::cout << "Max num of faces set to: " << videoDetector.getMaxNumberFaces() << std::endl; + + if (VIDEO_EXTS[fileExt]) // IF it is a video file. + { + detector = std::make_shared(process_framerate, nFaces, (affdex::FaceDetectorMode) faceDetectorMode); + } + else //Otherwise it's a photo + { + detector = std::make_shared(nFaces, (affdex::FaceDetectorMode) faceDetectorMode); + } + + + //VideoDetector videoDetector(process_framerate, nFaces, (affdex::FaceDetectorMode) faceDetectorMode); + + + + std::cout << "Max num of faces set to: " << detector->getMaxNumberFaces() << std::endl; std::string mode; - switch (videoDetector.getFaceDetectorMode()) + switch (detector->getFaceDetectorMode()) { case FaceDetectorMode::LARGE_FACES: mode = "LARGE_FACES"; @@ -116,67 +133,74 @@ int main(int argsc, char ** argsv) default: break; } - + std::cout << "Face detector mode set to: " << mode << std::endl; shared_ptr listenPtr(new PlottingImageListener(csvFileStream, draw_display)); - - //Activate all the detectors - videoDetector.setDetectAllEmotions(true); - videoDetector.setDetectAllExpressions(true); - videoDetector.setDetectAllEmojis(true); - videoDetector.setDetectGender(true); - videoDetector.setDetectGlasses(true); - //Set the location of the data folder and license file - videoDetector.setClassifierPath(DATA_FOLDER); - videoDetector.setLicensePath(LICENSE_PATH); - //Add callback functions implementations - videoDetector.setImageListener(listenPtr.get()); - - - videoDetector.start(); //Initialize the detectors .. call only once - + + detector->setDetectAllEmotions(true); + detector->setDetectAllExpressions(true); + detector->setDetectAllEmojis(true); + detector->setDetectGender(true); + detector->setDetectGlasses(true); + detector->setClassifierPath(DATA_FOLDER); + detector->setLicensePath(LICENSE_PATH); + detector->setImageListener(listenPtr.get()); + + + detector->start(); //Initialize the detectors .. call only once + do { shared_ptr videoListenPtr = std::make_shared(); - videoDetector.setProcessStatusListener(videoListenPtr.get()); - videoDetector.process(videoPath); //Process a video - - //For each frame processed - while (videoListenPtr->isRunning()) + detector->setProcessStatusListener(videoListenPtr.get()); + if (VIDEO_EXTS[fileExt]) + { + ((VideoDetector *)detector.get())->process(videoPath); //Process a video + } + else + { + //videoPath is of type std::wstring on windows, but std::string on other platforms. + cv::Mat img = cv::imread(std::string(videoPath.begin(), videoPath.end())); + + // Create a frame + Frame frame(img.size().width, img.size().height, img.data, Frame::COLOR_FORMAT::BGR); + + ((PhotoDetector *)detector.get())->process(frame); //Process an image + } + + while (!VIDEO_EXTS[fileExt] || videoListenPtr->isRunning()) { if (listenPtr->getDataSize() > 0) { std::pair > dataPoint = listenPtr->getData(); Frame frame = dataPoint.first; std::map faces = dataPoint.second; - - - //Draw on the GUI + + if (draw_display) { listenPtr->draw(faces, frame); } - + std::cerr << "timestamp: " << frame.getTimestamp() << " cfps: " << listenPtr->getCaptureFrameRate() << " pfps: " << listenPtr->getProcessingFrameRate() << " faces: "<< faces.size() << endl; - - //Output metrics to file + listenPtr->outputToFile(faces, frame.getTimestamp()); } } } while(loop); - - videoDetector.stop(); + + detector->stop(); csvFileStream.close(); - + std::cout << "Output written to file: " << csvPath << std::endl; } catch (AffdexException ex) { std::cerr << ex.what(); } - + return 0; } From 9af6fcd9c2e7ba42e3aa08a7497578180f7ad513 Mon Sep 17 00:00:00 2001 From: abdelrahman Date: Tue, 5 Apr 2016 13:58:40 -0400 Subject: [PATCH 08/10] Fix a bug where the screen hangs in the case of photo/video --- CMakeLists.txt | 4 ++-- video-demo/video-demo.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb46788..179a120 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,7 @@ endif( DEFINED OpenCV_DIR ) set(Boost_USE_MULTITHREADED ON) set( BOOST_COMPONENTS system filesystem date_time regex thread timer chrono serialization log log_setup program_options) -set( BOOST_MIN_VERSION "1.55.0" CACHE STRING "Minimum version of boost you would like to link against (e.g. C:/BOOST_1_55_0 is 1.55.0" ) +set( BOOST_MIN_VERSION "1.54.0" CACHE STRING "Minimum version of boost you would like to link against (e.g. C:/BOOST_1_55_0 is 1.55.0" ) status("") if( ANDROID ) find_host_package( Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS ${BOOST_COMPONENTS} ) @@ -159,4 +159,4 @@ status("") status( "Apps identified for building:" ) foreach( app ${${rootProject}_APPS} ) status( " - ${app}" ) -endforeach( app ${${rootProject}_APPS} ) \ No newline at end of file +endforeach( app ${${rootProject}_APPS} ) diff --git a/video-demo/video-demo.cpp b/video-demo/video-demo.cpp index 695ff1a..2a2d043 100644 --- a/video-demo/video-demo.cpp +++ b/video-demo/video-demo.cpp @@ -168,7 +168,7 @@ int main(int argsc, char ** argsv) ((PhotoDetector *)detector.get())->process(frame); //Process an image } - while (!VIDEO_EXTS[fileExt] || videoListenPtr->isRunning()) + while (VIDEO_EXTS[fileExt] && videoListenPtr->isRunning()) { if (listenPtr->getDataSize() > 0) { From 40617630861491addd4103f847b5be5a9d78e9a7 Mon Sep 17 00:00:00 2001 From: abdelrahman Date: Tue, 5 Apr 2016 14:30:11 -0400 Subject: [PATCH 09/10] iFix bug in video-demo --- video-demo/video-demo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/video-demo/video-demo.cpp b/video-demo/video-demo.cpp index 2a2d043..a2ce230 100644 --- a/video-demo/video-demo.cpp +++ b/video-demo/video-demo.cpp @@ -168,7 +168,7 @@ int main(int argsc, char ** argsv) ((PhotoDetector *)detector.get())->process(frame); //Process an image } - while (VIDEO_EXTS[fileExt] && videoListenPtr->isRunning()) + do { if (listenPtr->getDataSize() > 0) { @@ -189,7 +189,7 @@ int main(int argsc, char ** argsv) listenPtr->outputToFile(faces, frame.getTimestamp()); } - } + } while(VIDEO_EXTS[fileExt] && videoListenPtr->isRunning()); } while(loop); detector->stop(); From 7c66b5e7af8801fee00decbe806483e028b3fc4d Mon Sep 17 00:00:00 2001 From: Abdelrahman Mahmoud Date: Fri, 8 Apr 2016 10:12:02 -0400 Subject: [PATCH 10/10] Remove the word Windows from the man pages --- README.md | 4 +- opencv-webcam-demo/opencv-webcam-demo.cpp | 2 +- video-demo/video-demo.cpp | 60 +++++++++++------------ 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index e811c3a..b71d2e0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#Sample Apps for Affdex C++ SDK for Windows / Linux +#Sample Apps for Affdex SDK for Windows and Linux Welcome to our repository on GitHub! Here you will find example code to get you started with our Affdex SDK 3.0 and begin emotion-enabling you own app! Documentation for the SDKs is available on the Affectiva's Developer Portal. @@ -74,7 +74,7 @@ The following command line arguments can be used to run it: Video-demo (c++) ---------- -Project for demoing the Windows SDK [VideoDetector class](http://developer.affectiva.com/v3/windows/analyze-video/). It processs video files, displays the emotion metrics and exports the results in a csv file. +Project for demoing the C++ SDK [VideoDetector class](http://developer.affectiva.com/v3/windows/analyze-video/). It processs video files, displays the emotion metrics and exports the results in a csv file. The following command line arguments can be used to run it: diff --git a/opencv-webcam-demo/opencv-webcam-demo.cpp b/opencv-webcam-demo/opencv-webcam-demo.cpp index e32f744..40aa2c2 100644 --- a/opencv-webcam-demo/opencv-webcam-demo.cpp +++ b/opencv-webcam-demo/opencv-webcam-demo.cpp @@ -52,7 +52,7 @@ int main(int argsc, char ** argsv) std::cerr.precision(precision); std::cout.precision(precision); - po::options_description description("Project for demoing the Windows SDK CameraDetector class (grabbing and processing frames from the camera)."); + po::options_description description("Project for demoing the Affdex SDK CameraDetector class (grabbing and processing frames from the camera)."); description.add_options() ("help,h", po::bool_switch()->default_value(false), "Display this help message.") #ifdef _WIN32 diff --git a/video-demo/video-demo.cpp b/video-demo/video-demo.cpp index 695ff1a..dadd059 100644 --- a/video-demo/video-demo.cpp +++ b/video-demo/video-demo.cpp @@ -23,9 +23,9 @@ using namespace affdex; int main(int argsc, char ** argsv) { - - - + + + std::map VIDEO_EXTS = { {boost::filesystem::path(".avi"), 1}, {boost::filesystem::path(".mov"), 1}, {boost::filesystem::path(".flv"), 1}, @@ -40,13 +40,13 @@ int main(int argsc, char ** argsv) bool loop = false; unsigned int nFaces = 1; int faceDetectorMode = (int)FaceDetectorMode::LARGE_FACES; - + const int precision = 2; std::cerr.precision(precision); std::cout.precision(precision); - + namespace po = boost::program_options; // abbreviate namespace - po::options_description description("Project for demoing the Windows SDK VideoDetector class (processing video files)."); + po::options_description description("Project for demoing the Affdex SDK VideoDetector class (processing video files)."); description.add_options() ("help,h", po::bool_switch()->default_value(false), "Display this help message.") #ifdef _WIN32 @@ -81,7 +81,7 @@ int main(int argsc, char ** argsv) std::cerr << "For help, use the -h option." << std::endl << std::endl; return 1; } - + // Parse and check the data folder (with assets) if (!boost::filesystem::exists(DATA_FOLDER)) { @@ -93,19 +93,19 @@ int main(int argsc, char ** argsv) try { std::shared_ptr detector; - + //Initialize out file boost::filesystem::path csvPath(videoPath); boost::filesystem::path fileExt = csvPath.extension(); csvPath.replace_extension(".csv"); std::ofstream csvFileStream(csvPath.c_str()); - + if (!csvFileStream.is_open()) { std::cerr << "Unable to open csv file " << csvPath << std::endl; return 1; } - + if (VIDEO_EXTS[fileExt]) // IF it is a video file. { detector = std::make_shared(process_framerate, nFaces, (affdex::FaceDetectorMode) faceDetectorMode); @@ -114,12 +114,12 @@ int main(int argsc, char ** argsv) { detector = std::make_shared(nFaces, (affdex::FaceDetectorMode) faceDetectorMode); } - - + + //VideoDetector videoDetector(process_framerate, nFaces, (affdex::FaceDetectorMode) faceDetectorMode); - - - + + + std::cout << "Max num of faces set to: " << detector->getMaxNumberFaces() << std::endl; std::string mode; switch (detector->getFaceDetectorMode()) @@ -133,10 +133,10 @@ int main(int argsc, char ** argsv) default: break; } - + std::cout << "Face detector mode set to: " << mode << std::endl; shared_ptr listenPtr(new PlottingImageListener(csvFileStream, draw_display)); - + detector->setDetectAllEmotions(true); detector->setDetectAllExpressions(true); detector->setDetectAllEmojis(true); @@ -145,10 +145,10 @@ int main(int argsc, char ** argsv) detector->setClassifierPath(DATA_FOLDER); detector->setLicensePath(LICENSE_PATH); detector->setImageListener(listenPtr.get()); - - + + detector->start(); //Initialize the detectors .. call only once - + do { shared_ptr videoListenPtr = std::make_shared(); @@ -161,13 +161,13 @@ int main(int argsc, char ** argsv) { //videoPath is of type std::wstring on windows, but std::string on other platforms. cv::Mat img = cv::imread(std::string(videoPath.begin(), videoPath.end())); - + // Create a frame Frame frame(img.size().width, img.size().height, img.data, Frame::COLOR_FORMAT::BGR); - + ((PhotoDetector *)detector.get())->process(frame); //Process an image } - + while (!VIDEO_EXTS[fileExt] || videoListenPtr->isRunning()) { if (listenPtr->getDataSize() > 0) @@ -175,32 +175,32 @@ int main(int argsc, char ** argsv) std::pair > dataPoint = listenPtr->getData(); Frame frame = dataPoint.first; std::map faces = dataPoint.second; - - + + if (draw_display) { listenPtr->draw(faces, frame); } - + std::cerr << "timestamp: " << frame.getTimestamp() << " cfps: " << listenPtr->getCaptureFrameRate() << " pfps: " << listenPtr->getProcessingFrameRate() << " faces: "<< faces.size() << endl; - + listenPtr->outputToFile(faces, frame.getTimestamp()); } } } while(loop); - + detector->stop(); csvFileStream.close(); - + std::cout << "Output written to file: " << csvPath << std::endl; } catch (AffdexException ex) { std::cerr << ex.what(); } - + return 0; }