如何从 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
。
您确定您的imageRGB
是float
类型吗? 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 文件访问存储在元胞数组中的矩阵