简体   繁体   English

一步一步的指南,以便轻松地将OpenCV C ++变量发送到Matlab

[英]A step by step guide to easily send OpenCV C++ variables to Matlab

I want to be able to send any OpenCV variables to Matlab in order to plot graphs and calculate statistics in a confortable way. 我希望能够将任何OpenCV变量发送到Matlab ,以便以一种舒适的方式绘制图形并计算统计数据。

I know I have to use Matlab Engine, but there is little help on the web about how to make it accessible from any part of the code, or about functions to convert from CV::Mat to Matlab arrays, or how to deal with column-major and row-major in this specific case. 我知道我必须使用Matlab Engine,但是网上几乎没有关于如何从代码的任何部分访问它,或者关于从CV :: Mat转换到Matlab数组的函数,或者如何处理列的帮助 - 在这种特定情况下的主要和行主要。

I think an step by step procedure OpenCV-to-Matlab would be very interesting since OpenCV is becoming really popular and Matlab helps a lot for debugging. 我认为OpenCV-to-Matlab一步一步程序将非常有趣,因为OpenCV正变得非常流行,而且Matlab对调试有很大帮助。

Step by Step Sending data from OpenCV to Matlab 逐步将数据从OpenCV发送到Matlab

1.- Including and linking libraries 1.-包括和链接库

The neccesary headers for working with Matlab Engine are "engine.h" and "mex.h" . 使用Matlab Engine必要标题是“engine.h”“mex.h” The include path will be something like this: 包含路径将是这样的:

c:\\Program Files (x86\\MATLAB\\R2010a\\extern\\include) c:\\ Program Files(x86 \\ MATLAB \\ R2010a \\ extern \\ include)

In additional dependencies you should add: libeng.lib , libmex.lib and libmx.lib . 在其他依赖项中,您应该添加: libeng.liblibmex.liblibmx.lib

The easiest way to set up the project is by using CMake, as you just need to write the lines 设置项目的最简单方法是使用CMake,因为您只需要编写行

find_package( Matlab REQUIRED ) find_package(需要Matlab)

INCLUDE_DIRECTORIES( ${MATLAB_INCLUDE_DIR}) INCLUDE_DIRECTORIES($ {MATLAB_INCLUDE_DIR})

CMake will set the paths for you and link the needed libraries. CMake将为您设置路径并链接所需的库。 By using environment variables you make the project user-independent. 通过使用环境变量,您可以使项目与用户无关。 That's the reason why I always use CMake. 这就是我总是使用CMake的原因。

2.- Singleton template for an unique instance of Matlab Engine. 2.-用于Matlab引擎的唯一实例的单例模板。

A really comfortable way to call Matlab Engine from any part of the code is creating a Singleton template. 从代码的任何部分调用Matlab引擎的一种非常舒适的方法是创建一个Singleton模板。 You could create a "matlabSingleton.h" , for example, and write something like this. 例如,你可以创建一个“matlabSingleton.h” ,并写下这样的东西。

#include "engine.h";
#include "mex.h";

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 NULL, create it
        return _theInstance;                    
    }
public:
        static void openEngine();
        void initializeVariable(const string vName) const;
        // ... other functions ...
};

Then in "matlabSingleton.cpp" you should write 然后在“matlabSingleton.cpp”中你应该写

#include "matlabSingleton.h"

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::initializeVariable(const string vName) const
{
    string command = vName + "=0";
    engEvalString(eng, command.c_str());
}

3.- Using Matlab engine from your main code. 3.-使用主代码中的Matlab引擎。

There are many ways to do this but I usually define a function initializeMatlab() where I initialize the variables (Matlab variables) I will later use. 有很多方法可以做到这一点,但我通常定义一个函数initializeMatlab() ,我在其中初始化变量(Matlab变量)我将在以后使用。 You don't need to create the class MatlabWrapper because the first time you call getInstance() it will be created. 您不需要创建MatlabWrapper类,因为第一次调用getInstance()时它将被创建。 Next times you call getInstance it will just be returned. 下次你调用getInstance它只会被返回。 That's what singletone is for. 这就是单声道的用途。

void initializeMatlab(){
   MatlabWrapper::getInstance()->initializeVariable("whatever1"); //class is created
   MatlabWrapper::getInstance()->initializeVariable("whatever2"); //instance of the class returned
}

4.- Sending an OpenCV Matrix to Matlab 4.-将OpenCV矩阵发送到Matlab

At this is where I foun more difficulties. 在这是我遇到更多困难的地方。 This a simple function just to send a matrix to matlab for debugging step by step. 这个简单的函数只是将一个矩阵发送到matlab进行逐步调试。 It is overwritten each time. 它每次都被覆盖。

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);          

    double *buffer=(double*)mxGetPr(T);
    for(int i=0; i<rows; i++){    
        for(int j=0; j<cols; j++){
            buffer[i*(cols)+j]= (double)m.at<float>(i,j);      
        }
    }   
    engPutVariable(eng, name.c_str(), T);
    text = name + "=" + name + "'";                    // Column major to row major
    engEvalString(eng, text.c_str());
    mxDestroyArray(T);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM