Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Interaction of MEX and MATLAB or mexCallMATLAB and Co.

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: Michael

Date: 26 Apr, 2010 15:09:10

Message: 1 of 9

I am currently implementing some image processing operation that needs to be framed by two nested for-loops running over all columns and rows of the image.

Due to the slowness of nested for-loops in MATLAB I decided to code this problem using the MEX interface. I do know how to set up a mexFunction and how to pass input and output arguments between MATLAB and the mexFunction.

During the loop, I examine certain neighborhoods around the pixel that's actually adressed by the loop variables. Basically, I want to store the values of the neighborhood pixels in a vector, so that I can calculate statistical stuff like mean, median and variance of the neighborhood. In the end, I want to compare the statistics of several possible neighborhoods to determine the new value of the center pixel.

Anyway. Due to the fact there exist no pre-implemented mean, median, variance etc. functions in C/C++, I want to use the corresponding MATLAB functions, which can be adressed by mexCallMATLAB from a mexFunction. Unfortunately I haven't figured out how to interchange information between MATLAB and MEX/C cleanly.

Here's some example code:
#include <math.h>
#include "mex.h"
#include "matrix.h"

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
int rows, cols;
float* image_in;
float* image_out;
float* ppix;
float* pmean;
mwSize ndim;
const mwSize *dims;
mxArray *pix;
mxArray *mean;

rows = (int)mxGetM(prhs[0]);
cols = (int)mxGetN(prhs[0]);

image_in = mxGetData(prhs[0]);

ndim = mxGetNumberOfDimensions(prhs[0]);
dims = mxGetDimensions(prhs[0]);

plhs[0] = mxCreateNumericArray(ndim, dims, mxSINGLE_CLASS, mxREAL);
image_out = mxGetData(plhs[0]);

pix = mxCreateNumericMatrix(9, 1, mxSINGLE_CLASS, mxREAL);
ppix = mxGetData(pix);

mean = mxCreateNumericMatrix(9, 1, mxSINGLE_CLASS, mxREAL);
pmean = mxGetData(pix);

for(j = 0; j < cols; j++) // loop over cols
{
for(i = 0; i < rows; i++) // loop over rows
{
ppix[0] = image_in[(rows*j-1)+i-1];
ppix[1] = image_in[(rows*j-1)+i];
ppix[2] = image_in[(rows*j-1)+i+1];
ppix[3] = image_in[(rows*j)+i-1];
ppix[4] = image_in[(rows*j)+i];
ppix[5] = image_in[(rows*j)+i+1];
ppix[6] = image_in[(rows*j+1)+i-1];
ppix[7] = image_in[(rows*j+1)+i];
ppix[8] = image_in[(rows*j+1)+i+1];

mexCallMATLAB(1, &mean, 1, &pix, "mean");
}
}
return;
}

I know this piece of code is incomplete, but I just wanted to show in what direction my problem goes. I want to calculate the variance and the median the same way I tried to calculate the mean. And I want to store the respective values in vectors/arrays with length according to the number of neighborhoods, e.g. 9.
Then I want to compare the values using MATLAB's built-in min and max functions.

Can anybody help unravel the snarl in my head coming from all those pointers, C arrays, MATLAB arrays etc. pp.?

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: James Tursa

Date: 26 Apr, 2010 16:54:04

Message: 2 of 9

"Michael " <michael.schmittNOSPAM@bv.tum.de> wrote in message <hr4aam$9n5$1@fred.mathworks.com>...
>
> Here's some example code:
> #include <math.h>
> #include "mex.h"
> #include "matrix.h"

FYI, you don't really need the #include "matrix.h" since that is already included in the mex.h file.

> int rows, cols;
        :
> rows = (int)mxGetM(prhs[0]);
> cols = (int)mxGetN(prhs[0]);

Why are you casting these results to int? Why not just declare rows and cols as mwSize and put the results of mxGetM and mxGetN into rows and cols directly without casting?

> mean = mxCreateNumericMatrix(9, 1, mxSINGLE_CLASS, mxREAL);
> pmean = mxGetData(pix);
        :
