我试图在mex中开发一个函数。该功能的目的应该是将窗口滑动到3D图像上并在窗口内应用一些功能。目前我被卡住了,因为当算法到达padarray
函数的调用时,MATLAB崩溃。
到目前为止,我编写了这些代码行
#include <iostream>
#include "mex.h"
#include "matrix.h"
using namespace std;
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
#define O_IMAGE plhs[0]
#define I_IMAGE prhs[0]
#define I_PADSIZE prhs[1]
#define I_FUN prhs[2]
#define I_OPTION prhs[3]
// Argument Checking:
if(nrhs < 1 || nrhs > 4) /* Check the number of arguments */
mexErrMsgTxt("Wrong number of input arguments.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
// Variable declarations
static const char padding[] = "symmetric";
const char *windowShape;
const mwSize *dim;
mwSize *dimPad;
mwSize ndim;
double *pad, *windowSize, *thetaStep, *phiStep;
mxArray *inputFun[4], *inputPadFun[3], *input_image, *imagePad, *output_image;
/*Get dimensions of input image*/
ndim = mxGetNumberOfDimensions(I_IMAGE);
dim = mxGetDimensions(I_IMAGE);
/* Create dimensions of padded image*/
dimPad = (mwSize *) mxCalloc(ndim, sizeof(mwSize));
dimPad = (mwSize *) memcpy((void *) dimPad,(void *) dim, ndim*sizeof(mwSize));
pad = mxGetPr(I_PADSIZE);
for (int i=0;i<ndim;++i)
{
dimPad[i] += 2*pad[i];
}
/*Get pointer to the input image*/
input_image = (mxArray *) mxGetData(I_IMAGE);
/* Create output image*/
O_IMAGE = mxCreateNumericArray(ndim, dim, mxDOUBLE_CLASS, mxREAL);
output_image = (mxArray *) mxGetData(O_IMAGE);
/* Create padded image*/
imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
// Padding input matrix
inputPadFun[0] = input_image;
inputPadFun[1] = (mxArray *)(pad);
inputPadFun[2] = (mxArray *)(padding);
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
// Clean UP
mxFree(dimPad);
mxDestroyArray(imagePad);
}
我在mexCallMATLAB
检查了输入和输出中图像的尺寸,看起来是正确的。我真的不明白我做错了什么。任何帮助是极大的赞赏!
答案 0 :(得分:3)
有几个有问题的演员。
由于pad
是double*
,你在这里做了一个荒谬的演员:
(mxArray *)(pad)
同样padding
是const char[]
,你不能做
(mxArray *)(padding)
在以下行中,mxGetData
向缓冲区返回void*
,其基础数据为基本类型(double
,single
,等),但你将它投射到mxArray*
:
(mxArray *) mxGetData(prhs[0]);
请记住,mxArray
是MathWorks定义的不透明对象类型,您必须使用它们的函数来创建这些对象。你也只能处理它们的指针。
还有其他问题......
<强>代码强>
以下是有关如何更改代码的C ++示例:
// padarray_BugsFree.cpp
#include <iostream>
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
if(nrhs != 2)
mexErrMsgTxt("Wrong number of input arguments:\n\t"
"Iout = padarray_BugsFree(I,pad)");
if(nlhs > 1)
mexErrMsgTxt("Too many output arguments:\n\t"
"Iout = padarray_BugsFree(I,pad)");
if(!(mxIsDouble(prhs[0]) && mxIsDouble(prhs[1])))
mexErrMsgTxt("Inputs must be double");
mwSize ndim = mxGetNumberOfDimensions(prhs[0]);
const mwSize *dim = mxGetDimensions(prhs[0]);
if (ndim != mxGetNumberOfElements(prhs[1]))
mexErrMsgTxt("pad must be equal to ndims(I)");
const double *pad = mxGetPr(prhs[1]);
mwSize *dimPad = (mwSize *) mxCalloc(ndim, sizeof(mwSize));
for (int i=0; i<ndim; ++i) {
dimPad[i] = dim[i] + 2*pad[i];
}
mxArray *imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
mxFree(dimPad);
// Padding input matrix
mxArray *padding = mxCreateString("symmetric");
mxArray *inputPadFun[3];
inputPadFun[0] = const_cast<mxArray*>(prhs[0]);
inputPadFun[1] = const_cast<mxArray*>(prhs[1]);
inputPadFun[2] = padding;
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
mxDestroyArray(padding);
// do something with the padded image and generate output
plhs[0] = mxDuplicateArray(imagePad); // in place of useful operations
mxDestroyArray(imagePad);
}
<强>演示强>
>> I = magic(3)
I =
8 1 6
3 5 7
4 9 2
>> pad = [2 2]
pad =
2 2
>> padarray_BugsFree
Error using padarray_BugsFree
Wrong number of input arguments:
Iout = padarray_BugsFree(I,pad)
>> Iout = padarray_BugsFree(I,pad)
Iout =
5 3 3 5 7 7 5
1 8 8 1 6 6 1
1 8 8 1 6 6 1
5 3 3 5 7 7 5
9 4 4 9 2 2 9
9 4 4 9 2 2 9
5 3 3 5 7 7 5
备注强>
使用以下帖子作为参考,了解如何使用mexCallMATLAB
:
您还可以按如下方式构建RHS输入数组:
mxArray *inputPadFun[] = {const_cast<mxArray*>(prhs[0]),
const_cast<mxArray*>(prhs[1]), padding};
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");