2

ビデオ内のいくつかのオブジェクトを追跡するために cvBlobs を使用しています。cvBlobs は、IplImage、cvMat などの型で古い C インターフェイスを使用します。私は、cv::Mat を使用する C++ インターフェイスを使用しています。

したがって、ライブラリを使用するには、2 つの型の間で変換する必要があります。これは機能しますが、メモリの解放に問題があります。プログラムが使用するメモリが増え続けています。

これは私のコードで、一番下にメモリを解放しようとしていることが表示されます (コンパイラ エラー)。

void Tracker::LabelConnectedComponents(Mat& Frame, Mat& Foreground)
{
    // Convert to old format, this is the method used in the opencv cheatsheet
    IplImage IplFrame = Frame;
    IplImage IplForeground = Foreground;

    IplImage *LabelImg = cvCreateImage(cvGetSize(&IplFrame), IPL_DEPTH_LABEL, 1);

    // Make blobs (IplForeground is the segmented frame, 1 is foreground, 0 background)
    unsigned int result = cvLabel(&IplForeground, LabelImg, Blobs);

    // Remove small blobs
    cvFilterByArea(Blobs, 500, 1000000);

    // Draw bounding box
    cvRenderBlobs(LabelImg, Blobs, &IplFrame, &IplFrame, CV_BLOB_RENDER_BOUNDING_BOX | CV_BLOB_RENDER_CENTROID);

    // Convert back to c++ format
    Frame = cvarrToMat(&IplFrame);

    // Here are the problems
    cvReleaseImage(&IplFrame); // error
    cvReleaseImage(&IplForeground); // error
    cvReleaseImage(&LabelImg); // ok
}

cvReleaseImage には引数として IplImage** 型があり、これはコンパイラ エラーです。

tracker.cpp|35 col 33 error| cannot convert ‘IplImage* {aka _IplImage*}’ to ‘IplImage** {aka _IplImage**}’ for argument ‘1’ to ‘void cvReleaseImage(IplImage**)’

&IplFrame が正しい引数ではないことはわかっていますが、&&IplFrame は機能しません。これらの 2 つの IplImage を解放するにはどうすればよいですか?

4

2 に答える 2

1

問題は、ここでオブジェクトのコピーを作成したことです。

IplImage IplFrame = Frame;
IplImage IplForeground = Foreground;

したがって、これらの呼び出しは次のとおりです。

cvReleaseImage(IplFrame); 
cvReleaseImage(IplForeground);

これがコンパイルされても、元のイメージはリリースされません。すでにオブジェクトを削除している(つまり、オブジェクトを変更している)場合、なぜオブジェクトをポインターではなく参照としてメソッドに送信するのですか?あなたがこのようなことをしているように見えるので、私は少し混乱しています:

Mat frame = ...
Mat fg = ...
LabelConnectedComponents(frame, fg); // function releases the frame/fg memory
// at this point you are left with invalid frame/fg

ドキュメントを確認しましたがMat::operator IplImage() doesn't copy data、これはIplFrameがメモリを所有していないことを意味するため、解放するのは正しくありません。

Matインスタンスがどのように作成されたかによると思います。IplImage*をにcopyData設定してから作成された場合は、元のインスタンスfalseを解放する必要があります。に設定してIplImage作成された場合、インスタンスが自動的に処理します(明示的にを使用して作成した場合を除く)copyDatatrueMatMat::release

于 2012-09-28T08:22:00.093 に答える
1

Mat オブジェクトから構築された IplImage の割り当てを解除する必要はありません。これらはシン ラッパーであり、データをコピーしないため、何も解放する必要はありません。

また、cv::Mat には自動メモリ管理があるため、何も解放する必要はありません。

そして、完了として、cvReleaseImage を呼び出すには、ポインターをポインターに送信する必要があります。

IplImage* pimg= cvLoadImage();
...
cvReleaseImage(pimg);

コンストラクト

IplImage img;
... 
cvReleaseImage(&&img);

&img はアドレス (メモリ アドレス) ですが、変数を示していないため、機能しません。&img は値であるため、次の評価 &(&img) ではコンパイラ エラーが発生します。値にアドレスを含めることはできませんが、単純な数値です。

于 2012-09-28T08:44:26.857 に答える