3

我有一个有趣的问题。也就是这样;我正在尝试通过 mex 函数在内部使用 std::memcpy 函数,并像这样在 MATLAB 中调用该 mex 函数;

I2 = b_filter(I);

当我复制整个图像时,效果很好;

plhs[0] =  mxCreateDoubleMatrix(mxGetM(plhs[0]), mxGetN(plhs[0]), mxREAL);          
memcpy(mxGetPr(plhs[0]), mxGetPr(prhs[0]), sizeof(double) *mxGetM(plhs[0]) * mxGetN(plhs[0]));

但是当我尝试复制图像的某些部分时

plhs[0] =  mxCreateDoubleMatrix(100, 100, mxREAL);              
memcpy(mxGetPr(plhs[0]), mxGetPr(prhs[0]), sizeof(double) * 100 * 100);

它没有给出正确的图像部分,而是给出了无意义的像素值。

那么这里发生了什么?

4

2 回答 2

5

哈哈!您已经被最讨厌的 mex 文件细微差别之一抓住了!我以前也有过。mex 函数中的数组按列顺序而不是行顺序存储,因此您:

不过,您仍然像在 Matlab 中那样使用列优先索引

博客网址

也可以试试这个页面来获得一张漂亮的订购照片。

来自 Mathworks 的图

最后,我建议阅读此线程,以更好地了解 C 和 MATLAB 矩阵内存按列排序的区别。

于 2013-06-14T17:25:46.263 回答
3

正如@macduff 所解释的,MATLAB 使用列优先顺序来存储数组,而 C 数组是行优先顺序。

这是一个示例实现,展示了如何复制矩阵的一部分。

matrix_slice_mex.c

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *in, *out;
    mwIndex i,j;
    mwSize numRows;

    /* input checks */
    if (nrhs != 1 || nlhs > 1) {
        mexErrMsgIdAndTxt("MATLAB:nargchk", "Wrong number of arguments.");
    }
    if (mxGetNumberOfDimensions(prhs[0])>2 || !mxIsDouble(prhs[0])) {
        mexErrMsgIdAndTxt("MATLAB:wrongDims", "Expecting 2D double matrix.");
    }
    if (mxGetM(prhs[0])<100 || mxGetN(prhs[0])<100) {
        mexErrMsgIdAndTxt("MATLAB:wrongDims", "Matrix size must be >= 100x100.");
    }

    /* extract sub-matrix */
    plhs[0] = mxCreateDoubleMatrix(100, 100, mxREAL);
    out = mxGetPr(plhs[0]);
    in = mxGetPr(prhs[0]);
    numRows = mxGetM(prhs[0]);
    for(j=0; j<100; j++) {
        for(i=0; i<100; i++) {
            *out++ = in[i + numRows*j];
        }
    }
}

并对此进行测试:

x = rand(1000);
y = x(1:100,1:100);
yy = matrix_slice_mex(x);
isequal(y,yy)

您也可以用来memcpy复制每一列(一个 for 循环代替)

于 2013-06-15T14:43:03.347 回答