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 ファイルのニュアンスの 1 つに気付きました! それは私も前に手に入れました。mex 関数の配列は、行順ではなく列順で格納されるため、次のようになります。

ただし、Matlab のように列優先のインデックスを引き続き使用します。

ブログの URL

注文の素敵な写真については、こちらのページもお試しください。

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ます (代わりに 1 つの for ループ)。

于 2013-06-15T14:43:03.347 に答える