1

約3000枚の画像を含むいくつかのディレクトリを反復しようとしています。画像を読み込みます。画像が読み込まれたら、解放します。これは、エラーを再現するために作成できる最小のプログラムです。

124枚の画像をロードしてリリースした後、プログラムは画像のロードを停止します。これはメモリの問題だと思いますが、プログラムが画像の読み込みを停止する原因が正確にはわかりません。

MacでOpenCVを使用しています。使用しているバージョンをどれだけ正確に把握できるかわかりません。

これが私のプロジェクトのコードです。

bool FaceDetectionStrategy::detectFace(std::string imagePath) {

   IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR);
   if (img) {
      std::cout << "Image loaded " << imagePath << std::endl;
      cvReleaseImage(&img);
   } else {
      std::cout << "Image not loaded " << imagePath << std::endl;
   }
return true;

}

このメソッドは、反復処理しているディレクトリ内のすべての画像に対して呼び出されます。124枚の画像の後、if(img)部分はfalseと評価され、elseブランチが実行されます。後でプログラムの他の部分から画像を読み込もうとすると、それらも読み込まれません。

編集はメモリの問題ではありません。Mac Osの標準の最大オープンファイル数は、512に変更すると256になり、251の画像を開くことができます。そのため、OpenCVは画像ファイルを読み込んだ後に閉じないようです。

4

2 に答える 2

3

OpenCvからバグトラッカーを検索すると、この問題に対する答えがわかりました。MacImageIOを使用したcvLoadImageは、ファイルハンドルを開いたままにします。

これはOpenCVmac実装のバグのようであり、それを解決する唯一の方法は、OpenCVの新しいバージョンをインストールすることです。

EDITリポジトリトランクからOpenCVの最後のバージョンをインストールすると、問題が解決します。使用しているフレームワークのバグトラッカーをチェックするのに役立つ場合があります...

于 2009-07-25T17:51:05.730 に答える
2

私の経験では、記憶に関する行動が一貫した数と関係することはめったにありません。一貫性を保つ唯一の方法は、あまり一般的ではない番号124である、ある種の内部制限がcvLoadImageある場合です。しかし、あなたの論理は私には問題ないようです。画像をリリースする必要があります。

おそらく、ディレクトリはテスト間で変更されていないと想定しているので、125番目のイメージは不良です。

ロードしようとしている画像が実際に存在することを確認しましたか?もしそうなら(おそらくそうするでしょう)、画像ファイル形式がOpenCVでサポートされていることを確認してください。それが当てはまる場合は、別のエディターでファイルを開いて、ファイルが破損していないことを確認してください。

OpenCVにエラーの解決を支援してもらうことができます。エラーが発生したかどうかを確認するために使用しcvGetErrStatus()、次にエラーcvErrorStr()のテキストによる説明を取得するために使用します。あなたはこのようなことをすることができます:

// I would recommend putting this in a file, like CVUtility.h

#include <exception>

void check_CV_Error(void)
{
    int errorCode = cvGetErrStatus();
    if (errorCode) // I'm assuming 0 means no reportable error
    {
        throw std::runtime_error(cvErrorStr(errorCode));
        // std::cerr << cvErrorStr(errorCode);
        // ^ if you would rather not use exceptions
    }
}

コードは次のようになります。

bool FaceDetectionStrategy::detectFace(std::string imagePath) {

   IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR);
   if (img) {
      std::cout << "Image loaded " << imagePath << std::endl;
      cvReleaseImage(&img);
   } else {
      std::cout << "Image not loaded " << imagePath << std::endl;
      check_CV_Error(); // find reason for error
   }
return true;

そして、それはあなたがキャッチしてログに記録するための例外をスローし、おそらくそれに反応します。(または、バージョンを使用している場合は、エラーをコンソールに出力しますstd::cerr

于 2009-07-25T02:10:45.550 に答える