У меня есть интересная проблема. А именно так; Я пытаюсь использовать функцию 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);
это не дает правильную часть изображения, но дает неоправданные значения пикселей.
и так, что здесь происходит?
Ха Ха! Вы попали в один из самых неприятных нюансов mex-файла! Это до меня тоже дошло. Массивы в мекс-функциях хранятся в порядке столбцов, а не строк, поэтому вы:
Вы по-прежнему используете индексирование по столбцам, как в Matlab, хотя
Попробуй это страница тоже за красивую картину заказа.
Наконец, я бы порекомендовал прочитать эта тема чтобы лучше понять разницу между матричной памятью C и MATLAB, упорядоченной по столбцам.
Как объясняет @macduff, MATLAB использует основной порядок столбца хранить массивы, в то время как массивы 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)