2014-11-22 24 views
1

我正在写一个调用conv2函数的mex文件。这mex文件将得到一个大小为(M, N)的图像,并使用conv2多次应用卷积。将mxArray传递给mexCallMatlab失败

#include "mex.h" 

void myconv(mxArray *Ain, mxArray *Kernel, mxArray *&Aout) 
{ 

    mxArray *rhs[3]; 

    rhs[0] = mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxREAL); 
    rhs[1] = mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxREAL); 
    rhs[2] = mxCreateString  ("same"); 

    double *ainPtr = mxGetPr(Ain ); 
    mxSetPr(rhs[0], ainPtr  ); 
    mxSetM (rhs[0], mxGetM(Ain) ); 
    mxSetN (rhs[0], mxGetM(Ain) ); 

    double *kernelPtr = mxGetPr(Kernel); 
    mxSetPr(rhs[1], kernelPtr   ); 
    mxSetM (rhs[1], mxGetM(Kernel) ); 
    mxSetN (rhs[1], mxGetN(Kernel) ); 

    mexCallMATLAB(1, &Aout, 3, rhs, "conv2"); 

    mxSetPr(rhs[0], NULL); 
    mxSetPr(rhs[1], NULL); 

} 

void myconv_combine(mxArray *Ain, mxArray *&Aout) 
{ 

    mxArray *mask = mxCreateDoubleMatrix(1, 5, mxREAL); 

    double *maskPtr = mxGetPr(mask); 
    maskPtr[0] = 0.05; 
    maskPtr[1] = 0.25; 
    maskPtr[2] = 0.4; 
    maskPtr[3] = 0.25; 
    maskPtr[4] = 0.05; 

    mxArray *maskTranspose = mxCreateDoubleMatrix(0, 0, mxREAL); 
    mxSetPr(maskTranspose, maskPtr  ); 
    mxSetM (maskTranspose, mxGetN(mask)); 
    mxSetN (maskTranspose, mxGetM(mask)); 

    mxArray *AinConvolved = mxCreateDoubleMatrix((mwSize)mxGetM(Ain), (mwSize)mxGetN(Ain), mxREAL); 
    double *AinConvolvedPtr = mxGetPr(AinConvolved); 
    myconv(Ain, mask, AinConvolved); 

    // Some modifications. 
    mxArray *Temp = mxCreateDoubleMatrix((mwSize)mxGetM(Ain), (mwSize)mxGetN(Ain), mxREAL); 
    double *TempPtr = mxGetPr(Temp); 
    for(int i = 0; i < (mwSize)mxGetM(Ain)*(mwSize)mxGetN(Ain); i++) 
      TempPtr[ i ] = 2.0*AinConvolvedPtr[ i ]; 

    // Some other convolution. 
    mxArray *TempConvolved = mxCreateDoubleMatrix((mwSize)mxGetM(Ain), (mwSize)mxGetN(Ain), mxREAL); 
    double *TempConvolvedPtr = mxGetPr(TempConvolved); 
    myconv(Temp, maskTranspose, TempConvolved); 

    // Some other modifications. 
    double *AoutPtr = mxGetPr(Aout); 
    for(int i = 0; i < (mwSize)mxGetM(Ain)*(mwSize)mxGetN(Ain); i++) 
      AoutPtr[ i ] = 2.0*TempConvolvedPtr[ i ]; 


} 


void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{ 

    mxArray *Ain = mxCreateDoubleMatrix(100, 100, mxREAL); 
    mxArray *Aout = mxCreateDoubleMatrix(100, 100, mxREAL); 

    myconv_combine(Ain, Aout); 


} 

在我的实际代码,当它到达行:我不知道为什么发生这种情况,不幸的是我不能重复在我提供的示例代码相同的错误

myconv(Temp, maskTranspose, TempConvolved); 

MATLAB崩溃以上。在我的实际代码,图像是由行成功卷积:

myconv(Ain, mask, AinConvolved); 

但是,只要它想申请第二卷积:

myconv(Temp, maskTranspose, TempConvolved); 

它崩溃,当我调试它,它发生当mexCallMATLAB被调用时myconv函数。 Temp/TempConvolvedAin/AinConvolved之间的区别是什么使得前一次崩溃的时间为mexCallMATLAB

有人能帮我解决这个问题吗?

回答

1

重用数据缓冲器

mxArray *mask重用数据指针mxArray *maskTransposed是要求麻烦,如MATLAB具有用于引用计数严格机制共享数据数组是MATLAB的内存优化的重要组成部分。相反,重复整个事情与mxDuplicateArray

mxArray *maskTranspose = mxDuplicateArray(mask); 

有一个无证mxCreateSharedDataCopy模仿MATLAB的懒惰复制机制,但这是一个5个元素的数组真的矫枉过正。

多余到问题mxArray初始化之前mexCallMATLAB

另外,不要打扰调用mexCallMATLAB之前初始化mxArray *AinConvolved。只需传递一个NULL指针,它就会为你创建它。如果你不这样做,它会擦除​​旧的(发送到垃圾回收)并为conv2的输出创建一个新的。这让我想起这表明这是怎么在你的代码中的问题:

mxArray *AinConvolved = mxCreateDoubleMatrix(mxGetM(Ain), mxGetN(Ain), mxREAL); 
double *AinConvolvedPtr0 = mxGetPr(AinConvolved); 
myconv(Ain, mask, AinConvolved); 
double *AinConvolvedPtr = mxGetPr(AinConvolved); 
mexPrintf("%p\n%p\n", AinConvolvedPtr0, AinConvolvedPtr); 

输出在MATLAB:

00000000B852FA20 
0000000026B8EB00 

正如你所看到的,如果您尝试使用您在使用前用mxGetPr得到了指针mexCallMATLAB,你可能使用了错误的数据,可能已经释放了内存。

imfilter

而且自动分离滤波,请注意,如果你有imfilter,你并不需要实现可分离卷积,因为它内置了该功能。就在imfilter.m看看,并注意isSeparable功能。请参阅here for more information

试试看,我会发布测试。

+0

我改变了我的代码,并使用了'mxArray * AinConvolved = NULL;'和'mxArray * TempConvolved = NULL;'。我也尝试过'myconv(Temp,mask,TempConvolved);'以消除引起引用计数的可能性,并使用'mask'而不是'maskTranspose'。但是,它仍然不起作用,问题发生在与以前相同的地方,无法计算“TempConvolved”。 – AFP 2014-11-22 06:01:16

+1

@ A2009在调用“mexCallMATLAB”后,如何放置'mxGetPr(AinConvolved)'和'mxGetPr(TempConvolved)'?是否有任何代码可以复制,您可以在gist.github.com上发布大量代码? – chappjc 2014-11-22 06:21:44

+0

让我看看如何重现错误的部分以更好地阐明问题。我感谢您的帮助。 – AFP 2014-11-22 06:52:16

相关问题