5

OpenCV の最新リリースの多くの機能では、STL コンテナーを使用する必要があります。それらを Matlab MEX ファイルで使用しようとすると、問題が発生します。Matlab 内から MEX ファイルをコンパイルしています。OpenCV と Matlab はどちらも、コード生成に「マルチスレッド DLL」である「/MD」フラグを使用します。

コンパイラ: MSVC++ 9.0 Matlab 2010a SVN の最新の OpenCV、2.11 だと思います。

私が使用しているコードは非常に単純です。

vector<KeyPoint> keypoints_vec;
SurfFeatureDetector surf;
surf.detect(cvImg,keypoints_vec);

これはコンパイルされますが、Matlab MEX ファイルで実行するとクラッシュします。クラッシュは、vector::resize の OpenCV 内にあります。古いインターフェース (STL コンテナーなし) は問題なく動作しますが、非推奨です。Matlab と OpenCV の間で STL コンテナーを使用するにはどうすればよいですか?

4

4 に答える 4

2

私はこの 2 日間、まさにこの問題と闘いました。問題はこれです:
libmex.dll(およびMatlab全体)はMicrosoft.VC80.CRT(バージョン= 8.0.50727.4053)
を使用しますが、OpenCVはMicrosoft.VC90.CRT(バージョン= 9.0.21022.8)を使用します

したがって、以前のバージョンの VC (私の知る限り VS 2005 SP1) を使用するか、回避策として gcc (MINGW) を使用できます (この場合、まったく異なる stl を使用するため、干渉することはできません)。 .
私は後者を実行しましたが、動作し、Matlab の次のバージョンで動作することを願っています (うまくいけば)。

于 2011-03-09T11:13:25.130 に答える
1

過去数日間、同様の問題がありましたが、MathWorks の親切な人々の助けを借りて問題を解決することができました。

http://www.mathworks.com/matlabcentral/answers/9294-mex-dynamic-memory-management-issue-with-std-vector-in-linked-external-dll-segmentation-errorの元の投稿から:

おそらく、コンパイル済みの dll で使用される stl ライブラリまたはコンパイラ オプションと、MATLAB および MEX コマンドで使用されるものとの間に非互換性が見られます。MATLAB 2009b は MSVC 2005 でビルドされました。

mex で使用されるオプションを変更するか、MSVC を使用して mex ファイルを直接ビルドすることで、問題を解決できる場合があります。影響を与える可能性があるオプションの一例は、SECURE_SCL=0 です。問題のあるオプションを見つけるために MATLAB が使用しているオプションを使用してテスト プログラムをビルドすることから始め、mex ファイルをビルドするときにそのオプションを削除してみます。

この種の非互換性のため、サードパーティがコンパイルしたライブラリの API で stl オブジェクトを使用することは、通常はお勧めできません。

彼のアドバイスに従って、mex オプション ファイルから SECURE_SCL=0 オプションを削除しました。

C:\Users\ThePit\AppData\Roaming\MathWorks\MATLAB\R2009b\mexopts.bat

次に、mex ファイルを再コンパイルすると、すべてが魅力的に機能するようになりました。関数は正しいデータを返し、セグメンテーション エラーは発生しなくなりました。

于 2011-06-13T20:55:54.787 に答える
1

ずっと前に、Matlab <-> VS 相互運用に問題がありました。Microsoft Visual C++ ランタイム ライブラリの不一致である可能性があります。matlab に必要なランタイム ライブラリと、使用しているビジュアル スタジオのバージョンを確認してください。プログラムの dll 依存関係を取得するために Depends を使用したことを覚えています。クラッシュ後に (msdev デバッガーをアタッチして) コール スタックを確認すると、ヒントが得られる場合があります。

ずいぶん前のことなので、覚えていることをヒントにしています。

于 2010-07-29T15:28:18.530 に答える
0

ベクトル内のデータは、単一の連続したブロックとして保存する必要があります

std::vector<int> data;
int *array = &data[0]; 
int *array = &data.front(); 

データへの 'c' スタイルのポインターを与える必要があります。これらを matlab に渡してみてください。

参照: C++ STL ベクトル テンプレートは、そのオブジェクトを Visual Studio コンパイラの実装にどのように格納しますか?

于 2010-07-29T15:32:37.720 に答える