Vous êtes sur la page 1sur 25

Interfacing Matlab and C / C++

Professor:
Bladimir Bacca Cortes Ph.D.
Perception and Intelligent Systems
Research Group.

Email:
Bladimir.bacca@correounivalle.edu.co
Contents

Justification
Requirements
MEX files framework.
Initial configurations:
GNUmex
File mexopts.bat
Example.
API description
Additional considerations with other packages:
Using external APIs: OpenCV.
Justification
Matlab Advantages :
Matrix based scientific software
Script language: low development time
Wide scientific community.
Many data acquisition systems support.
Many embedded systems support.
Function based programming: modular.

Matlab Disadvantages :
Since it is script based, it is slow.
Since it is function based, people get bad programming habits

Solutions to increase the processing speed:


Take advantage of the matrix based framework.
Use built-in functions such as: find(), reshape(), repmat().
Justification
j
Solutions to increase the
processing speed: i
Matrix based framework
Example Normalizing
histograms

First implementation:

for ii=1:size(H, 1)
vSum = 0;

for jj = 1:size(H, 2)
vSum = vSum + H(ii, jj); Second implementation:
end
for jj = 1:size(H, 2) for ii=1:size(H, 1)
H(ii, jj) = H(ii, jj) / vSum;
end H(ii, :) = H(ii, :) / sum(H(ii, :));
end end
Justification
Solutions to increase y
the processing speed:
Using built-in functions
such as: find(), repmat(),
reshape()
Example: Searching the x
minimum distance
between the elements of
two vectors. Ps1
First implementation:
Ps2
dPs1 = zeros(size(Ps1, 1), size(Ps2, 1));
for ii = 1:size(Ps1, 1) Second implementation:
for jj = 1:size(Ps2, 1)
dPs(ii, jj) = distPP(Ps1(ii), Ps2(jj)); MPs1 = repmat(Ps1, size(Ps2, 1), 1);
End MPs2 = repmat(Ps2, size(Ps1, 1), 1);
end dPs = sqrt((Ps1x Ps2x).^2 + (Ps2y
minD = min(dPs, [], 1); Ps1y).^2);
minD = min(dPs, [], 1);
Justification

Observation

If modifying the Matlab code such that the matrix based


framework is exploited to its maximum does not improve the
processing speed, then the MEX files framework is the better
option.
Requirements

Matlab Version: Equal or bigger than 6.5, which introduced the


Just In Time Compilation (JIT) technology.

Compiler: C/C++ or Java previously installed.

Configuring how Matlab can use the compiler.

In case of using other APIs or libraries:


Proper modifications to the mexopts.bat file is required in order to
include the API headers and libraries.
MEX Framework

Life cycle of a MEX


file:
MEX Framework
MEX files include:
A Gateway function to serve of interface between Matlab and C/C++ code.
The C/C++ custom software
And, a set of macros based on pre-processor directives in order to have a platform independent code.

All MEX file must have a function called mexFunction() which Matlab calls using a pre-defined pointer based
parameters. The function specification is as follows:

#include "mex.h"
#include "matrix.h"

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

}

Once Matlab is configured to use the C/C++ or Java compiler, the following Matlab command line is executed:

mex myMexFile.c // Donde myMexFile es el archivo que contiene la funcin mexFunction().


MEX Framework

MEX file parameters:


prhs: An array of pointers to the function parameters.
plhs: An array of pointers to the function return values.
nrhs: Number of input parameters.
nlhs: Number of output parameters.

mxArray data type: It is a data structure that encapsulates the Matlab data types.

These Matlab data types are handled through specialized functions.

The mx- prefix is used for all function or data type which is direct related with the Matlab data
types.

