OpenCVを使った動画像処理の問題なのですが...

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

OpenCVを使った動画像処理の問題なのですが...

#1

投稿記事 by galaxyS9 » 14年前

初心者です.
openCV1.0を使って,
動画ファイル(数十秒程度)と画像1枚を用意し,
動画を背景差分を使って背景(動画中の動いていない
部分)と物体にわけ、背景に別の画像を貼り付ける仕様にしたいと考えてい
ます.
(例えばボクサーがパンチしている動画で動いているボクサーを切り抜いて,べ
つの草原の画像に貼りつけ,草原でパンチしている動画にする)

openCVの公式サイトのサンプルプログラムを拝見して以下のURLの動的背景更
新による物体検出を利用するまで至ったのですが,それ以降はわかっていません.


ここからは私事なのですが先週からインフルエンザで出席停
止であったため,課題ができる時間が取れなく,その上期限が木曜0時までといわれて,
このままでは課題提出は無理だと判断し,今はここで回答のみを聞いて提出して
からまた学び直そうと考えました.

よろしければ上の条件で動くプログラムを作成していただけないでしょうか.


作業環境:OpenCV Workspace.NET 2005,使用言語:C++
http://opencv.jp/sample/accumulation_of ... ground_sub

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: OpenCVを使った動画像処理の問題なのですが...

#2

投稿記事 by beatle » 14年前

お示しいただいたページのサンプルには

コード:

    // (12)物体領域のみを出力画像にコピーする(背景領域は黒)
    cvSetZero (dst_img);
    cvCopy (frame, dst_img, msk_img);
とありますね.
出力画像というのはdst_imgのことで,dst_imgをcvSetZeroによりゼロ初期化しているために,全部黒くなっているだけです.dst_imgにお好みの背景画像を入れておけば,希望することができるようになるはずです.

galaxyS9

Re: OpenCVを使った動画像処理の問題なのですが...

#3

投稿記事 by galaxyS9 » 14年前

beatle さんが書きました:お示しいただいたページのサンプルには

コード:

    // (12)物体領域のみを出力画像にコピーする(背景領域は黒)
    cvSetZero (dst_img);
    cvCopy (frame, dst_img, msk_img);
とありますね.
出力画像というのはdst_imgのことで,dst_imgをcvSetZeroによりゼロ初期化しているために,全部黒くなっているだけです.dst_imgにお好みの背景画像を入れておけば,希望することができるようになるはずです.
dst_imgを"lena.jpg"に変えたところ、ビルドは通ったものの、デバック時にcvSetZero ("lena.jpg");の行でエラーが起きていました。
ファイルはopenCV¥sample¥c¥にあるのに、正しくデバックされないのはなぜでしょうか。
この行以下のdst_imgも"lena.jpg"に変えたのですが、同じくcvSetZero ("lena.jpg");の行の時点でエラーが起きてしまいます。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: OpenCVを使った動画像処理の問題なのですが...

#4

投稿記事 by みけCAT » 14年前

dst_imgにファイル名そのものを入れるのではなく、ファイルを読み込んだ画像が入った変数を入れるのではないでしょうか?
想像ですが。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: OpenCVを使った動画像処理の問題なのですが...

#5

投稿記事 by beatle » 14年前

dst_imgはIplImage構造体へのポインタです.それを文字列に書き換えた所で正常に動くはずはありません.
「ビルドは通った」といっても,警告はでませんでしたか?「互換性のないポインタ」とかいう感じの.
(もし出たとしたら)警告を無視するのは良くないことです.

cvSetZeroに渡すのは,画像データを記録したIplImage構造体へのポインタです.そして,cvSetZeroはその画像データを全部0,つまり真っ黒にするという関数です.

cvLoadImage関数を使えば,画像ファイルからIplImageを作成できます.dst_imgには,元のサンプルコードではcvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 3);の戻り値を代入していますので,その代わりにcvLoadImage関数の戻り値を代入すればいいでしょう.

galaxyS9

Re: OpenCVを使った動画像処理の問題なのですが...

#6

投稿記事 by galaxyS9 » 14年前

beatle さんが書きました:dst_imgはIplImage構造体へのポインタです.それを文字列に書き換えた所で正常に動くはずはありません.
「ビルドは通った」といっても,警告はでませんでしたか?「互換性のないポインタ」とかいう感じの.
(もし出たとしたら)警告を無視するのは良くないことです.
ビルドには何もなく、ただ正常終了とだけ出ました。
以下のようにやってみたのですが、まだ動きません。
どこが間違っているかわかりません。

