【问题标题】:memcpy function calling inside mexmemcpy 函数在 mex 中调用
【发布时间】:2013-06-14 17:15:49
【问题描述】:

我有一个有趣的问题。也就是这样;我正在尝试通过 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);

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

那么这里发生了什么?

【问题讨论】:

    标签: c++ matlab mex memcpy matrix-indexing


    【解决方案1】:

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

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

    Blog URL

    也可以试试这个page 以获得漂亮的订购照片。

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

    【讨论】:

    • 我去看看!干杯!
    • 不仅有排序问题,而且memcpy 会产生和reshape 一样的效果。它肯定不会像 MATLAB 切片运算符那样工作,这似乎是 OP 想要的。
    【解决方案2】:

    正如@macduff 所解释的,MATLAB 使用column-major order 来存储数组,而 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 循环代替)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多