The mex- prefix is used for all function that interacts with Matlab such as: error reporting,
printing, etc.
MEX Framework
Example rmsd() /* Check data type of first input argument */
if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])) {
#include "mex.h mexErrMsgTxt("Input argument must be a real
double.");
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[])
/* Do the calculations */
{ nel = mxGetNumberOfElements(prhs[0]);
double res = 0; in = mxGetPr(prhs[0]);
double *in; for (ii=0; ii<nel; ii++) {
int ii, nel; res += *in * *in;
in++;
/* Check for proper number of input and output }
arguments */
res = sqrt(res);
if (nrhs != 1) {
mexErrMsgTxt("One input argument required.");
/* Create an output matrix and put the result in it. */
}
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
if (nlhs > 1) {
mxGetPr(plhs[0])[0] = res;
mexErrMsgTxt("Too many output arguments.");
} }
Initial Configurations

Download and Install the compiler suite for Windows based on the GNU
toolchain:
64bits platform: tdm64-gcc-4.9.2.exe
32bits platform: tdm32-gcc-4.9.2.exe
URL: http://tdm-gcc.tdragon.net/

Download the GNUMEX utility, which allows Matlab mex and engine files
written in C, C++, Fortran 77 or Fortran 95 to be compiled with MinGW (or
Cygwin) MS Windows versions of gcc, gfortran, g77 or g95.
URL: http://gnumex.sourceforge.net/

Download and Install the OpenCV 4.9 package. Note: This is not needed for
MEX files, however is needed at the second part of this class.
URL: http://opencv.org/downloads.html
Initial Configurations
GNUMEX

Open MATLAB
Unzip the GNUMEX package in:
C:\__APP_DIR__\MathWorks\MATLAB\
R2012a. Where, __APP_DIR__ is
your Matlab application directory.
Change the Working Directory to
where GNUMEX is unzipped.
Run gnumex.m
A dialog as shown at right will be
appear.
Normally, you have to fill the MinGW
root directory, the Path to
gfortran.exe, the Path to g95.exe
and the Path to gnumex utilities
options.
Press the Make Options File button.
It will generate the mexopts.bat file,
where all the compiler and linker
options will be stored.
Update PATH environment variable
with the BIN folder of TDM.
Initial Configurations
MEXOPTS.BAT
file:

Initial configuration
section:
Initial Configurations
MEXOPTS.BAT file:

Definitions section:
Initial Configurations
MEXOPTS.BAT file:

Compiler and linker sections:


Initial Configurations
Example No. 1:
Program Hola Mundo in MEX.

Compiling the program


myHelloWorld.c using the following
command:
mex myHelloWorld.c

In Matlab:
myHelloWorld(Funciona?);

Example No. 2:
Compiling and test the rmsd() file.

Running:
rmsd(1:10)
API Description
MX Functions mxGetField
mxAddField mxGetFieldByNumber
mxArrayToString mxGetFieldNameByNumber
mxCalloc mxGetFieldNumber
mxClassID mxGetImagData
mxCreateCellArray mxGetM
mxCreateCellMatrix mxGetN
mxCreateCharArray mxGetName
mxCreateCharMatrixFromStrings mxGetNumberOfDimensions
mxCreateDoubleMatrix mxGetNumberOfElements
mxCreateNumericArray mxGetNumberOfFields
mxCreateNumericMatrix mxGetPi
mxCreateScalarDouble mxGetPr
mxCreateSparse mxGetScalar
mxCreateString mxGetString
mxCreateStructArray mxIsXXX
mxCreateStructMatrix
mxDestroyArray
mxDuplicateArray
mxFree
mxGetCell
mxGetClassID
mxGetData
mxGetDimensions
mxGetElementSize
API Description

MEX Functions mexIsGlobal


mexAtExit mexIsLocked
mexCallMATLAB mexLock
mexErrMsgTxt mexMakeArrayPersistent
mexEvalString mexMakeMemoryPersistent
mexFunction mexPrintf
mexFunctionName mexPutArray
mexGet mexSet
mexGetArray mexSetTrapFlag
mexGetArrayPtr mexUnlock
mexWarnMsgTxt
Additional Considerations with
Other Packages
Case of Study: OpenCV 4.9

System configurations: Including the BIN directory of the OpenCV distirbution in the
PATH variable

Open the mexopts.bat file:

Include the following lines into mexopts.bat file:

rem OPENCV 2.49


set OPENCVINCCORE1=%OPENCV249_HOME_S%\build\include\opencv2\core
set OPENCVINCCORE2=%OPENCV249_HOME_S%\build\include
set OPENCVIMGPROC1=%OPENCV249_HOME_S%\build\include\opencv2\imgproc
set OPENCVINCGUI=%OPENCV249_HOME_S%\build\include\opencv2\highgui
set LIBOPENCV=%OPENCV249_HOME_S%\build\x64\vc10\bin

IMPORTANT: Where OPENCV249_HOME_S is an environmental variable pointing to the


install directory of OpenCV 4.9. Replace x64 for x86 if it is needed.
Additional Considerations with
Other Packages
Case of Study: OpenCV 4.9

To locate the GM_ADD_LIBS environmental variable and modify it to:

set GM_ADD_LIBS=-llibmx -llibmex -llibmat -lopencv_core249 -lopencv_imgproc249 -


lopencv_highgui249

For 64bits machines: To locate the COMPILER and COMPFLAGS environment variables
and modify them if needed to:

set COMPILER=x86_64-w64-mingw32-gcc
set COMPFLAGS=-m64 -c -DMATLAB_MEX_FILE -I%OPENCVINCCORE1% -
I%OPENCVINCCORE2% -I%OPENCVIMGPROC1% -I%OPENCVINCGUI%

For 32bits machines: To locate the COMPILER and COMPFLAGS environment variables
and modify them if needed to:

set COMPILER=gcc
set COMPFLAGS=-c -DMATLAB_MEX_FILE -I%OPENCVINCCORE1% -I%OPENCVINCCORE2% -
I%OPENCVIMGPROC1% -I%OPENCVINCGUI%
Additional Considerations with
Other Packages
Case of Study: OpenCV 4.9

To locate the LINKFLAGS (Second one) environment variable and modify it to:

set LINKFLAGS=-static-libgcc -
LC:\Users\BLADIM~1\AppData\Roaming\MATHWO~1\MATLAB\R2012a\gnumex
-L%LIBOPENCV%

Where the text in blue may change according with your system configuration.

Update the PATH environment variable with the following value if your PC is 64bits:

%OPENCV249_HOME_S%\build\x64\vc10\bin

Update the PATH environment variable with the following value if your PC is 32bits:

%OPENCV249_HOME_S%\build\x86\vc10\bin
Additional Considerations with Other
Packages
Measuring the execution time in Matlab, load the matlabCannyFilter.m script:

close all;
Image = rgb2gray(imread('img_120.jpg'));

tic; edgeImage = edge(Image, 'canny', 0.1, 2); tt = toc;

figure(1002); imshow(uint8(Image)); title('Imagen Original');


figure(1003); imshow(uint8(edgeImage * 255)); title(['Bordes - Tcalc: ' num2str(tt)]);
Additional Considerations with
Other Packages
Compiling the myCannyFilterV31.c function:

mex myCannyFilterV31.c

Testing the compiled function with the program testMyCannyFilterV3.m and measure
the execution time.
Questions?

Vous aimerez peut-être aussi