画像処理(openCV)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たると

画像処理(openCV)

#1

投稿記事 by たると » 9年前

C言語初心者です。
カメラから取得した映像から1フレーム目と2フレーム目の差分の画像、1フレーム目と3フレーム目の差分の画像を取得するプログラムを書きました。
動作するのですが数分経つと「ハンドルされていない例外が発生しました:」とでてエラーがでます。
どうやら原因はメモリリークらしいのですがどう対処していいのかわかりません。
アドバイスお願いします。

コード:

 
#include <opencv2/opencv.hpp>                   // OpenCVヘッダ
#pragma comment(lib,"opencv_imgproc242d.lib")   // OpenCVライブラリ
#pragma comment(lib,"opencv_core242d.lib")      // OpenCVライブラリ
#pragma comment(lib,"opencv_highgui242d.lib")   // OpenCVライブラリ

int main(int argc, char* argv[])
{
	int key;
	CvCapture* capture;							//ビデオキャプチャ宣言
    IplImage *srcCur=NULL, *Noillum=NULL, *lt_1=NULL, *lt_2=NULL, *dst_1=NULL, *dst_2=NULL; // 画像リソース宣言
    cvNamedWindow("カメラ映像表示1");		    // 表示ウィンドウの作成
	cvNamedWindow("カメラ映像表示2");			// 表示ウィンドウの作成
    capture = cvCaptureFromCAM(0);				// 映像取得(カメラ映像)

    if(capture == NULL){                        // ファイルが読み込めない場合
        printf("映像が取得できません。\n");
        cvWaitKey(0);							// キー入力待機
        return -1;
    }

    srcCur=cvQueryFrame(capture);				// 取得
    dst_1=cvCloneImage(srcCur);
	dst_2=cvCloneImage(srcCur);
	while(1){									//映像が終了するまで繰り返す
			int gazo;
			for (gazo = 1;gazo<= 3; gazo++){            //3枚の画像を取得
				srcCur=cvQueryFrame(capture);
					if (gazo == 1){						
						Noillum=cvCloneImage(srcCur);   //1枚目の画像を取得
        					if(Noillum==NULL)
           						break;
					} else if (gazo == 2){
        				lt_1=cvCloneImage(srcCur);      //2枚目の画像を取得
        					if(lt_1==NULL)
           						break;
    				} else if (gazo == 3){
        				lt_2=cvCloneImage(srcCur);      //3枚目の画像を取得
        					if(lt_2==NULL)
           						break;
					}
			}
        cvSub(Noillum, lt_1, dst_1);             //1枚目と2枚目の差分
		cvShowImage("カメラ映像表示1", dst_1);   // 表示
        cvSub(Noillum, lt_2, dst_2);             //1枚目と3枚目の差分
		cvShowImage("カメラ映像表示2", dst_2);   // 表示
		key = cvWaitKey(33);					 // キー入力待機(33ms)
		if(key == 27) break;					 //ESCキーを押した時終了
	}


    cvDestroyWindow("カメラ映像表示1");          // 表示ウィンドウの破棄
	cvDestroyWindow("カメラ映像表示2");          // 表示ウィンドウの破棄
    cvReleaseCapture(&capture);                  // ビデオキャプチャの開放
    return 0;
}
 

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 画像処理(openCV)

#2

投稿記事 by h2so5 » 9年前

使い終わった画像をcvReleaseImageで解放してください。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 画像処理(openCV)

#3

投稿記事 by usao » 9年前

・あなたは作成した画像領域を全く破棄していません.
 → cvReleaseImage()について調べましょう.

・ループ内ですごい勢いで新しい画像領域を生成しています.
 →dst_1,dst_2は最初に必要サイズ確保してその領域を使いまわしていますよね.
  Noillum等もそういう感じにしてみてはいかがでしょう?


まとめると,

・全ての作業用画像領域は,dst_1,dst_2のように,最初(whileよりも前)に必要なサイズで生成しておく.
・ループ内でキャプチャ画像のクローンを作っている箇所は,cvCopy()に置き換える.
・ループを抜けたら 全ての作業用画像領域を cvReleaseImage()で破棄する.

という形に修正してみてはいかがでしょうか.

その他:
・Nuillum,lt_1,lt_2 を配列にすれば 27行目~ のあたりを楽に書けそうですね.
・cvSub() は,やりたいことに合っているのでしょうか? (cvAbsDiff()というのもありますが)

閉鎖

“C言語何でも質問掲示板” へ戻る