初心者です.
openCV1.0を使って,
動画ファイル(数十秒程度)と画像1枚を用意し,
動画を背景差分を使って背景(動画中の動いていない
部分)と物体にわけ、背景に別の画像を貼り付ける仕様にしたいと考えてい
ます.
(例えばボクサーがパンチしている動画で動いているボクサーを切り抜いて,べ
つの草原の画像に貼りつけ,草原でパンチしている動画にする)
openCVの公式サイトのサンプルプログラムを拝見して以下のURLの動的背景更
新による物体検出を利用するまで至ったのですが,それ以降はわかっていません.
ここからは私事なのですが先週からインフルエンザで出席停
止であったため,課題ができる時間が取れなく,その上期限が木曜0時までといわれて,
このままでは課題提出は無理だと判断し,今はここで回答のみを聞いて提出して
からまた学び直そうと考えました.
よろしければ上の条件で動くプログラムを作成していただけないでしょうか.
作業環境:OpenCV Workspace.NET 2005,使用言語:C++
http://opencv.jp/sample/accumulation_of ... ground_sub
OpenCVを使った動画像処理の問題なのですが...
-
galaxyS9
Re: OpenCVを使った動画像処理の問題なのですが...
dst_imgを"lena.jpg"に変えたところ、ビルドは通ったものの、デバック時にcvSetZero ("lena.jpg");の行でエラーが起きていました。
ファイルはopenCV¥sample¥c¥にあるのに、正しくデバックされないのはなぜでしょうか。
この行以下のdst_imgも"lena.jpg"に変えたのですが、同じくcvSetZero ("lena.jpg");の行の時点でエラーが起きてしまいます。
Re: OpenCVを使った動画像処理の問題なのですが...
dst_imgにファイル名そのものを入れるのではなく、ファイルを読み込んだ画像が入った変数を入れるのではないでしょうか?
想像ですが。
想像ですが。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: OpenCVを使った動画像処理の問題なのですが...
dst_imgはIplImage構造体へのポインタです.それを文字列に書き換えた所で正常に動くはずはありません.
「ビルドは通った」といっても,警告はでませんでしたか?「互換性のないポインタ」とかいう感じの.
(もし出たとしたら)警告を無視するのは良くないことです.
cvSetZeroに渡すのは,画像データを記録したIplImage構造体へのポインタです.そして,cvSetZeroはその画像データを全部0,つまり真っ黒にするという関数です.
cvLoadImage関数を使えば,画像ファイルからIplImageを作成できます.dst_imgには,元のサンプルコードではcvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 3);の戻り値を代入していますので,その代わりにcvLoadImage関数の戻り値を代入すればいいでしょう.
「ビルドは通った」といっても,警告はでませんでしたか?「互換性のないポインタ」とかいう感じの.
(もし出たとしたら)警告を無視するのは良くないことです.
cvSetZeroに渡すのは,画像データを記録したIplImage構造体へのポインタです.そして,cvSetZeroはその画像データを全部0,つまり真っ黒にするという関数です.
cvLoadImage関数を使えば,画像ファイルからIplImageを作成できます.dst_imgには,元のサンプルコードではcvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 3);の戻り値を代入していますので,その代わりにcvLoadImage関数の戻り値を代入すればいいでしょう.
-
galaxyS9
Re: OpenCVを使った動画像処理の問題なのですが...
ビルドには何もなく、ただ正常終了とだけ出ました。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を使った動画像処理の問題なのですが...
デバックしたところ、95行目のcvSetZero (dst_img); がエラーの原因のようでした。
これ自体はサンプルのものと変わっていないのでその前のdst_imgの定義が間違っているということでしょうか。
締め切りは過ぎてしまいましたが、もしかしたら遅れて出しても出さないよりはましだと思うので、アドバイスお願いします。
これ自体はサンプルのものと変わっていないのでその前のdst_imgの定義が間違っているということでしょうか。
締め切りは過ぎてしまいましたが、もしかしたら遅れて出しても出さないよりはましだと思うので、アドバイスお願いします。
Re: OpenCVを使った動画像処理の問題なのですが...
95行目じゃなくて99行目のことでしょうか?95行目は
// (11)物体領域と判断された領域では輝度振幅のみを(背景領域よりも遅い速度で)更新する
です.
どのようなエラーが出るのか,エラーメッセージを貼りつけてもらわないと,こちらではエスパーで当てるしかありません.
というか,そもそもなんでcvSetZero(dst_img);をやろうとしているのでしょうか.
僕はNo.5で
どんなエラーが出ているのか知りませんが,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 );
みたいにすれば大丈夫だと思います.実験はしていませんが.
// (11)物体領域と判断された領域では輝度振幅のみを(背景領域よりも遅い速度で)更新する
です.
どのようなエラーが出るのか,エラーメッセージを貼りつけてもらわないと,こちらではエスパーで当てるしかありません.
というか,そもそもなんでcvSetZero(dst_img);をやろうとしているのでしょうか.
僕はNo.5で
と書きました.せっかくlena.jpgの画像データを読み込んだのに0クリアしたいのですか?beatle さんが書きました:cvSetZeroに渡すのは,画像データを記録したIplImage構造体へのポインタです.そして,cvSetZeroはその画像データを全部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を使った動画像処理の問題なのですが...
エラーが出たといいますか、デバック時にしばらく何も反応がなく、何分かしたらデバックについて、中断or継続のウインドウが出てきます。beatle さんが書きました:どのようなエラーが出るのか,エラーメッセージを貼りつけてもらわないと,こちらではエスパーで当てるしかありません.
cvZeroのところを消したところそれは消えて、実行が行われたのですが、
(1)ウインドウが現れて、lena.jpgが表示される
(2)そのままデバックは止まり、そのウインドウを消すとデバックが再開され、今度はべつに、動的背景の更新による物体検出が実行され(cvZeroを消したため今回は背景は黒くならない)lenaは関与されませんでした。
Re: OpenCVを使った動画像処理の問題なのですが...
背景が黒くならずに、lenaは関与(?)していないならgalaxyS9 さんが書きました:動的背景の更新による物体検出が実行され(cvZeroを消したため今回は背景は黒くならない)lenaは関与されませんでした。
背景はどのような状態なのですか?