From 7eeb8dfaede7bb54b37b8ea538135914a43ab011 Mon Sep 17 00:00:00 2001 From: Wim Vriend <facetracknoir@gmail.com> Date: Mon, 21 Mar 2011 21:32:13 +0000 Subject: New effort to embrace faceAPI 3.2.6 git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@54 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- faceAPI/utils.h | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 faceAPI/utils.h (limited to 'faceAPI/utils.h') diff --git a/faceAPI/utils.h b/faceAPI/utils.h new file mode 100644 index 00000000..9c67665e --- /dev/null +++ b/faceAPI/utils.h @@ -0,0 +1,346 @@ +#ifndef SM_API_TESTAPPCONSOLE_UTILS_H +#define SM_API_TESTAPPCONSOLE_UTILS_H + +#include "lock.h" + +#define THROW_ON_ERROR(x) \ +{ \ + smReturnCode result = (x); \ + if (result < 0) \ + { \ + std::stringstream s; \ + s << "API error code: " << result; \ + throw std::runtime_error(s.str()); \ + } \ +} + +namespace sm +{ + namespace faceapi + { + namespace samplecode + { + // Global variables + Mutex g_mutex; + bool g_ctrl_c_detected(false); + bool g_do_head_pose_printing(false); + bool g_do_face_data_printing(false); + unsigned short g_overlay_flags(SM_API_VIDEO_DISPLAY_HEAD_MESH); + + // CTRL-C handler function + void __cdecl CtrlCHandler(int) + { + Lock lock(g_mutex); + std::cout << "Ctrl-C detected, stopping..." << std::endl; + g_ctrl_c_detected = true; + } + + // Radians to degrees conversion + float rad2deg(float rad) + { + return rad*57.2957795f; + } + + void toggleFlag(unsigned short &val, unsigned short flag) + { + if (val & flag) + { + val = val & ~flag; + } + else + { + val = val | flag; + } + } + + // Save an image to PNG file + smReturnCode saveToPNGFile(const std::string& filepath, smImageInfo image_info) + { + smBool ok; + smReturnCode error; + + // Create an API string + smStringHandle filepath_handle = 0; + ok = (error = smStringCreate(&filepath_handle)) == SM_API_OK; + ok = ok && (error = smStringReadBuffer(filepath_handle,filepath.c_str(),filepath.size())) == SM_API_OK; + + // Create an API image + smImageHandle image_handle = 0; + smImageMemoryCopyMode copy_mode = SM_API_IMAGE_MEMORYCOPYMODE_AUTO; + ok = ok && (error = smImageCreateFromInfo(&image_info,©_mode,&image_handle)) == SM_API_OK; + + // Save the image as PNG + ok = ok && (error = smImageSaveToPNG(image_handle,filepath_handle)) == SM_API_OK; + + // Destroy the image and string + smStringDestroy(&filepath_handle); + smImageDestroy(&image_handle); + return error; + } + + // Stream operators for printing + + std::ostream &operator<<(std::ostream & os, const smSize2i &s) + { + return os << "[" << s.h << "," << s.h << "]"; + } + + std::ostream &operator<<(std::ostream & os, const smCoord3f &pos) + { + return os << "(" << pos.x << "," << pos.y << "," << pos.z << ")"; + } + + std::ostream &operator<<(std::ostream & os, const smRotEuler &rot) + { + return os << "(" << rad2deg(rot.x_rads) << "," << rad2deg(rot.y_rads) << "," << rad2deg(rot.z_rads) << ")"; + } + + std::ostream &operator<<(std::ostream & os, const smPixel &p) + { + return os << "[" << static_cast<int>(p.x) << "," << static_cast<int>(p.y) << "]"; + } + + std::ostream &operator<<(std::ostream & os, const smFaceTexCoord &ftc) + { + return os << "{" << ftc.u << "," << ftc.v << "}"; + } + + std::ostream &operator<<(std::ostream & os, const smFaceLandmark &lm) + { + return os << "id "<< lm.id << " fc" << lm.fc << " ftc" << lm.ftc << " pc" << lm.pc << " wc" << lm.wc; + } + + std::ostream &operator<<(std::ostream & os, const smImageInfo &im) + { + os << "format "; + switch (im.format) + { + case SM_API_IMAGECODE_GRAY_8U: + os << "GRAY_8U"; + break; + case SM_API_IMAGECODE_GRAY_16U: + os << "GRAY_16U"; + break; + case SM_API_IMAGECODE_YUY2: + os << "YUY2"; + break; + case SM_API_IMAGECODE_I420: + os << "I420"; + break; + case SM_API_IMAGECODE_BGRA_32U: + os << "BGRA_32U"; + break; + case SM_API_IMAGECODE_ARGB_32U: + os << "ARGB_32U"; + break; + case SM_API_IMAGECODE_BGR_24U: + os << "BGR_24U"; + break; + case SM_API_IMAGECODE_RGB_24U: + os << "RGB_24U"; + break; + default: + os << "unknown"; + break; + } + os << " res" << im.res; + os << " plane_addr(" << static_cast<void *>(im.plane_addr[0]) << "," + << static_cast<void *>(im.plane_addr[1]) << "," + << static_cast<void *>(im.plane_addr[2]) << "," + << static_cast<void *>(im.plane_addr[3]) << ")"; + os << " step_bytes(" << im.step_bytes[0] << "," << im.step_bytes[1] << "," << im.step_bytes[2] << "," << im.step_bytes[3] << ")"; + os << " user_data " << im.user_data; + return os; + } + + std::ostream &operator<<(std::ostream & os, const smFaceTexture &t) + { + os << "type "; + switch (t.type) + { + case SM_ORTHOGRAPHIC_PROJECTION: + os << "orthographic"; + break; + default: + os << "unknown"; + break; + } + os << " origin" << t.origin << " scale" << t.scale << std::endl; + os << " image_info " << t.image_info << std::endl; + os << " num_mask_landmarks " << t.num_mask_landmarks << std::endl; + for (int i=0; i<t.num_mask_landmarks; i++) + { + os << " " << t.mask_landmarks[i] << std::endl; + } + return os; + } + + // Stream operator for printing face landmarks + std::ostream &operator<<(std::ostream &os, const smEngineFaceData &face_data) + { + fixed(os); + showpos(os); + os.precision(2); + os << "Face Data: " + << "origin_wc" << face_data.origin_wc << " " + << "num_landmarks " << face_data.num_landmarks + << std::endl; + for (int i=0; i<face_data.num_landmarks; i++) + { + os << " " << face_data.landmarks[i] << std::endl; + } + // Print any face texture info + if (face_data.texture) + { + os << "Face Texture: " << *face_data.texture; + } + return os; + } + + // Stream operator for printing head-pose data + std::ostream &operator<<(std::ostream & os, const smEngineHeadPoseData &head_pose) + { + fixed(os); + showpos(os); + os.precision(2); + return os << "Head Pose: " + << "head_pos" << head_pose.head_pos << " " + << "head_rot" << head_pose.head_rot << " " + << "left_eye_pos" << head_pose.left_eye_pos << " " + << "right_eye_pos" << head_pose.right_eye_pos << " " + << "confidence " << head_pose.confidence; + } + + std::ostream &operator<<(std::ostream & os, const smCameraVideoFrame &vf) + { + fixed(os); + showpos(os); + os.precision(2); + return os << "Framenum: " << vf.frame_num; + } + + // Handles keyboard events: return false if quit. + bool processKeyPress(smEngineHandle engine_handle, smVideoDisplayHandle video_display_handle) + { + Lock lock(g_mutex); + if (g_ctrl_c_detected) + { + return false; + } + if (!_kbhit()) + { + return true; + } + int key = _getch(); + switch (key) + { + case 'q': + return false; + case 'r': + { + // Manually restart the tracking + THROW_ON_ERROR(smEngineStart(engine_handle)); + std::cout << "Restarting tracking" << std::endl; + } + return true; + case 'a': + { + // Toggle auto-restart mode + int on; + THROW_ON_ERROR(smHTGetAutoRestartMode(engine_handle,&on)); + THROW_ON_ERROR(smHTSetAutoRestartMode(engine_handle,!on)); + std::cout << "Autorestart-mode is " << (on?"on":"off") << std::endl; + } + return true; + case '1': + toggleFlag(g_overlay_flags,SM_API_VIDEO_DISPLAY_REFERENCE_FRAME); + THROW_ON_ERROR(smVideoDisplaySetFlags(video_display_handle,g_overlay_flags)); + return true; + case '2': + toggleFlag(g_overlay_flags,SM_API_VIDEO_DISPLAY_PERFORMANCE); + THROW_ON_ERROR(smVideoDisplaySetFlags(video_display_handle,g_overlay_flags)); + return true; + case '3': + toggleFlag(g_overlay_flags,SM_API_VIDEO_DISPLAY_HEAD_MESH); + THROW_ON_ERROR(smVideoDisplaySetFlags(video_display_handle,g_overlay_flags)); + return true; + case '4': + toggleFlag(g_overlay_flags,SM_API_VIDEO_DISPLAY_LANDMARKS); + THROW_ON_ERROR(smVideoDisplaySetFlags(video_display_handle,g_overlay_flags)); + return true; + case 'l': + if (smAPINonCommercialLicense() == SM_API_TRUE) + { + return false; + } + else + { + int on; + THROW_ON_ERROR(smHTGetLipTrackingEnabled(engine_handle,&on)); + THROW_ON_ERROR(smHTSetLipTrackingEnabled(engine_handle,!on)); + } + return true; + case 'e': + if (smAPINonCommercialLicense() == SM_API_TRUE) + { + return false; + } + else + { + int on; + THROW_ON_ERROR(smHTGetEyebrowTrackingEnabled(engine_handle,&on)); + THROW_ON_ERROR(smHTSetEyebrowTrackingEnabled(engine_handle,!on)); + } + return true; + case 'h': + if (smEngineIsLicensed(engine_handle) != SM_API_OK) + { + return false; + } + else + { + g_do_head_pose_printing = !g_do_head_pose_printing; + std::cout << "HeadPose printing is " << (g_do_head_pose_printing?"on":"off") << std::endl; + } + return true; + case 'f': + if (smEngineIsLicensed(engine_handle) != SM_API_OK) + { + return false; + } + else + { + g_do_face_data_printing = !g_do_face_data_printing; + std::cout << "FaceData printing is " << (g_do_face_data_printing?"on":"off") << std::endl; + } + return true; + default: + return true; + } + } + + // Setup console window geometry / font etc + void initConsole() + { + HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + // Buffer of 255 x 1024 + ////COORD buffer_size; + ////buffer_size.X = 255; + ////buffer_size.Y = 1024; + ////SetConsoleScreenBufferSize(console_handle, buffer_size); + ////// Window size of 120 x 50 + ////SMALL_RECT window_size; + ////window_size.Left = 0; + ////window_size.Right = 20; + ////window_size.Top = 0; + ////window_size.Bottom = 20; + ////SetConsoleWindowInfo(console_handle,TRUE,&window_size); + // Green text + SetConsoleTextAttribute(console_handle, FOREGROUND_GREEN | FOREGROUND_INTENSITY); + ShowWindow(GetConsoleWindow(), SW_HIDE); + } + } + } +} + +#endif -- cgit v1.2.3