2014-11-22 3 views
1

conv2 함수가 호출 된 mex 파일을 작성하고 있습니다. 이 mex 파일은 (M, N) 크기의 이미지를 가져오고 conv2을 사용하여 여러 번 회선을 적용합니다. 이런 불행하게도 내가 제공 한 예제 코드에서 같은 오류를 복제 할 수없는 이유를 나는 단서가 없다mexCallMatlab에 mxArray를 전달하지 못했습니다.

myconv(Temp, maskTranspose, TempConvolved); 

MATLAB 충돌 : 그것은 선에 도달 내 실제 코드에서

#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(Ain, mask, AinConvolved); 

그러나 즉시 두 번째 회선을 적용하고 싶어 같이

myconv(Temp, maskTranspose, TempConvolved); 

이 충돌하고 나는 그것을 디버깅 할 때, 그것은 발생 mexCallMATLAB이 호출되면 myconv 함수에 호출됩니다. Temp/TempConvolvedAin/AinConvolved의 차이점은 mexCallMATLAB 일 때 이전의 충돌을 어떻게 유발합니까?

친절하게도이 문제를 해결할 수 있습니까? 공유 데이터 배열은 MATLAB의 메모리 최적화의 중요한 부분으로 MATLAB은 참조 카운팅에 대한 엄격한 메커니즘이 같은 mxArray *maskTransposed에 대한 mxArray *mask에서 데이터 포인터를 재사용

답변

1

재사용 데이터 버퍼는

, 문제가 요구된다. 대신, mxDuplicateArray로 전체를 복제 :이 MATLAB의 게으른 복사 메커니즘을 에뮬레이트 문서화되지 않은 mxCreateSharedDataCopy이지만, 그 5 요소 배열 정말 잔인한

mxArray *maskTranspose = mxDuplicateArray(mask); 

.

불필요한 간 문제가 mxArray 초기화하기 전에 또한

mexCallMATLAB에, mexCallMATLAB를 호출하기 전에 mxArray *AinConvolved를 초기화 귀찮게하지 않습니다. 그냥 NULL 포인터를 전달하면 그것을 당신을 위해 만들 것입니다. 그렇지 않으면 오래된 것을 지 웁니다 (가비지 콜렉션으로 보내십시오). conv2의 결과를 위해 새 것을 작성하십시오. 어느 날 생각 나게이 코드에서 문제가 어떻게이 보여 MATLAB에서

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

출력 :

00000000B852FA20 
0000000026B8EB00 

당신이 볼 수 있듯이, 당신은 당신이 사용하기 전에 mxGetPr에있어 포인터를 사용하려고하면 mexCallMATLAB, 아마도 이미 잘못된 데이터를 사용하고 있습니다. 아마도 할당 해제 된 메모리 일 수 있습니다.또한 imfilter

자동 분리 필터링, 당신이 imfilter이있는 경우는 내장하는 기능을 가지고 있기 때문에, 당신은 분리 회선을 구현할 필요는 없습니다. 그냥 imfilter.m에 모습을 가지고 있고주의 isSeparable 기능. here for more information을 참조하십시오.

시험해 보겠습니다.

+0

코드를 변경하고'mxArray * AinConvolved = NULL;'및'mxArray * TempConvolved = NULL; '을 사용했습니다. 나는 또한'myconv (Temp, mask, TempConvolved);를 시도해 참조 카운팅의 가능성을 제거하고'maskTranspose' 대신'mask'를 사용했습니다. 그러나 여전히 작동하지 않으며 'TempConvolved'를 계산할 수없는 이전과 같은 장소에서 문제가 발생합니다. – AFP

+1

@ A2009'mexCallMATLAB'을 호출 한 후'mxGetPr (AinConvolved)'와'mxGetPr (TempConvolved) '를 어떻게 배치합니까? 많은 양의 코드를 gist.github.com에 게시 할 수있는 코드가 있습니까? – chappjc

+0

문제를보다 명확하게 설명하기 위해 오류 부분을 어떻게 재현 할 수 있는지 보겠습니다. 도와 주셔서 감사합니다. – AFP