ステップバイステップOpenCVからMatlabにデータを送信する
1.-ライブラリを含めてリンクする
Matlabエンジンを操作するために必要なヘッダーは、 「engine.h」と「mex.h」です。インクルードパスは次のようになります。
c:\ Program Files(x86 \ MATLAB \ R2010a \ extern \ include)
追加の依存関係では、 libeng.lib、libmex.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);
}