3

グラフをプロットし、快適な方法で統計を計算するために、 OpenCV変数をMatlabに送信できるようにしたいと考えています。

Matlab エンジンを使用する必要があることはわかっていますが、コードの任意の部分からアクセスできるようにする方法、CV::Mat から Matlab 配列に変換する関数、または列の処理方法について、Web 上にはほとんど助けがありません。この特定のケースでは、-major および row-major です。

OpenCV から Matlab へのステップバイステップの手順は非常に興味深いと思います。なぜなら、OpenCV は非常に人気があり、Matlab はデバッグに大いに役立つからです。

4

1 に答える 1

4

ステップバイステップOpenCVからMatlabにデータを送信する

1.-ライブラリを含めてリンクする

Matlabエンジンを操作するために必要なヘッダーは、 「engine.h」「mex.h」です。インクルードパスは次のようになります。

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

追加の依存関係では、 libeng.liblibmex.lib、およびlibmx.libを追加する必要があります。

プロジェクトを設定する最も簡単な方法は、行を書くだけでよいので、CMakeを使用することです。

find_package(Matlab REQUIRED)

INCLUDE_DIRECTORIES($ {MATLAB_INCLUDE_DIR})

CMakeがパスを設定し、必要なライブラリをリンクします。環境変数を使用することにより、プロジェクトをユーザーに依存しないようにします。それが私がいつもCMakeを使う理由です。

2.-MatlabEngineの一意のインスタンスのシングルトンテンプレート。

コードの任意の部分からMatlabEngineを呼び出すための本当に快適な方法は、シングルトンテンプレートを作成することです。たとえば、「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 ...
};

次に、「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.-メインコードからMatlabエンジンを使用します。

これを行うには多くの方法がありますが、私は通常、initializeMatlab()後で使用する変数(Matlab変数)を初期化する関数を定義します。初めてgetInstance()を呼び出すと作成されるため、クラスMatlabWrapperを作成する必要はありません。次にgetInstanceを呼び出すと、それが返されます。それがシングルトーンの目的です。

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

4.-OpenCVマトリックスをMatlabに送信する

これで私はより多くの困難を見つけました。これは、ステップバイステップでデバッグするために行列をmatlabに送信するだけの単純な関数です。毎回上書きされます。

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);
}
于 2012-06-12T07:14:58.463 に答える