2 開発の事前準備

2.1 命令集チェック

Windowsの場合、runtime_check.exeを用いてFMAとAVX命令集の存在を確認します。FMAとAVX命令集をサポートしない場合,SSE命令集の指定が必要です。

// システムがサポートする命令集を確認する
// FMA/AVXパラメーターを用いてruntime_check.exeを実行させます
// 返り値は"true"の場合は, FMA/AVXは利用可能です。
static bool runtime_check(bool *fma, bool *avx) {
    if (!fma || !avx) {
        return false;
    }
  *fma = true;
    *avx = true;
    char exe[] = "runtime_check.exe ";
    bool is_exist = false;
    if (_access(exe, 0) == 0) {
        is_exist = true;
    }
    if (is_exist) {
        char arg[2][4] = { "FMA", "AVX" };
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
        memset(&pi, 0, sizeof(PROCESS_INFORMATION));
        memset(&si, 0, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.dwFlags |= STARTF_USESTDHANDLES; // STARTF_USESTDHANDLES is Required.
        si.dwFlags |= STARTF_USESHOWWINDOW;
         si.wShowWindow = SW_HIDE;
        BOOL bSuccess;
        int i;
        for (i = 0; i < 2; i++) {
            SECURITY_ATTRIBUTES saAttr;
            saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
            saAttr.bInheritHandle = TRUE;
            saAttr.lpSecurityDescriptor = NULL;
            HANDLE hChildStdoutRd = NULL;
            HANDLE hChildStdoutWr = NULL; 
            if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
                printf("cannot create pipe\n");
                return false;
            }
            // Ensure the read handle to the pipe for STDOUT is not inherited.
            if (!SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0)) {
                printf("Stdout SetHandleInformation");
                return false;
            }
            si.hStdOutput = hChildStdoutWr;
            si.hStdError = hChildStdoutWr;
            // Requires STARTF_USESTDHANDLES in dwFlags
            // Requires STARTF_USESTDHANDLES in dwFlags
            char *cmd = new char[strlen(exe) + strlen(arg[i]) + 1];
            strcpy(cmd, exe);
            strcat(cmd, arg[i]);
            bSuccess = CreateProcess(
                NULL,   // No module name (use command line)
                cmd,    // Command line
                NULL,   // Process handle not inheritable
                NULL,   // Thread handle not inheritable
                TRUE,   // Set handle inheritance to TRUE
                0,      // No creation flags
                NULL,   // Use parent's environment block
                NULL,   // Use parent's starting directory
                &si,    // Pointer to STARTUPINFO structure
                &pi);   // Pointer to PROCESS_INFORMATION structure
            delete[] cmd;
            if (bSuccess) {
                if (0 == i) *fma = false;
                if (1 == i) *avx = false;
                WaitForSingleObject(pi.hProcess, INFINITE);
            if (!CloseHandle(hChildStdoutWr)) {
            printf("cannot close handle");
            return false;
            }
            std::string strResult;
            // Read output from the child process.
            for (;;) {
                DWORD dwRead;
                char chBuf[64];
                // Read from pipe that is the standard output for child process.
                bSuccess = ReadFile(hChildStdoutRd, chBuf, 64, &dwRead, NULL);
                if (!bSuccess || 0 == dwRead) {
                break; 
                }
                strResult += std::string(chBuf, dwRead);
            }
            if (strResult.length() > 0) {
                std::size_t pos = strResult.find(":");
                strResult = strResult.substr(pos + 2, 4);
                if (strResult == "true") {
                    if (0 == i) *fma = true;
                    if (1 == i) *avx = true;
                }
            }
            CloseHandle(hChildStdoutRd);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            }
            else {
            printf("CreateProcess failed: %d\n", GetLastError());
            *fma = false;
            *avx = false;
            return false;
            }     
        }
    if (bSuccess && (!(*fma) || !(*avx)))
        return false;
    }
    return true;
}

2.2 SDK のアクティベーション

SDK はライセンスファイルに従って、アルゴリズムライブラリの権限をチェックします。通常、アクティベーション完了後にのみ、SDK の機能を使用できます。

