1

opencv でメモリ管理のあいまいさを経験しました。これは、新しい opencv C++ クラスで行うことができます。

cv::Mat theimage = cvLoadImage("rawimage.pgm",CV_LOAD_IMAGE_ANYDEPTH);

次のことを行うと、エラーが発生します。

theimage.deallocate();

多分これは間違っています。私はいくつかの実験を行い、Mat オブジェクトを解放すると:

theimage.release();

IplImage オブジェクトはまだメモリに残っています。cv::Mat オブジェクトに IplImage オブジェクトを破棄させる方法はありますか、それともコードの最初の行が間違っていますか (IplImage オブジェクトのポインターを失ったため) ? 人々がコードの最初の行を使用しているインターネットで多くの例を見てきました。多くの人が変換方法を説明していますが、メモリで何が起こるかは誰も説明していません!

問題は、IplImage オブジェクトを使用している多くのクラスがあることです (私はそれを使用してプロジェクトを開始しました)。また、cv::Mat が IplImage よりも優れている理由も理解しています。

- 編集 -

インターネットで、ミキシングのための次の解決策を見つけました。

cv::Ptr<IplImage> tmp = cvLoadImage("rawimage.pgm",CV_LOAD_IMAGE_ANYDEPTH);
cv::Mat theimage(tmp);

これは私の問題のいくつかを解決できると思いますが、コードが少し読みにくくなり、私の意見ではまだ危険です。cv::Mat の前に tmp の割り当てが解除された場合、いくつかの破損したオブジェクトを使用します (テストはしていませんが、そうだと思います)。簡単な方法は、コピーを使用することです。

cv::Mat theimage(tmp,true);

これが私が見つけた唯一の解決策ですが、私にとっては間違っていると感じています...

4

1 に答える 1

3

あいまいさは、C インターフェースと OpenCV の C++ インターフェースを混在させるという、非常に恐ろしい慣習に由来します。それをしないで、cv::imread()代わりに使用してください。

のデストラクタは、から初期化された場合を除いて、必要にcv::Mat 応じて常にメモリの割り当てを解除します。この情報を確認するための簡単な実験を書きました。IplImagedeallocate()

void load()
{
    cv::Mat img = cvLoadImage("out.png", 1);

    std::cout << "* IMG was loaded\n";
    getchar();

    img.deallocate();
}

int main()
{
    load();

    std::cout << "* IMG was deallocated\n";
    getchar();

    return 0;
}

呼び出しによってプログラムが一時停止されるgetchar()ため、アプリケーションのメモリ フットプリントを確認できます。コメント アウトdeallocate()すると、イメージを読み込んだ後もメモリ フットプリントが減少しないことがわかります。

余談ですが、参照カウンターのみを減らし、必要に応じてデータの割り当てを解除します (ただし、が から初期化さMat::release()れた場合は割り当ても解除されません)。MatIplImage

于 2012-06-22T12:49:43.830 に答える