コード例 #1
0
// MATLAB entry point
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if (nrhs != 1)
    {
        mexErrMsgTxt("Improper number of input arguments.\n\n"
                "FLANDMARK_LOAD_MODEL loads model for flandmark detector to memory.\n\n"
                "Synopsis: \n"
                "model = flandmark_load_model(fname)\n"
                "\n"
                "Input: \n"
                "  fname [string]\n"
                "Output: \n"
                "  model [binary data]\n"
            );
    }

    int address_offset, dynamic_begin, lbp_pointer, disp_pointer;
    int model_size = 0, dynamic_offset = 0;
    double start, ms;
    char * fname = mxArrayToString(prhs[0]);
    int tsize = 0;
    FLANDMARK_PSIG * PsiGi = NULL;

    // check input
    if (fname == NULL)
    {
        mexErrMsgTxt("Improper argument type \"fname\"\n\n"
                     "  fname must be a string.");
    }

    /* read model */
    start = (double)cvGetTickCount();
    FLANDMARK_Model * model = flandmark_init(fname);
    if (model == 0)
    {
        mexErrMsgTxt("Error opening file with model structure.\n");
    }
    start = (double)cvGetTickCount() - start;
    ms = cvRound( start / ((double)cvGetTickFrequency() * 1000.0) );
    mexPrintf("Structure model loaded in %.6f ms\n", ms);

    uint8_t M = model->data.options.M;

    // Compute size of model_size -------------------------------------------
    model_size += sizeof(FLANDMARK_Model);
    model_size += model->W_ROWS*model->W_COLS*sizeof(double);
    model_size += model->data.options.bw[0]*model->data.options.bw[1]*sizeof(uint8_t);
    model_size += 4*sizeof(double);
    model_size += 2*sizeof(float);
    model_size += sizeof(FLANDMARK_LBP*);
    model_size += M*sizeof(FLANDMARK_LBP);
    for (int i = 0; i < M; ++i)
    {
        model_size += model->data.lbp[i].WINS_ROWS*model->data.lbp[i].WINS_COLS*sizeof(uint32_t);
    }
    model_size += 4*M*sizeof(double);
    model_size += sizeof(FLANDMARK_Options);
    model_size += 4*M*sizeof(int);
    for (int i = 0; i < 3; ++i)
    {
        switch (i)
        {
            case 0: PsiGi = model->data.options.PsiGS0;
            break;
            case 1: PsiGi = model->data.options.PsiGS1;
            break;
            case 2: PsiGi = model->data.options.PsiGS2;
            break;
        }

        tsize = model->data.options.PSIG_ROWS[i]*model->data.options.PSIG_COLS[i];

        for (int idx = 0; idx < tsize; ++idx)
        {
            model_size += sizeof(FLANDMARK_PSIG);
            model_size += PsiGi[idx].ROWS*PsiGi[idx].COLS*sizeof(int);
        }
    }

    mexPrintf("model_size = %d\n", model_size);
    //mexErrMsgTxt("Exitting for sure...\n");

    /* Create uint8 buffer for storing the structure into matlab memory */
    plhs[0] = mxCreateNumericMatrix(model_size, 1, mxUINT8_CLASS, mxREAL);
    uint8_t *buffer = (uint8_t*)mxGetPr(plhs[0]);

    // copy data from structure to memory
    // Statically allocated parts -----------------------------------------------

    // FLANDMARK_Model - static part
    address_offset = 0;
    memcpy(&buffer[address_offset], model, sizeof(FLANDMARK_Model));

    // FLANDMARK_Data - static part
    address_offset = (char*)&(model->data) - (char*)model;
    memcpy(&buffer[address_offset], &model->data, sizeof(FLANDMARK_Data));

    // FLANDMARK_Options - static part
    address_offset = (char*)&(model->data.options) - (char*)model;
    memcpy(&buffer[address_offset], &model->data.options, sizeof(FLANDMARK_Options));

    // Dynamically allocated parts ----------------------------------------------
    dynamic_offset = sizeof(FLANDMARK_Model);
    dynamic_begin = dynamic_offset;

    // model->W
    address_offset = dynamic_offset;
    memcpy(&buffer[address_offset], model->W, model->W_COLS*model->W_ROWS*sizeof(double));
    dynamic_offset += model->W_COLS*model->W_ROWS*sizeof(double);
    // update pointer model->W
    *(double**)&buffer[(char*)&(model->W)-(char*)model]=(double*)&buffer[address_offset];

    // model->normalizedImageFrame
    address_offset = dynamic_offset;
    memcpy(&buffer[address_offset], model->normalizedImageFrame, model->data.options.bw[0]*model->data.options.bw[1]*sizeof(uint8_t));
    dynamic_offset += model->data.options.bw[0]*model->data.options.bw[1]*sizeof(uint8_t);
    // update pointer model->normalizedImageFrame
    *(uint8_t**)&buffer[(char*)&(model->normalizedImageFrame)-(char*)model]=(uint8_t*)&buffer[address_offset];

    // model->bb
    address_offset = dynamic_offset;
    memcpy(&buffer[address_offset], model->bb, 4*sizeof(double));
    dynamic_offset += 4*sizeof(double);
    // update pointer model->bb
    *(double**)&buffer[(char*)&(model->bb)-(char*)model]=(double*)&buffer[address_offset];

    // model->sf
    address_offset = dynamic_offset;
    memcpy(&buffer[address_offset], model->sf, 2*sizeof(float));
    dynamic_offset += 2*sizeof(float);
    // update pointer model->sf
    *(float**)&buffer[(char*)&(model->sf)-(char*)model]=(float*)&buffer[address_offset];

    // model->data.mapTable
    address_offset = dynamic_offset;
    memcpy(&buffer[address_offset], model->data.mapTable, M*4*sizeof(int));
    dynamic_offset += M*4*sizeof(int);
    // update pointer model->data.mapTable
    *(int**)&buffer[(char*)&(model->data.mapTable)-(char*)model]=(int*)&buffer[address_offset];

    // model->data.options.S
    address_offset = dynamic_offset;
    memcpy(&buffer[address_offset], model->data.options.S, M*4*sizeof(int));
    dynamic_offset += M*4*sizeof(int);
    // update pointer model->data.options.S
    *(int**)&buffer[(char*)&(model->data.options.S)-(char*)model]=(int*)&buffer[address_offset];

    // model->data.lbp

    // lbp static part
    lbp_pointer = dynamic_offset;
    for (uint8_t i=0; i < M; ++i)
    {
        address_offset = dynamic_offset;
        memcpy(&buffer[address_offset], &model->data.lbp[i], sizeof(FLANDMARK_LBP));
        dynamic_offset += sizeof(FLANDMARK_LBP);
    }
    // Update pointer
    *(FLANDMARK_LBP**)&buffer[(char*)&(model->data.lbp)-(char*)model]=(FLANDMARK_LBP*)&buffer[lbp_pointer];

    // lbp dynamic part
    for (uint8_t i=0; i < M; ++i)
    {
        address_offset = dynamic_offset;
        memcpy(&buffer[address_offset], model->data.lbp[i].wins, model->data.lbp[i].WINS_COLS*model->data.lbp[i].WINS_ROWS*sizeof(uint32_t));
        dynamic_offset += model->data.lbp[i].WINS_COLS*model->data.lbp[i].WINS_ROWS*sizeof(uint32_t);
        // update pointer
        *(uint32_t**)&buffer[lbp_pointer+i*sizeof(FLANDMARK_LBP)+(long long)((char*)&(model->data.lbp[i].wins))-(long long)((char*)&(model->data.lbp[i]))]=(uint32_t*)&buffer[address_offset];
    }

    // model->data.options.PsiGSi

    for (int i=0; i < 3; ++i)
    {
        address_offset = dynamic_offset;
        switch(i)
        {
            case 0: PsiGi = model->data.options.PsiGS0;
                *(FLANDMARK_PSIG**)&buffer[(char*)&(model->data.options.PsiGS0)-(char*)model]=(FLANDMARK_PSIG*)&buffer[address_offset];
            break;
            case 1: PsiGi = model->data.options.PsiGS1;
                *(FLANDMARK_PSIG**)&buffer[(char*)&(model->data.options.PsiGS1)-(char*)model]=(FLANDMARK_PSIG*)&buffer[address_offset];
            break;
            case 2: PsiGi = model->data.options.PsiGS2;
                *(FLANDMARK_PSIG**)&buffer[(char*)&(model->data.options.PsiGS2)-(char*)model]=(FLANDMARK_PSIG*)&buffer[address_offset];
            break;
        }

        tsize = model->data.options.PSIG_COLS[i]*model->data.options.PSIG_ROWS[i];

        // static part
        disp_pointer = dynamic_offset;
        for (int idx=0; idx < tsize; ++idx)
        {
            address_offset = dynamic_offset;
            memcpy(&buffer[address_offset], &PsiGi[idx], sizeof(FLANDMARK_PSIG));
            dynamic_offset += sizeof(FLANDMARK_PSIG);
        }

        // dynamic part
        for (int idx=0; idx < tsize; ++idx)
        {
            address_offset = dynamic_offset;
            memcpy(&buffer[address_offset], PsiGi[idx].disp, PsiGi[idx].ROWS*PsiGi[idx].COLS*sizeof(int));
            dynamic_offset += PsiGi[idx].ROWS*PsiGi[idx].COLS*sizeof(int);
            // update pointer
            *(int**)&buffer[disp_pointer+idx*sizeof(FLANDMARK_PSIG)+(long long)((char*)&(PsiGi[idx].disp))-(long long)((char*)&(PsiGi[idx]))]=(int*)&buffer[address_offset];
        }
    }

    /* CHECK MODEL  */

    mexPrintf("Checking model...");

    FLANDMARK_Model *tmp = (FLANDMARK_Model*)buffer;

    EError_T err =  flandmark_check_model(model, tmp);

    if (err == NO_ERR)
    {
        mexPrintf(" passed.\n");
    } else {
        mexPrintf(" not passed!\n");

        switch (err)
        {
            case NO_ERR:
                mexErrMsgTxt("No error.\n");
                break;
            case ERROR_M:
                mexErrMsgTxt("model->M does not match!\n");
                break;
            case ERROR_BW:
                mexErrMsgTxt("model->data.bw does not match!\n");
                break;
            case ERROR_BW_MARGIN:
                mexErrMsgTxt("model->data.bw_margin does not match!\n");
                break;
            case ERROR_W:
                mexErrMsgTxt("model->W does not match!\n");
                break;
            case ERROR_DATA_IMAGES:
                mexErrMsgTxt("model->data.Images does not match!\n");
                break;
            case ERROR_DATA_MAPTABLE:
                mexErrMsgTxt("model->data.mapTable does not match!\n");
                break;
            case ERROR_DATA_LBP:
                mexErrMsgTxt("model->data.lbp does not match!\n");
                break;
            case ERROR_DATA_OPTIONS_S:
                mexErrMsgTxt("model->data.options.S does not match!\n");
                break;
            case ERROR_DATA_OPTIONS_PSIG:
                mexErrMsgTxt("model->data.options.PsiGSi does not match!\n");
                break;
            case UNKNOWN_ERROR:
                mexErrMsgTxt("Uknown error!\n");
                break;
        }
    }

    // clean model
    mexPrintf("Cleaning structure model... ");
    flandmark_free(model);
    mexPrintf(" done.\n");
}
コード例 #2
0
// MATLAB entry point
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if (nrhs < 2 || nrhs > 3)
    {
        mexErrMsgTxt("Improper number of input arguments.\n\n"
                "FLANDMARK_WRITE_MODEL loads model for flandmark detector and writes it to file.\n\n"
                "Synopsis: \n"
                "flandmark_write_model(model, fname)\n"
                "\n"
                "Input: \n"
                "  model [structure]\n"
                "  fname [string]\n"
            );
    }

    // variables for interface to matlab
    const mwSize *dims, *tmp_dims;
    mxArray *field_ptr, *field_data_ptr, *tmp_field_ptr, *cell_ptr;
    // pointers to data types used in mat file
    double * p_double = 0;
    uint32_t * p_uint32 = 0;
    int tsize = -1, tmp_tsize = -1;
    EError_T retval = UNKNOWN_ERROR;
    char * fname = mxArrayToString(prhs[1]);

    // check input
    if (!mxIsStruct(prhs[0]))
    {
        mexErrMsgTxt("Improper argument type \"model\".\n\n"
                "  model must be a structure containing joint parameter vector W and structure data.\n"
             );
    }
    mxArray *in_w = mxGetField(prhs[0], 0, "W");
    mxArray *in_data = mxGetField(prhs[0], 0, "data");
    if (in_w == NULL || in_data == NULL)
    {
        mexErrMsgTxt("Improper argument type \"model\".\n\n"
                "  model must be a structure containing joint parameter vector \"W\" and structure \"data\".\n"
             );
    }
    if (fname == NULL)
    {
        mexErrMsgTxt("Improper argument type \"fname\"\n\n"
                "  fname must be a string.\n"
              );
    }


    // Model structure (see detector_model.h for details)
    FLANDMARK_Model * model = (FLANDMARK_Model*)malloc(sizeof(FLANDMARK_Model));
    uint8_t M = 0;
    // model.data.options.M --------------------------------------------------
    mexPrintf("Getting number of components M:\n");
    field_data_ptr = mxGetField(prhs[0], 0, "data");
    field_ptr = mxGetField(field_data_ptr, 0, "options");
    tmp_field_ptr = mxGetField(field_ptr, 0, "M");
    p_double = (double*)mxGetPr(tmp_field_ptr);
    model->data.options.M = (uint8_t)p_double[0];
    M = model->data.options.M;
    mexPrintf("model->data.options.M = %d\n", model->data.options.M);
    // model->data.options.bw -------------------------------------------------
    tmp_field_ptr = mxGetField(field_ptr, 0, "bw");
    p_double = (double*)mxGetPr(tmp_field_ptr);
    model->data.options.bw[0] = (int)p_double[0];
    model->data.options.bw[1] = (int)p_double[1];
    mexPrintf("model->data.options.bw = [%d, %d]\n",
            model->data.options.bw[0], model->data.options.bw[1]);
    model->data.imSize[0] = model->data.options.bw[0];
    model->data.imSize[1] = model->data.options.bw[1];
    // model->data.options.bw_margin ------------------------------------------
    tmp_field_ptr = mxGetField(field_ptr, 0, "bw_margin");
    p_double = (double*)mxGetPr(tmp_field_ptr);
    model->data.options.bw_margin[0] = (int)p_double[0];
    model->data.options.bw_margin[1] = (int)p_double[1];
    mexPrintf("model->data.options.bw_margin = [%d, %d]\n",
            model->data.options.bw_margin[0], model->data.options.bw_margin[1]);
    // model->W ---------------------------------------------------------------
    // get model->W from mat file
    mexPrintf("Loading field model->W:\n");
    field_ptr = mxGetField(prhs[0], 0, "W");
    dims = mxGetDimensions(field_ptr);
    model->W_ROWS = dims[0]; model->W_COLS = dims[1];
    mexPrintf("model->W = [%d x %d]\n", model->W_ROWS, model->W_COLS);
    p_double = (double*)mxGetPr(field_ptr);
    model->W = (double*)malloc(model->W_ROWS * sizeof(double));
    for (int i = 0; i < model->W_ROWS; ++i)
    {
        model->W[i] = p_double[i];
    }
    // model->data.mapTable ----------------------------------------------------
    mexPrintf("Loading field model->data.mapTable:\n");
    field_ptr = mxGetField(field_data_ptr, 0, "mapTable");
    dims = mxGetDimensions(field_ptr);
    mexPrintf("mapTable = [%d x %d]\n", dims[0], dims[1]);
    mexPrintf(" = %d\n", dims[0]*dims[1]);
    if (dims[0]*dims[1] != model->data.options.M*4)
    {
        mexErrMsgTxt("Error. Possibly corrupted file.\n");
    }
    model->data.mapTable = (int*)calloc(M*4, sizeof(int));
    p_double = (double*)mxGetPr(field_ptr);
    mexPrintf("model->data.mapTable: \n");
    for (int i = 0; i < model->data.options.M*4; ++i)
    {
        model->data.mapTable[i] = (int)p_double[i];
        mexPrintf(" %d", model->data.mapTable[i]);
    }
    mexPrintf("\n");

    // model->data.lbp ---------------------------------------------------------
    mexPrintf("Loading field model->data.lbp:\n");
    field_ptr = mxGetField(field_data_ptr, 0, "lbp");
    dims = mxGetDimensions(field_ptr);
    mexPrintf("lbp = [%d x %d]\n", dims[0], dims[1]);
    model->data.lbp = (FLANDMARK_LBP*)malloc(M*sizeof(FLANDMARK_LBP));
    for (int idx = 0; idx < model->data.options.M; ++idx)
    {
        // get pointer to cell lbp{idx}
        cell_ptr = mxGetCell(field_ptr, idx);
        // get lbp{idx}.winSize
        tmp_field_ptr = mxGetField(cell_ptr, 0, "winSize");
        tmp_dims = mxGetDimensions(tmp_field_ptr);
        mexPrintf("lbp[%d].winSize = [%d x %d]", idx, tmp_dims[0], tmp_dims[1]);
        p_double = (double*)mxGetPr(tmp_field_ptr);
        for (int i = 0; i < 2; ++i)
        {
            model->data.lbp[idx].winSize[i] = (int)p_double[i];
            mexPrintf(" %d", model->data.lbp[idx].winSize[i]);
        }
        mexPrintf("\n");

        // get lbp{idx}.hop
        model->data.lbp[idx].hop = 4;

        // get lbp{idx}.wins
        tmp_field_ptr = mxGetField(cell_ptr, 0, "wins");
        tmp_dims = mxGetDimensions(tmp_field_ptr);
        model->data.lbp[idx].WINS_ROWS = tmp_dims[0]; model->data.lbp[idx].WINS_COLS = tmp_dims[1];
        mexPrintf("lbp[%d].wins = [%d x %d]\n", idx, model->data.lbp[idx].WINS_ROWS, model->data.lbp[idx].WINS_COLS);
        p_uint32 = (uint32_t*)mxGetPr(tmp_field_ptr);
        tsize = model->data.lbp[idx].WINS_ROWS * model->data.lbp[idx].WINS_COLS;
        model->data.lbp[idx].wins = (uint32_t*)malloc(tsize * sizeof(uint32_t));
        for (int i = 0; i < tsize; ++i)
        {
            model->data.lbp[idx].wins[i] = p_uint32[i];
        }
    }

    // model->data.options.S ---------------------------------------------------
    mexPrintf("Loading field model->data.options.S:\n");
    //field_data_ptr = mxGetField(prhs[0], 0, "data");
    field_ptr = mxGetField(field_data_ptr, 0, "options");
    tmp_field_ptr = mxGetField(field_ptr, 0, "S");
    dims = mxGetDimensions(tmp_field_ptr);
    mexPrintf("options.S = [%d x %d]\n", dims[0], dims[1]);
    model->data.options.S = (int*)calloc(4*M, sizeof(int));
    if (dims[0]*dims[1] != 4*model->data.options.M)
    {
        mexErrMsgTxt("Error. Possibly corrupted file.\n");
    }
    p_double = (double*)mxGetPr(tmp_field_ptr);
    for (int i = 0; i < 4*model->data.options.M; ++i)
    {
        model->data.options.S[i] = (int)p_double[i];
        mexPrintf(" %d", model->data.options.S[i]);
    }
    mexPrintf("\n");

    // model->data.options.PsiG ------------------------------------------------
    mexPrintf("Loading field model->data.options.PsiG:\n");
    field_ptr = mxGetField(field_data_ptr, 0, "options");

    FLANDMARK_PSIG * PsiGi = NULL;
    char psig_id[7] = "PsiGS#";

    for (int psig_idx = 0; psig_idx < 3; ++psig_idx)
    {
        mexPrintf("PsiGS%d:\n", psig_idx);

        switch (psig_idx)
        {
            case 0:
                //PsiGi = model->data.options.PsiGS0;
                tmp_field_ptr = mxGetField(field_ptr, 0, "PsiGS0");
                psig_id[5] = '0';
                break;
            case 1:
                //PsiGi = model->data.options.PsiGS1;
                tmp_field_ptr = mxGetField(field_ptr, 0, "PsiGS1");
                psig_id[5] = '1';
                break;
            case 2:
                //PsiGi = model->data.options.PsiGS2;
                tmp_field_ptr = mxGetField(field_ptr, 0, "PsiGS2");
                psig_id[5] = '2';
                break;
        }

        if (tmp_field_ptr == NULL)
        {
            mexErrMsgTxt("Looks like you are trying to load a model using gtab version of deformation cost.\n"
                    "We now support only loading models with gdisp deformation cost.\n"
                    "\n"
                 );
        }
        dims = mxGetDimensions(tmp_field_ptr);
        tsize = dims[0]*dims[1];
        model->data.options.PSIG_ROWS[psig_idx] = dims[0]; model->data.options.PSIG_COLS[psig_idx] = dims[1];

        mexPrintf("options.%s = [%d x %d]\n", psig_id, model->data.options.PSIG_ROWS[psig_idx], model->data.options.PSIG_COLS[psig_idx]);

        switch (psig_idx)
        {
            case 0:
                model->data.options.PsiGS0 = (FLANDMARK_PSIG*)malloc(tsize*sizeof(FLANDMARK_PSIG));
                PsiGi = model->data.options.PsiGS0;
                break;
            case 1:
                model->data.options.PsiGS1 = (FLANDMARK_PSIG*)malloc(tsize*sizeof(FLANDMARK_PSIG));
                PsiGi = model->data.options.PsiGS1;
                break;
            case 2:
                model->data.options.PsiGS2 = (FLANDMARK_PSIG*)malloc(tsize*sizeof(FLANDMARK_PSIG));
                PsiGi = model->data.options.PsiGS2;
                break;
        }

        for (int idx = 0; idx < tsize; ++idx)
        {
            cell_ptr = mxGetCell(tmp_field_ptr, idx);
            tmp_dims = mxGetDimensions(cell_ptr);
            tmp_tsize = tmp_dims[0]*tmp_dims[1];
            PsiGi[idx].ROWS = tmp_dims[0]; PsiGi[idx].COLS = tmp_dims[1];
            PsiGi[idx].disp = (int*)mxGetPr(cell_ptr);
        }
    }

    model->bb = 0;
    model->sf = 0;
    model->normalizedImageFrame = 0;

    mexPrintf("Structure model loaded.\n");

    // write model
    mexPrintf("\n\n");
    mexPrintf("Calling flandmark_writeModel...\n");
    flandmark_write_model(fname, model);
    mexPrintf("Write model done.\n");

    // read model
    mexPrintf("Calling flandmark_init...\n");
    FLANDMARK_Model * tst = flandmark_init(fname);
    mexPrintf("Read model done.\n");

    // chceck model
    mexPrintf("Calling flandmark_checkModel... ");
    retval = flandmark_check_model(model, tst);
    switch (retval)
    {
        case NO_ERR:
            mexPrintf("all done.\n");
        break;
        case ERROR_M:
            mexErrMsgTxt("check model->data.options.M not passed.\n");
        break;
        case ERROR_BW:
            mexErrMsgTxt("check model->data.options.bw not passed.\n");
        break;
        case ERROR_BW_MARGIN:
            mexErrMsgTxt("check model->data.options.bw_margin not passed.\n");
        break;

        case ERROR_W:
            mexErrMsgTxt("check model->w not passed.\n");
        break;
        case ERROR_DATA_IMAGES:
            mexErrMsgTxt("check model->data.Images not passed.\n");
        break;
        case ERROR_DATA_MAPTABLE:
            mexErrMsgTxt("check model->data.mapTable not passed.\n");
        break;

        case ERROR_DATA_LBP:
            mexErrMsgTxt("check model->data.lbp not passed.\n");
        break;
        case ERROR_DATA_OPTIONS_S:
            mexErrMsgTxt("check model->data.options.S not passed.\n");
        break;
        case ERROR_DATA_OPTIONS_PSIG:
            mexErrMsgTxt("check model->data.options.PsiG not passed.\n");
        break;

        default:
            mexErrMsgTxt("Unknown error.\n");
        break;
    }

    // cleanup
    mexPrintf("Cleanup...");
    flandmark_free(model);
    flandmark_free(tst);
    mexPrintf(" done.\n");
}