How to return a matrix structure from a mex function?

对着背影说爱祢 提交于 2019-12-10 12:14:19

问题


I have a struct that defines a 3d array, the size is known:

struct uchar3
{
  unsigned char x, y, z;
};

and I want to return it via mex function in order to use it in matlab like a three dimensional array, like an image. How can this be done?

EDIT:

This is apart of the function I use.

foo(uchar3 **imagePtr, Mat Im){
unsigned char *cvPtr = Im.ptr<unsigned char>(0);
    for (size_t i = 0; i < Im.rows * Im.cols; ++i) {
        (*imagePtr)[i].x = cvPtr[3 * i + 0];
        (*imagePtr)[i].y = cvPtr[3 * i + 1];
        (*imagePtr)[i].z = cvPtr[3 * i + 2];
    }
}

Shai's code:

cv::Mat imageRGB;
    cv::cvtColor(OutPutMat, imageRGB, CV_BGR2RGB);

    // uc3 is populated here 
    mwSize sz[3];
    sz[0] = imageRGB.rows; // matlab is row first
    sz[1] = imageRGB.cols;
    sz[2] = 3;
    plhs[0] = mxCreateNumericArray( 3, sz, mxDOUBLE_CLASS, // create double array, you can change the type here
        mxREAL ); // create real matrix
    float *cvPtr = imageRGB.ptr<float>(0);
    float* p = (float*)mxGetData(plhs[0]); // get a pointer to actual data
    for ( size_t y = 0 ; y < imageRGB.rows ; y++ ) {
        for ( size_t x = 0; x < imageRGB.cols ; x++ ) {
            int i = y * imageRGB.cols + x; // opencv is col first
            p[ x * imageRGB.rows + y ] = cvPtr[3 * i + 0];
            p[ imageRGB.cols * imageRGB.rows + x * imageRGB.rows + y ] = cvPtr[3 * i + 1];
            p[ 2*imageRGB.cols * imageRGB.rows + x * imageRGB.rows + y ] = cvPtr[3 * i + 2];
        }
    }

回答1:


You need to use mxCreateNumericArray

uchar3 uc3;  
// uc3 is populated here 
mwSize sz[3];
sz[0] = Im.rows; // matlab is row first
sz[1] = Im.cols;
sz[2] = 3;
mxArray* pOut = mxCreateNumericArray( 3, sz, mxDOUBLE_CLASS // create double array, you can change the type here
                                      mxREAL ); // create real matrix
double* p = (double*)mxGetData(pOut); // get a pointer to actual data
for ( size_t y = 0 ; y < Im.rows ; y++ ) {
    for ( size_t x = 0; x < Im.cols ; x++ ) {
        int i = y * Im.cols + x; // opencv is col first
        p[ x * Im.rows + y ] = cvPtr[3 * i + 0];
        p[ Im.cols*Im.rows + x * Im.rows + y ] = cvPtr[3 * i + 1];
        p[ 2*Im.cols*Im.rows + x * Im.rows + y ] = cvPtr[3 * i + 2];
    }
}
// set one of your mexFunction's outputs to pOut



回答2:


Into your mex function do this :

plhs[0] = valueStruct(Test,Test2);

Where ValueStruct is a function

mxArray* valueStruct(const double& d,const double& d2)
{
    mxArray* p = mxCreateStructMatrix(1,1,2,_fieldnames);

    if (!p)
        mexErrMsgIdAndTxt("error","Allocation error");

    mxSetField(p,0,"d",mxArray(d));
    mxSetField(p,0,"d2",mxArray(d2));
    return p;
}

You can refer to mxCreateStructMatrix documentation for more informations.

And for mxSetField.

For an example, You can refer to mexopencv that create struct with his mxArray class where you can get here.



来源:https://stackoverflow.com/questions/20402887/how-to-return-a-matrix-structure-from-a-mex-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!