//---------------------------------------------------------
// 概要      : 背景差分をとる
// File Name : tutorial_02.cpp
// Library   : OpenCV for MS-Windows 1.0
//---------------------------------------------------------

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

#define WIDTH	640	//	キャプチャ画像の横幅
#define HEIGHT	480	//	キャプチャ画像の縦幅

int main( int argc, char **argv ) { 
	int key;							//	キー入力用の変数
	CvCapture *capture = NULL;			//	カメラキャプチャ用の構造体
	IplImage *frameImage;				//	キャプチャ画像用IplImage
	
	//	画像を生成する
	IplImage *backgroundImage = cvCreateImage( cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1 );	//	背景画像用IplImage
	IplImage *grayImage = cvCreateImage( cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1 );		//	グレースケール画像用IplImage
	IplImage *differenceImage = cvCreateImage( cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1 );	//	差分画像用IplImage
	
	char windowNameCapture[] = "Capture"; 			//	キャプチャした画像を表示するウィンドウの名前
	char windowNameDifference[] = "Difference";		//	背景差分結果を表示するウィンドウの名前
    
	//	カメラを初期化する
	if ( ( capture = cvCreateCameraCapture( -1 ) ) == NULL ) {
		//	カメラが見つからなかった場合
		printf( "カメラが見つかりません\n" );
		return -1;
	}

	//	ウィンドウを生成する
	cvNamedWindow( windowNameCapture, CV_WINDOW_AUTOSIZE );
	cvNamedWindow( windowNameDifference, CV_WINDOW_AUTOSIZE );
    
	//	初期背景を設定するためにカメラから画像取得
	frameImage = cvQueryFrame( capture );
	//	frameImageをグレースケール化し、背景画像とする
	cvCvtColor( frameImage, backgroundImage, CV_BGR2GRAY );
    
	//	メインループ
	while ( 1 ) {
		//	captureの入力画像1フレームをframeImageに格納する
		frameImage = cvQueryFrame( capture );
		//	frameImageをグレースケール化したものを、grayImageに格納する
		cvCvtColor( frameImage, grayImage, CV_BGR2GRAY );
		//	grayImageと背景画像との差分をとる
		cvAbsDiff( grayImage, backgroundImage, differenceImage );

		if ( differenceImage->origin == 0 ) {
			//　左上が原点の場合
			cvFlip( differenceImage, differenceImage, 0 );
		}

		//	画像を表示する
		cvShowImage( windowNameCapture, frameImage );
		cvShowImage( windowNameDifference, differenceImage );

		//	キー入力判定
		key = cvWaitKey( 1 );
		if ( key == 'q' ) {
			//	'q'キーが押されたらループを抜ける
			break;
		} else if ( key == 'b' ) {
			//	'b'キーが押されたら、その時点でのキャプチャ画像を背景画像とする
		    frameImage = cvQueryFrame( capture );
		    cvCvtColor( frameImage, backgroundImage, CV_BGR2GRAY );
		}
	}

	//	キャプチャを解放する
	cvReleaseCapture( &capture );
	//	メモリを解放する
	cvReleaseImage( &backgroundImage );
	cvReleaseImage( &grayImage );
	cvReleaseImage( &differenceImage );
	//	ウィンドウを破棄する
	cvDestroyWindow( windowNameCapture );
	cvDestroyWindow( windowNameDifference );

	return 0;
}