1. ホーム
  2. c++

[解決済み] OpenCV - 画像表示ウィンドウを閉じる

2022-02-18 02:37:49

質問

画像データベースを検索するプロジェクトを行っているのですが、あるクエリの結果、5つのデータベース画像を見つけたとき、その結果をビジュアルに表示したいのです。私はメモリ内のすべての画像を保持していないため、私はそれを表示するために最初に画像をロードする必要があります。

私は、疑似コードで、簡単なものを考えていました。

for image 1..5
    load images
    display image in a window
    wait for any keypress
    close the window

以下は、私のコードのスニペットです。 C++ を使って OpenCV を使用します。

IplImage *img;

for (int i=0; i < 5; ++i){
    img = cvLoadImage(images[i].name.c_str(),1);
    cvShowImage(("Match" + images[i].name).c_str(), img);
    cvWaitKey(0);
    cvDestroyWindow(("Match" + images[i].name).c_str());
    // sleep(1);
    cvReleaseImage(&img);
}

images ここで使われている配列は、私のコードには存在しませんが、質問の便宜上、現在のプログラムの実行点からの相対的な画像のファイル名が含まれています。 name のメンバーです。私のプロジェクトでは、画像名を少し違った形で保存しています。

上記のコード ほとんど が動作します。しかし、最後の画像が表示され、キーが押されると、画像はグレーになり、アプリケーションの残りの部分をクラッシュさせずに画像ウィンドウを閉じることができません。

最初に考えたのは、コンパイル時の最適化が原因ではないかということでした。 cvReleaseImage が画像を解放する前に cvDestroyWindow が終了してしまい、なぜかフリーズしてしまいます。しかし、私はいくつかの待ち時間を追加してみました(そのため、コメントアウトされた sleep(1) という行がありますが、これは役に立ちませんでした。

私はコンソールアプリケーションからこの表示機能を呼び出していますが、画像がフリーズすると、コントロールは私のアプリケーションに戻り、私はそれを使い続けることができます(しかし、画像ウィンドウはバックグラウンドでフリーズしたままです)。

これを修正する方法について、何かご提案いただけますか?

EDIT

質問してから定期的にコンピュータビジョンやOpenCVを扱っている人に話を聞きましたが、まだアイデアが出ません。

また、同様の スタックオーバーフローの質問 しかし、まだ受理された回答はありません。ググっても似たような質問が出るだけで、回答はありません。

何か試すべきアイデアがあれば(完全な解決策でなくても)、とてもありがたいです。

解決方法は?

テスト用に 以下のアプリケーションは、あなたが質問で述べたことと全く同じことを行います。 : コマンドラインから7枚の画像を1枚ずつロードし、表示する画像ごとに新しいウィンドウを作成します。

LinuxのOpenCV 2.3.1では問題なく動作します。

#include <cv.h>
#include <highgui.h>

#define NUM_IMGS 7

int main(int argc, char* argv[])
{
    if (argc < 8)
    {
        printf("Usage: %s <img1> <img2> <img3> <img4> <img5> <img6> <img7>\n", argv[0]);
        return -1;
    }

    // Array to store pointers for the images
    IplImage* images[NUM_IMGS] = { 0 };

    for (int i = 0; i < NUM_IMGS; i++)
    {
        // load image
        images[i] = cvLoadImage(argv[i+1], CV_LOAD_IMAGE_UNCHANGED);
        if (!images[i])
        {
            printf("!!! failed to load: %s\n", argv[i+1]);
            continue;
        }

        // display image in a window
        cvNamedWindow(argv[i+1], CV_WINDOW_AUTOSIZE); // creating a new window each time
        cvShowImage(argv[i+1], images[i]);

        // wait for keypress
        cvWaitKey(0);

        // close the window
        cvDestroyWindow(argv[i+1]);
        cvReleaseImage(&images[i]);
    }

    return 0;
}