вызов функции memcpy внутри mex

У меня есть интересная проблема. А именно так; Я пытаюсь использовать функцию std :: memcpy внутри функции mex и вызываю эту функцию mex внутри MATLAB вот так;

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);

это не дает правильную часть изображения, но дает неоправданные значения пикселей.

и так, что здесь происходит?

3

Решение

Ха Ха! Вы попали в один из самых неприятных нюансов mex-файла! Это до меня тоже дошло. Массивы в мекс-функциях хранятся в порядке столбцов, а не строк, поэтому вы:

Вы по-прежнему используете индексирование по столбцам, как в Matlab, хотя

URL блога

Попробуй это страница тоже за красивую картину заказа.

Рисунок из Mathworks

Наконец, я бы порекомендовал прочитать эта тема чтобы лучше понять разницу между матричной памятью C и MATLAB, упорядоченной по столбцам.

5

Другие решения

Как объясняет @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)

3

По вопросам рекламы [email protected]