Pages

Sunday, 24 May 2015

What if I told you, you can use OpenCV code with Matlab mex!!



Matlab is probably one of the best tools for quickly prototyping and testing your research ideas. As quick and flexible it is, sometimes Matlab code can consume a lot of execution time. This is specifically a big hurdle when multiple experiments need to be run. A real-time execution alternative is to implement Matlab compatible C++ code and compile it with mex-compiler. While this works most of the time, it is well known that quickly implementing ideas in C++ is not possible.



Being familiar with OpenCV, it was straightforward for me to implement my code using OpenCV in C++. So I wondered if it was possible to compile code written using OpenCV with mex-compiler for use in matlab. It turns out that it is quite easy, and requires no change to your existing OpenCV C++ implementations - which is awesome as it can speed a code upto 10x better without consuming too much time for writing a low level C++ code.

In this blog post I explain this process so that it could be of help to anyone facing the same problem as I did.

The first thing to know about mex C++ code is that you have to check for all the anticipated input and output (unlike a Matlab function). This requires a bit of planning and I absolutely think that most of the logical errors end up being somehow related to handling of the input to and output from the mexFunction. Next step is to convert the input data to OpenCV Mat format and convert output OpenCV Mats to mex compatible arrays. Once the input is converted to OpenCV Mat, one can directly call methods written purely in C++ using OpenCV. This makes all the code written in C++ compatible with Matlab mex.

Some important points to keep in mind:
- Index in C++ starts from 0, whereas matlab starts from 1 - so whenever directly returning indices be sure to convert between the two formats or else it may result in apparently mysterious logical errors. This is specifically true if you have used hashmaps for defining relationships between data and the algorithms applied on it.

- mex code with OpenCV support should be linked and compiled with corresponding OpenCV libraries -  dlls corresponding to these linked libraries should be placed in the same folder as compiled mex.

- datatypes in C++ mex have to be explicitly handled - this is quite different from Matlab, where the datatype is automatically determined. I have noticed that most of the crashes/logical errors in C++ arises as a result of ignoring this very important point.

I have prepared a simple example with the help of a code from mathworks, which converts between matlab mex mxArray and OpenCV Mat for input to and output from a mex function. This OpenCVWithMex project can be accessed at: https://github.com/devkicks/OpenCVWithMex. The project includes a mex compile script that compiles and links the cpp mexFunction with OpenCV libraries (also included in the project).

If this is your first time using mex, then it is highly recommended that you go through the guidance documents for mex on mathworks website. In the interest of the length of the post and keeping everything simple I am leaving the details on how mex works for a future post.