コード:


#include <cv.h>
#include <highgui.h>
#include <ctype.h>
#include <stdio.h>
#define snprintf _snprintf
#define CV_LOAD_IMAGE_UNCHANGED  -1
#define CV_LOAD_IMAGE_GRAYSCALE   0
#define CV_LOAD_IMAGE_COLOR       1
#define CV_LOAD_IMAGE_ANYDEPTH    2
#define CV_LOAD_IMAGE_ANYCOLOR    4


int main (int argc, char* argv[])
{  
	int i, c, counter;  
	int INIT_TIME = 100;  
	int w = 0, h = 0;  
	double B_PARAM = 1.0 / 50.0;  
	double T_PARAM = 1.0 / 200.0;  
	double Zeta = 10.0;  
	CvCapture *capture = 0;  
	IplImage *frame = 0;  
	IplImage *av_img, *sgm_img;  
	IplImage *lower_img, *upper_img, *tmp_img;  
	IplImage *msk_img;  
	IplImage* dst_img;//=cvLoadImage( "lena.jpg",  CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR );
	CvFont font;  
	char str[64];  

	// (1)コマンド引数によって指定された番号のカメラに対するキャプチャ構造体を作成する  
	if (argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit (argv[1][0])))    
		capture = cvCreateCameraCapture (argc == 2 ? argv[1][0] - '0' : 0);  
	// (2)1フレームキャプチャし,キャプチャサイズを取得する.  
	frame = cvQueryFrame (capture);
	w = frame->width;
	h = frame->height; 

	// (3)作業用の領域を生成する  
	av_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3);  
	sgm_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3);  
	tmp_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3);  
	lower_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3);  
	upper_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3);  
	dst_img = cvLoadImage( "lena.jpg",  CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR );
	msk_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 1);  
	// (4)背景の輝度平均の初期値を計算する  
	printf ("Background statistics initialization start\n");  
	cvSetZero (av_img);  
	for (i = 0; i < INIT_TIME; i++) {    
		frame = cvQueryFrame (capture);    
		cvAcc (frame, av_img);
	}  
	cvConvertScale (av_img, av_img, 1.0 / INIT_TIME); 
	// (5)背景の輝度振幅の初期値を計算する  
	cvSetZero (sgm_img);  
	for (i = 0; i < INIT_TIME; i++) {
		frame = cvQueryFrame (capture);
		cvConvert (frame, tmp_img); 
		cvSub (tmp_img, av_img, tmp_img);    
		cvPow (tmp_img, tmp_img, 2.0);
		cvConvertScale (tmp_img, tmp_img, 2.0);    
		cvPow (tmp_img, tmp_img, 0.5);
		cvAcc (tmp_img, sgm_img);
	}  
	cvConvertScale (sgm_img, sgm_img, 1.0 / INIT_TIME);
	printf ("Background statistics initialization finish\n");
	// (6)表示用ウィンドウを生成する  
	cvInitFont (&font, CV_FONT_HERSHEY_COMPLEX, 0.7, 0.7);
	cvNamedWindow ("Input", CV_WINDOW_AUTOSIZE);
	cvNamedWindow ("Substraction", CV_WINDOW_AUTOSIZE); 
	// (7)取得画像から背景を分離するループ
	counter = 0;
	while (1) {
		frame = cvQueryFrame (capture);
		cvConvert (frame, tmp_img);    

		// (8)背景となりうる画素の輝度値の範囲をチェックする
		cvSub (av_img, sgm_img, lower_img);
		cvSubS (lower_img, cvScalarAll (Zeta), lower_img);
		cvAdd (av_img, sgm_img, upper_img);
		cvAddS (upper_img, cvScalarAll (Zeta), upper_img);
		cvInRange (tmp_img, lower_img, upper_img, msk_img);    
		// (9)輝度振幅を再計算する   
		cvSub (tmp_img, av_img, tmp_img); 
		cvPow (tmp_img, tmp_img, 2.0);
		cvConvertScale (tmp_img, tmp_img, 2.0);
		cvPow (tmp_img, tmp_img, 0.5);
		// (10)背景と判断された領域の背景の輝度平均と輝度振幅を更新する
		cvRunningAvg (frame, av_img, B_PARAM, msk_img);
		cvRunningAvg (tmp_img, sgm_img, B_PARAM, msk_img);
		
		//cvSaveImage("vinci_result", image);
		//IplImage *image = cvLoadImage("Apple.jpg", CV_LOAD_IMAGE_ANYCOLOR);
		// (11)物体領域と判断された領域では輝度振幅のみを(背景領域よりも遅い速度で)更新する
		cvNot (msk_img, msk_img);
		cvRunningAvg (tmp_img, sgm_img, T_PARAM, msk_img);
		// (12)物体領域のみを出力画像にコピーする(背景領域は黒)
		cvSetZero (dst_img);    
		cvCopy (frame, dst_img, msk_img); 
		// (13)処理結果を表示する    
		snprintf (str, 64, "%03d[frame]", counter);
		cvPutText (dst_img, str, cvPoint (10, 20), &font, CV_RGB (0, 255, 100));
		cvShowImage ("Input", frame);    
		cvShowImage ("Substraction", dst_img);
		counter++;    
		c = cvWaitKey (10);
		if (c == '\x1b')
			break;
	}  
	cvDestroyWindow ("Input");
	cvDestroyWindow ("Substraction");
	cvReleaseImage (&frame);
	cvReleaseImage (&dst_img);
	cvReleaseImage (&av_img); 
	cvReleaseImage (&sgm_img);
	cvReleaseImage (&lower_img); 
	cvReleaseImage (&upper_img); 
	cvReleaseImage (&tmp_img); 
	cvReleaseImage (&msk_img); 
	return 0;
}



