5

次のコード サンプルを検討してください。以下にマークされた行が実行時にブレークポイント/例外をトリガーするのはなぜですか?

int main() {
    Mat m1 = Mat::zeros(10, 1, CV_32FC1);
    Mat m2 = Mat::zeros(10, 3, CV_32FC1);

    vector<float> v1(m1); // works
    Mat m2sub = m2.col(0);
    Mat m2subClone = m2.col(0).clone();
    vector<float> v2(m2subClone); // works
    vector<float> v3(m2sub); // doesn't work
return 0;
}

呼び出されているのは mat.hpp にあるため、奇妙に思えます。

template<typename _Tp> inline Mat::operator std::vector<_Tp>() const {
    std::vector<_Tp> v;
    copyTo(v);
    return v; // <- breaks here
}

そしてcopyToはデータをmemcpyしているようです。

エラー メッセージは表示されませんが、スタック トレースを見ると、return ステートメントでブレークし、「operator new」と「ntdll.dll!RtlpAllocateHeap()」のどこかで壊れていることがわかります。

奇妙なことに、私の完全なコードでは、わずかに異なる場所で中断します: memcpy の copyTo(v) 内で、「場所 0x0000000001F43D4C を書いているアクセス違反」をスローします。私の完全なコードは上記のものとまったく同じように見えますが、行列はより大きくなっています。

編集:上記の例では、行列を次のように変更します

    Mat m1 = Mat::zeros(5900, 1, CV_32FC1);
    Mat m2 = Mat::zeros(5900, 3, CV_32FC1);

スニペットは、完全なコードと同じ場所で失敗し、アクセス違反エラーが発生します。

2GB を超える RAM があり、アプリは 64 ビット アプリとしてコンパイルされているため、「メモリ不足」の問題ではありません (?)

4

1 に答える 1

2

OpenCVのMatクラスはよくわかりませんが、行列の列で共有されているものがあるので、memcopyするのは良くないかもしれません。Mat::row メソッドの OpenCV ドキュメント (ここでは、Mat::col メソッドには「共有ヘッダー」について同じ引数があります) を確認すると、次のことはお勧めできないことを示すメモがあります。

Mat A;
...
A.row(i) = A.row(j); // will not work

代わりに以下を使用する必要があります。

A.row(j).copyTo(A.row(i));

したがって、おそらくコードでこれを使用する必要がありました。

vector<float> v3;
m2sub.copyTo(v3);
于 2013-10-25T19:54:46.047 に答える