如何从mex函数返回矩阵结构?

时间:2013-12-05 14:41:17

标签: c++ c opencv mex

我有一个定义3d数组的结构,大小已知:

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

我希望通过mex函数返回它,以便在matlab中像三维数组一样使用它,就像图像一样。怎么办呢?

修改

这是我使用的功能的一部分。

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的代码:

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];
        }
    }

2 个答案:

答案 0 :(得分:1)

您需要使用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

答案 1 :(得分:0)

进入你的mex函数执行此操作:

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

ValueStruct是一个函数

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;
}

您可以参考mxCreateStructMatrix文档了解更多信息。

对于mxSetField

例如,你可以参考mexopencv,用他的mxArray类创建struct,你可以获得here