출처 : http://opencv.jp/sample/accumulation_of_background.html#background_sub
[code cpp] #include <cv.h>
#include <highgui.h>
#include <ctype.h>
#include <stdio.h> 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 *dst_img, *msk_img; 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 = cvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 3);
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); // (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;
}
[/code]
댓글
댓글 쓰기