//---------------------------------------------------------
// 概要      : 画像をセピア色にする
// File Name : sepia.cpp
// Library   : OpenCV for MS-Windows 1.0
//---------------------------------------------------------

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

#define	DEFAULT_H	22	//	H値を置き換える値
#define	DEFAULT_S	90	//	S値を置き換える値

int main( int argc, char **argv ){
	char windowNameSource[] = "Source";		//	元画像を表示するウィンドウの名前
	char windowNameSepia[] = "Sepia"; 		//	処理結果を表示するウィンドウの名前

	//	画像を読み込む	
	IplImage *sourceImage = cvLoadImage( "image/source.bmp", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR );

	if ( sourceImage == NULL ) {
		//	画像が見つからなかった場合
		printf( "画像が見つかりません\n" );
		return -1;
	}

	CvSize sizeOfImage = cvGetSize( sourceImage );

	//	画像を生成する
	IplImage *hsvImage = cvCreateImage( sizeOfImage, IPL_DEPTH_8U, 3 );			//	HSV画像用IplImage
	IplImage *hueImage = cvCreateImage( sizeOfImage, IPL_DEPTH_8U, 1);			//	色相(H)情報用IplImage
	IplImage *saturationImage = cvCreateImage( sizeOfImage, IPL_DEPTH_8U, 1);	//	彩度(S)情報用IplImage
	IplImage *valueImage = cvCreateImage( sizeOfImage, IPL_DEPTH_8U, 1);		//	明度(V)情報用IplImage

	IplImage *mergeImage = cvCreateImage( sizeOfImage, IPL_DEPTH_8U, 3 );		//	マージ用IplImage
	IplImage *destinationImage = cvCreateImage( sizeOfImage, IPL_DEPTH_8U, 3 );	//	結果出力用IplImage

	CvScalar valueH = cvScalar( DEFAULT_H );
	CvScalar valueS = cvScalar( DEFAULT_S );

	//	ウィンドウを生成する
	cvNamedWindow( windowNameSource, CV_WINDOW_AUTOSIZE );
	cvNamedWindow( windowNameSepia, CV_WINDOW_AUTOSIZE );

	//	BGRからHSVに変換する
	cvCvtColor( sourceImage, hsvImage, CV_BGR2HSV );

	//	HSV画像をH、S、V画像に分ける
	cvSplit( hsvImage, hueImage, saturationImage, valueImage, NULL ); 

	//	HとSの値を変更する
	cvSet( hueImage, valueH, NULL );
	cvSet( saturationImage, valueS, NULL );

	//	3チャンネルを結合
	cvMerge( hueImage, saturationImage, valueImage, NULL, mergeImage );

	//	HSVからBGRに変換する
	cvCvtColor( mergeImage, destinationImage, CV_HSV2BGR );

	//	画像を表示する
	cvShowImage( windowNameSource, sourceImage );
	cvShowImage( windowNameSepia, destinationImage );

	//	キー入力を待つ
	cvWaitKey( 0 );

	//	メモリを解放する
	cvReleaseImage( &sourceImage );
	cvReleaseImage( &hsvImage );
	cvReleaseImage( &hueImage );
	cvReleaseImage( &saturationImage );
	cvReleaseImage( &valueImage );
	cvReleaseImage( &mergeImage );
	cvReleaseImage( &destinationImage );
	//	ウィンドウを破棄する
	cvDestroyWindow( windowNameSource );
	cvDestroyWindow( windowNameSepia );

	return 0;
}
