Search code examples
c++matlabopencvmatlab-engine

Sending data from OpenCV matrix to Matlab Engine, C++


I am sending data from OpenCV matrices to matlab using C++ and Matlab Engine. I tried to convert from column major to row major but I am really confused on how to do that. I cannot understand how to deal with Matlab pointer mxArray and put data to the engine.

Has anybody worked with OpenCV together with matlab to send matrices? I didn't find much information and I think it is a really interesting tool. Any help will be welcomed.


Solution

  • I have a function that works if you have created the matlab engine. What I do is creating a SingleTone template for the matlab engine:

    My header looks like this:

    /** Singletone class definition
      * 
      */
    class MatlabWrapper
        {
        private:
            static MatlabWrapper *_theInstance; ///< Private instance of the class
            MatlabWrapper(){}           ///< Private Constructor
            static Engine *eng; 
    
        public:
            static MatlabWrapper *getInstance() ///< Get Instance public method
            {
                if(!_theInstance) _theInstance = new MatlabWrapper(); ///< If instance=NULL, create it
    
        return _theInstance;            ///< If instance exists, return instance
            }
        public:
        static void openEngine();               ///< Starts matlab engine.
        static void cvLoadMatrixToMatlab(const Mat& m, string name);
        };
    

    My cpp:

    #include <iostream>
    using namespace std;
    
    MatlabWrapper *MatlabWrapper::_theInstance = NULL;              ///< Initialize instance as NULL    
    Engine *MatlabWrapper::eng=NULL;
    void MatlabWrapper::openEngine()
    {
            if (!(eng = engOpen(NULL))) 
            {
                cerr << "Can't start MATLAB engine" << endl;
                exit(-1);
            }       
    }
    void MatlabWrapper::cvLoadMatrixToMatlab(const Mat& m, const string name)
    {
        int rows=m.rows;
        int cols=m.cols;    
        string text;
        mxArray *T=mxCreateDoubleMatrix(cols, rows, mxREAL);
    
        memcpy((char*)mxGetPr(T), (char*)m.data, rows*cols*sizeof(double));
        engPutVariable(eng, name.c_str(), T);
        text = name + "=" + name + "'";                    // Column major to row major
        engEvalString(eng, text.c_str());
        mxDestroyArray(T);
    }
    

    When you want to send a matrix, for example

    Mat A = Mat::zeros(13, 1, CV_32FC1);
    

    It's so simple as this:

    MatlabWrapper::getInstance()->cvLoadMatrixToMatlab(A,"A");