license_online.licファイルを実行ファイルと同じフォルダにコピーしてください。,check_license_online()メソッドはライセンス認証を行います。詳細は helper.hに参照してください。

アクティベーションコードの認証手順は以下の通りです。

  1. ライセンスファイルのコンテンツを読み込みます。

  2. ローカルコンピュータに保存されたアクティベーションコードを取得します。

  3. 利用可能なアクティベーションコードがない場合は、生成します。

  4. checkActiveCode *コマンドを直接実行して、アクティベーションコードが有効であるかどうか確認します。

  5. 確認に失敗した場合、別のアクティベーションコードを生成します。生成に失敗した場合、エラーメッセージが表示されます。成功すると、新しいアクティベーションコードが保存され、成功したことを示すメッセージが表示されます。

static int check_license_online() {
    // generate and check active code
    char activate_buf[10000] = { 0 };
    int activate_buf_len = sizeof(activate_buf);
    const char* license_path = "license_online.lic";
    const char* activate_path = "activate_code.lic";
    std::ifstream in(activate_path);
    if (!in.eof()) {
        in >> activate_buf;
        in.close();
    } 
    int ret = st_mobile_check_activecode(license_path, activate_buf, strlen(activate_buf));
    if (ret != ST_OK){
        printf("we will generate new activate_code %d\n", ret);
        ret = st_mobile_generate_activecode(license_path, activate_buf, &activate_buf_len);
        if (ret == ST_OK) {
            std::ofstream out(activate_path);
            out << activate_buf;
            out.close();
        } else{ 
            printf("fail to generate activate_code %d\n", ret);
            return -1; 
        } 
    } 
    return 0; 
} 

2.3 モデルファイルの利用

st_mobile_human_action_createst_mobile_human_action_create_with_sub_modelsを用いてmodelファイルをロードします。詳細はSampleプロジェクトのhelper.hに記載されているmodelモデルファイルの利用方法を参照してください。

const char* face_model = "M_SenseME_Face_Video_7.0.3.model";
const char* face_282_model = "M_SenseME_Face_Extra_Advanced_6.0.8.model";
const char* hand_model = "M_SenseME_Hand_6.0.8.model";
const char* segment_model = "M_SenseME_Segment_4.12.8.model";
const char* body14_model = "M_SenseME_Body_5.5.6.model";
const char* body_contour_model = "M_SenseME_Body_Contour_77_1.2.2.model";
const char* face_extra_model = "M_SenseME_Face_Extra_Advanced_6.0.8.model";
const char* mouth_parse_model = "M_SenseME_MouthOcclusion_1.0.0.model";
const char* eyeball_model = "M_SenseME_Iris_2.0.0.model";
const char* ear_model = "M_SenseME_Ear_1.0.1.model";
const char* body4_model = "M_SenseME_Body_Four_1.0.0.model";
const char* body8_model = "body8.model";
const char* hair_model = "M_SenseME_Segment_Hair_1.3.4.model";
const char* tongue_model = "M_SenseME_Tongue_1.0.0.model";
const char* face_mesh_model = "M_SenseME_3Dmesh_1.4.0.model";
const char* avatar_helper_model = "M_SenseME_Avatar_Help_2.2.0.model";
const char* gaze_model = "M_SenseME_GazeTracking_2.1.3.model";
const char* dynamic_gesture_model = "M_SenseME_Hand_Dynamic_Gesture_1.0.0.model";
const char* hand_skeleton_model = "M_SenseME_Hand_Skeleton_2d3d_1.0.0.model";
const char* multi_segment_model = "M_SenseME_Segment_Multiclass_1.0.0.model";
const char* attribute_model = "M_SenseME_Attribute_2.2.0.model";
const char* animal_model = "M_SenseME_CatFace_3.0.0.model";
const char* classify_model = "M_SenseME_Classify_3.4.10.model";
const char* verify_model = "M_SenseME_Verify_3.91.0.model";
const char* p_db_path = "M_SenseME_Classify_Table_1.0.7.db";
const char* p_custom_db_path = "M_SenseME_Classify_Custom_Table_1.0.7.db";
const char* upbody_model = "M_SenseME_Upper_Body_0.0.42.model";
static std::string g_ModelDir = "../models/";

Last updated