Prev: Fourier Transform (fft)
Next: fft on matlab
From: Michael on 27 Apr 2010 04:17 Ok, funnily the "size_t / mwSize" warning has disappeared, though I haven't changed anything in between... Ok, here's what I want to do: For each image pixel, I want to examine 9 neighborhoods, each of which made up of 9 pixels. In the code fragment I postet earlier, the first neighborhood is shown (stored in ppix[]). For each of the 9 neighborhoods of one image pixel I need to calculate mean, median and variance. As stated before, I want to use the MATLAB functions mean, median and var. The 3 resulting values of each of the 9 neighborhoods shall be stored in three new arrays themselves. One for the 9 mean values, one for the 9 median values, one for the 9 variance values. When that is done, I want to find the neighborhood with the smallest variance using the MATLAB function min. Then I want to give the median value of the neighborhood with the smallest variance to the accordant center pixel. In the end, I have one single output argument back to the MATLAB workspace, namely the smoothed image. And all that has to take place within the MEX-file with several mexCallMATLAB-calls as I have to use two nested for loops running across all rows and columns of an image of several thousand rows and cols...
From: Michael on 27 Apr 2010 10:12 No new ideas available? I've tried all day, but I'm beginning to feel desperate... The core problem I have is the interaction of mxArrays as used by MATLAB and the MEX-interface and the C arrays/pointers I need to use for calculations and decisions within the C/MEX code. It's especially all the pointers, array of pointers, pointers to arrays etc. thing that gets me confused. To make it clear (while the questions posted in my last message are still waiting to be answered!): 1) How can I grab values from the input data (prhs[0])? For the moment I declare a float* variable named image_in which I point to prhs[0] using image_in = mxGetData(prhs[0]); Then I adress the elements of my input image using image_in[blablabla] Is that correct? Or should I rather declare image_in an array? 2) How can I make data extracted from the input data (image_in) and stored in a seperate float array to an mxArray, so that it can be passed to MATLAB using mexCallMATLAB? 3) How should I declare the output variable of that mexCallMATLAB call? I guess it should also be mxArray*? 4) How can I extract the data from that mxArray to a standard C variable, pointer or array so that I can use it with standard C functionality (plus, minus, if..else, etc.)? I hope you all can follow my problem. Help is highly appreciated!!
From: James Tursa on 27 Apr 2010 11:26 "Michael " <michael.schmittNOSPAM(a)bv.tum.de> wrote in message <hr6rbk$47p$1(a)fred.mathworks.com>... > > No new ideas available? I've tried all day, but I'm beginning to feel desperate... Sorry for the delay ... but I do have to sleep sometime :) > The core problem I have is the interaction of mxArrays as used by MATLAB and the MEX-interface and the C arrays/pointers I need to use for calculations and decisions within the C/MEX code. It's especially all the pointers, array of pointers, pointers to arrays etc. thing that gets me confused. Here is a short example. This mex routine simply takes a single class 2D array as input and returns a variable of the same size where each element has been replaced with the median of the surrounding 9-pixel block. This doesn't do your particular problem, but it can serve as a starting point in the use of data pointers and the use of mexCallMATLAB. Hopefully this will answer your basic questions on how to access the data of an mxArray and how to use mexCallMATLAB properly. James Tursa -------------------------------------------------------------------------------------------- // Input: single class 2D array // Output: single class 2D array same size as input with // values that are the median of the 9-pixel block #include "mex.h" #define R(i) ((i)<0?0:((i)>M-1?(M-1):(i))) #define C(j) ((j)<0?0:((j)>N-1?(N-1):(j))) #define A(i,j) a[C(j)*M+R(i)] #define B(i,j) b[C(j)*M+R(i)] void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize i, j, M, N; float *a, *b, *x, *y; mxArray *rhs[1], *lhs[1]; a = mxGetData(prhs[0]); M = mxGetM(prhs[0]); N = mxGetN(prhs[0]); plhs[0] = mxDuplicateArray(prhs[0]); b = mxGetData(plhs[0]); rhs[0] = mxCreateNumericMatrix(1, 9, mxSINGLE_CLASS, mxREAL); x = mxGetData(rhs[0]); for( j=0; j<N; j++ ) { for( i=0; i<M; i++ ) { x[0] = A(i-1,j-1); x[1] = A(i ,j-1); x[2] = A(i+1,j-1); x[3] = A(i-1,j ); x[4] = A(i ,j ); x[5] = A(i+1,j ); x[6] = A(i-1,j+1); x[7] = A(i ,j+1); x[8] = A(i+1,j+1); mexCallMATLAB(1, lhs, 1, rhs, "median"); y = mxGetData(lhs[0]); B(i,j) = *y; mxDestroyArray(lhs[0]); } } mxDestroyArray(rhs[0]); }
From: Michael on 28 Apr 2010 04:30
Sleep is way overrated. ;) Just joking, you're help is very appreciated, thank you very much for your efforts! Your code helped me understanding the concept of MATLAB and C interaction better, nevertheless I have to admit I still haven't really realized how to make the lhs mxArray an array of results itself. Here's what I've made out of your code in the meantime. The comment shows what I want to do: // Input: single class 2D array // Output: single class 2D array same size as input #include "mex.h" #define PHASE_IN(i,j) phase_in[j*rows+i] #define PHASE_OUT(i,j) phase_out[j*rows+i] void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize i, j, rows, cols; float *phase_in, *phase_out, *nbhood, *median, *variance; mxArray *mxNbhood[1], *mxMedian[1], *mxVariance[1]; phase_in = mxGetData(prhs[0]); rows = mxGetM(prhs[0]); cols = mxGetN(prhs[0]); plhs[0] = mxDuplicateArray(prhs[0]); phase_out = mxGetData(plhs[0]); mxNbhood[0] = mxCreateNumericMatrix(1, 9, mxSINGLE_CLASS, mxREAL); nbhood = mxGetData(mxNbhood[0]); // The following block might be wrong. In MATLAB I would store the 9 medians // and the 9 according variances in 9-element vectors. This is what I'm trying // to do here as well mxMedian[0] = mxCreateNumericMatrix(1, 9, mxSINGLE_CLASS, mxREAL); median = mxGetData(mxMedian[0]); mxVariance[0] = mxCreateNumericArray(1, 9, mxSINGLE_CLASS, mxREAL); variance = mxGetData(mxVariance[0]); for(j = 2; j < cols-3; j++) { for(i = 2; i < rows; i++) { nbhood[0] = PHASE_IN(i-1,j-1); nbhood[1] = PHASE_IN(i,j-1); nbhood[2] = PHASE_IN(i+1,j-1); nbhood[3] = PHASE_IN(i-1,j); nbhood[4] = PHASE_IN(i,j); nbhood[5] = PHASE_IN(i+1,j); nbhood[6] = PHASE_IN(i-1,j+1); nbhood[7] = PHASE_IN(i,j+1); nbhood[8] = PHASE_IN(i+1,j+1); // How do I access the first vector element? (And later the 2nd, 3rd...9th?) mexCallMATLAB(1, mxMedian, 1, mxNbhood, "median"); mexCallMATLAB(1, mxVariance, 1, mxNbhood, "var"); // Now the same procedure for 8 other neighborhoods -> to be completed // here the median of the neighborhood with lowest variance should be chosen // PHASE_OUT(i,j) = ???; } } mxDestroyArray(mxMedian[0]); mxDestroyArray(mxNbhood[0]); } Then I wonder if, when and how I have to delete - the neighborhood array, which is used 9 times in one single loop step - the median and variance arrays (also containing 9 elements), which are used once per loop step? |