#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(p.x) << "," << static_cast(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(im.plane_addr[0]) << "," << static_cast(im.plane_addr[1]) << "," << static_cast(im.plane_addr[2]) << "," << static_cast(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