galaxyS9

Re: OpenCVを使った動画像処理の問題なのですが...

#7

投稿記事 by galaxyS9 » 14年前

デバックしたところ、95行目のcvSetZero (dst_img); がエラーの原因のようでした。
これ自体はサンプルのものと変わっていないのでその前のdst_imgの定義が間違っているということでしょうか。
締め切りは過ぎてしまいましたが、もしかしたら遅れて出しても出さないよりはましだと思うので、アドバイスお願いします。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: OpenCVを使った動画像処理の問題なのですが...

#8

投稿記事 by beatle » 14年前

95行目じゃなくて99行目のことでしょうか?95行目は
// (11)物体領域と判断された領域では輝度振幅のみを(背景領域よりも遅い速度で)更新する
です.

どのようなエラーが出るのか,エラーメッセージを貼りつけてもらわないと,こちらではエスパーで当てるしかありません.
というか,そもそもなんでcvSetZero(dst_img);をやろうとしているのでしょうか.
僕はNo.5で
beatle さんが書きました:cvSetZeroに渡すのは,画像データを記録したIplImage構造体へのポインタです.そして,cvSetZeroはその画像データを全部0,つまり真っ黒にするという関数です.
と書きました.せっかくlena.jpgの画像データを読み込んだのに0クリアしたいのですか?

どんなエラーが出ているのか知りませんが,lena.jpgはきちんと.exeと同じフォルダに入っているでしょうか.
例えばVisual C++ 2010でDebugモードで動かす場合は,
C:\Users\username\Documents\Visual Studio 2010\Projects\projectname\Debug\lena.jpg
C:\Users\username\Documents\Visual Studio 2010\Projects\projectname\Debug\projectname.exe
のような配置になっている必要があります.
lena.jpgが他の場所にあるなら,lena.jpgのフルパスをcvLoadImageに指定する必要があります.

cvLoadImage( "X:\\path\\to\\image\\lena.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR );
みたいにすれば大丈夫だと思います.実験はしていませんが.

galaxyS9

Re: OpenCVを使った動画像処理の問題なのですが...

#9

投稿記事 by galaxyS9 » 14年前

beatle さんが書きました:どのようなエラーが出るのか,エラーメッセージを貼りつけてもらわないと,こちらではエスパーで当てるしかありません.
エラーが出たといいますか、デバック時にしばらく何も反応がなく、何分かしたらデバックについて、中断or継続のウインドウが出てきます。
cvZeroのところを消したところそれは消えて、実行が行われたのですが、
(1)ウインドウが現れて、lena.jpgが表示される
(2)そのままデバックは止まり、そのウインドウを消すとデバックが再開され、今度はべつに、動的背景の更新による物体検出が実行され(cvZeroを消したため今回は背景は黒くならない)lenaは関与されませんでした。

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

Re: OpenCVを使った動画像処理の問題なのですが...

#10

投稿記事 by h2so5 » 14年前

galaxyS9 さんが書きました:動的背景の更新による物体検出が実行され(cvZeroを消したため今回は背景は黒くならない)lenaは関与されませんでした。
背景が黒くならずに、lenaは関与(?)していないなら
背景はどのような状態なのですか?

閉鎖

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