> mexCallMATLAB(1, &mean, 1, &pix, "mean");

"mean" is going to be an output of the mexCallMATLAB call, it is not going to be something you as a programmer create ahead of time. Delete the above two lines creating mean and getting its data pointer.

James Tursa

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: James Tursa

Date: 26 Apr, 2010 18:46:05

Message: 3 of 9

"Michael " <michael.schmittNOSPAM@bv.tum.de> wrote in message <hr4aam$9n5$1@fred.mathworks.com>...
>
> for(j = 0; j < cols; j++) // loop over cols
> {
> for(i = 0; i < rows; i++) // loop over rows
> {
> ppix[0] = image_in[(rows*j-1)+i-1];
> ppix[1] = image_in[(rows*j-1)+i];
> ppix[2] = image_in[(rows*j-1)+i+1];
> ppix[3] = image_in[(rows*j)+i-1];
> ppix[4] = image_in[(rows*j)+i];
> ppix[5] = image_in[(rows*j)+i+1];
> ppix[6] = image_in[(rows*j+1)+i-1];
> ppix[7] = image_in[(rows*j+1)+i];
> ppix[8] = image_in[(rows*j+1)+i+1];

Also, you are not doing your edge calculations correctly. e.g., for i==0 and j==0 you get the following:

ppix[0] = image_in[(rows*0-1)+0-1];

which works out to:

ppix[0] = image_in[-2];

which of course is going to access invalid memory. Similar comments apply for the other edges. So you need account for these edge cases in your code.

James Tursa

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: Michael

Date: 27 Apr, 2010 07:25:08

Message: 4 of 9

Thank you for your advice, James!

I know about the indexing error in the edge case, but for the moment I was more interested in the functionality of the MEX/MATLAB interaction.

If I am not supposed to create any mean vector in advance, how do I work with the output of "mexCallMATLAB(1, &mean, 1, &pix, "mean");" within the MEX file? And how can I give an array created from several such calls back to MATLAB? That's the core of my problem.

Concerning the mwSize topic: I tried to declare rows and cols as mwSize like you suggested, but my compiler (Visual Studio) then gives me a warning for converting "size_t" to "mwSize", which might lead to some data loss...

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: James Tursa

Date: 27 Apr, 2010 07:44:04

Message: 5 of 9

"Michael " <michael.schmittNOSPAM@bv.tum.de> wrote in message <hr63gk$8ts$1@fred.mathworks.com>...
>
> If I am not supposed to create any mean vector in advance, how do I work with the output of "mexCallMATLAB(1, &mean, 1, &pix, "mean");" within the MEX file? And how can I give an array created from several such calls back to MATLAB? That's the core of my problem.

The variable mean will point to an mxArray that contains the result of the "mean" function call. You can do whatever you want with it such as alter its data contents by using mxGetPr(mean) to get the data pointer, or return it back to MATLAB as one of the plhs elements if you like (e.g., plhs[0] = mean;), or both. Or you can treat it as a temporary variable inside you mex function and then when you are done with it just call mxDestroyArray(mean) to free it. If you state specifically what you want to do with it I can give you a more specific answer.

> Concerning the mwSize topic: I tried to declare rows and cols as mwSize like you suggested, but my compiler (Visual Studio) then gives me a warning for converting "size_t" to "mwSize", which might lead to some data loss...

What line is giving you a warning? I would have expected things to be matching up.

James Tursa

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: Michael

Date: 27 Apr, 2010 08:17:03

Message: 6 of 9

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...

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: Michael

Date: 27 Apr, 2010 14:12:04

Message: 7 of 9

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!!

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: James Tursa

Date: 27 Apr, 2010 15:26:04

Message: 8 of 9

"Michael " <michael.schmittNOSPAM@bv.tum.de> wrote in message <hr6rbk$47p$1@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]);
}

Subject: Interaction of MEX and MATLAB or mexCallMATLAB and Co.

From: Michael

Date: 28 Apr, 2010 08:30:21

Message: 9 of 9

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?

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us