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

Posted

技术标签:

【中文标题】如何从 mex 函数返回矩阵结构?【英文标题】:How to return a matrix structure from a mex function? 【发布时间】:2013-12-05 14:41:16 【问题描述】:

我有一个定义 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];
        
    

【问题讨论】:

如果创建mxDOUBLE_CLASS 类型的数组,那么指向其内容p 的指针必须是double 类型,而不是float。如果你想要float,请使用mxSINGLE_CLASS 您确定您的imageRGBfloat 类型吗? cvPtr 的类型有可能是 unsigned char 吗? 颜色变换修改后cv::cvtColor(OutPutMat, imageRGB, CV_BGR2RGB, CV_32F );it steel crashs. 不应该是CV_32F3C吗? 我猜你必须调试你的墨西哥......祝你好运。看这里mathworks.com/help/matlab/matlab_external/… 【参考方案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

【讨论】:

我的uc3是3维数组,RGB图,能指点一下吗? @darkmoor 如果uc3 只有三个标量字段,它如何存储 RGB 图像数据?你有uc3 的数组吗?有多大? 对不起,我不清楚。在编辑 imagePtr 是我想要返回的。 我添加了我使用的确切内容,但它崩溃了。解决后我会删除它。【参考方案2】:

在你的 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 类创建结构,您可以在其中获得here。

【讨论】:

以上是关于如何从 mex 函数返回矩阵结构?的主要内容,如果未能解决你的问题,请参考以下文章

如何逐行读取 Matlab mex 函数的输入矩阵?

创建一个可以返回对角矩阵的 C++ mex 函数

如何访问传递给 MEX 函数的矩阵成员?

在 MATLAB 中使用 MEX 文件访问存储在元胞数组中的矩阵

如何查看从 Matlab 中 Mex 函数使用的 DLL 调用的 printf 的输出?

如何从函数返回矩阵(二维数组)? (C)