-
Notifications
You must be signed in to change notification settings - Fork 319
Developing a new MEX function
All you need to do is to add your C++ source file in src/+cv/
. If you want
to add a MEX function called myfunc
, create src/+cv/myfunc.cpp
.
The minimum contents of the myfunc.cpp
would look like this:
#include "mexopencv.hpp"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// Check number of arguments
nargchk(nlhs<=1 && nrhs==1);
// Convert mxArray to cv::Mat
cv::Mat mat = MxArray(prhs[0]).toMat();
// Do whatever you want
// Convert cv::Mat back to mxArray
plhs[0] = MxArray(mat);
}
This example simply copies an input to a cv::Mat
object and then copies
it again to the output. Notice how the MxArray
class provided by
mexopencv converts mxArray
to cv::Mat
object and back. Of course
you would want to do something more with the object. Once you create a new
source file, type mexopencv.make()
in MATLAB to build your new function. The
compiled MEX function will be located inside +cv/
and accessible through
cv.myfunc
within MATLAB.
The mexopencv.hpp
header includes the class MxArray
to
manipulate mxArray
objects. Mostly this class is used to convert
between OpenCV data types and mxArray
.
int i = MxArray(prhs[0]).toInt();
double d = MxArray(prhs[0]).toDouble();
float f = MxArray(prhs[0]).toFloat();
bool b = MxArray(prhs[0]).toBool();
std::string s = MxArray(prhs[0]).toString();
cv::Mat mat = MxArray(prhs[0]).toMat(); // For pixels
cv::MatND mat = MxArray(prhs[0]).toMatND(); // For N-D array
cv::SparseMat sp = MxArray(prhs[0]).toSparseMat(); // Only double to float
cv::Point pt = MxArray(prhs[0]).toPoint();
cv::Size sz = MxArray(prhs[0]).toSize();
cv::Rect rct = MxArray(prhs[0]).toRect();
cv::Scalar sc = MxArray(prhs[0]).toScalar();
cv::RotatedRect rr = MxArray(prhs[0]).toRotatedRect();
plhs[0] = MxArray(i);
plhs[0] = MxArray(d);
plhs[0] = MxArray(b);
plhs[0] = MxArray(s);
plhs[0] = MxArray(mat);
plhs[0] = MxArray(sp); // Only 2D float to double
plhs[0] = MxArray(pt);
plhs[0] = MxArray(sz);
plhs[0] = MxArray(rct);
plhs[0] = MxArray(sc);
plhs[0] = MxArray(rr);
There are also versions that handle STL vectors of such types.
Check MxArray.hpp
for the complete list of the conversion API.
mexopencv.hpp
also contains additional helper conversion functions.
If you rather want to develop a MATLAB class that internally calls a MEX
function, make use of the +cv/private/
directory. Any function placed under
private directory is only accessible from +cv/
directory.
So if you want to design a MATLAB class cv.MyClass
that wraps the various
behavior of a C++ class, define your MATLAB class at +cv/MyClass.m
with a
corresponding MEX function in src/+cv/private/MyClass_.cpp
.
Inside of +cv/MyClass.m
, you can call MyClass_()
without the cv
namespace. In mexopencv, this is usually used to exposed C++ classes as MATLAB
classes.
Check +cv/PCA.m
and src/+cv/private/PCA_.cpp
for a concrete example.
You can optionally add a testing script for your new function. The testing
convention in mexopencv is that testing scripts are all written as a static
function in a MATLAB class. For example, test/unit_tests/TestFilter2D.m
is
a class that describes test cases for cv.filter2d
function. Inside of the
class, a couple of test cases are written as static functions whose name start
with 'test'.
Testing is performed by test/UnitTest.m
. It looks for unit testing classes
inside test/unit_tests/
, invokes all test cases, and reports the results.
Place any resource files necessary for testing inside the test/
directory.
An example of testing class is shown below:
classdef TestMyFunc
methods (Static)
function test_my_func
src = imread(fullfile(mexopencv.root(),'test','img001.jpg'));
ref = [1,2,3]; % reference output
dst = cv.myfunc(src); % execute your function
assert(isequal(dst, ref)); % check the output
end
function test_error_argnum
try
cv.myfunc('foo'); % myfunc should throw an error
error('UnitTest:Fail', 'myfunc incorrectly returned');
catch ME
assert(strcmp(ME.identifier, 'mexopencv:error'));
end
end
end
end
First add the test
directory to the MATLAB path and invoke UnitTest
to run all the test routines. You can also run make test
from a Unix shell.
You can create a MATLAB help documentation for a MEX function by having the
same file with '.m' extension. For example, a help file for
src/+cv/filter2D.cpp
would be +cv/filter2D.m
placed next to the compiled
MEX function +cv/filter2D.mex*
. The help file should only contain MATLAB
comments. MATLAB will display the help text when you run help cv.filter2D
.
An example is shown below:
%MYFUNC Brief description about my function
%
% out = cv.myfunc(in)
%
% ## Input
% * __in__ input image.
%
% ## Output
% * __out__ output image.
%
% Detailed description of function continues...
%
% See also: cv.filter2D
%
The help file can also contain Markdown syntax in the comments, which is
processed by MDoc
when generating the HTML documentation.
Help: Stack Overflow (MATLAB, OpenCV) | MATLAB Answers | OpenCV Answers
- Windows + MATLAB
- Windows + Octave
- Linux + MATLAB
- Linux + Octave
- macOS + MATLAB
- macOS + Octave
- Windows + MATLAB
- Linux + MATLAB
- macOS + MATLAB