/////////////////////////////////////////
// Created by Jonash. 
// 
#include<iostream>
#include<cstdio>

#include"cv.h"
#include"cxcore.h"
#include"highgui.h"
#include"cvaux.h"

using namespace std;
#define M 24	//number of training samples
#define P 10	//number of PCA planes

void main()
{
	int k;
	char buf[80];
	CvTermCriteria	cri				= cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 0.05);
	IplImage		**objects		= new IplImage*[M];
	IplImage		**eigenObjects	= new IplImage*[M];
	float			*eigVals		= new float[M];
	IplImage		*avg;

	for(k = 0; k < M; k++)				
	{
		sprintf(buf, "./Yale/%d.bmp", k);	//load training samples
		cout<<buf<<endl;
		objects[k] = cvLoadImage(buf, 0);
	}

	CvSize size = cvGetSize(objects[0]);	//Assume all training samples with same resolution

	avg	= cvCreateImage(size, IPL_DEPTH_32F, 1);
	for(k = 0; k < M; k++)		eigenObjects[k] = cvCreateImage(size, IPL_DEPTH_32F, 1);
	
	//Calculate EigenFaces, and put in eigenObjects
	cvCalcEigenObjects(	M-1, objects, eigenObjects, 0,0,0, &cri, avg, eigVals);

	//Demonstrate using from 0 to 9 eigen faces
	for(k = 0; k < 10; k++)
	{
		IplImage	*newone = cvLoadImage("input3.bmp", 0);
		float		*coeffs = new float[k];
		IplImage	*out	= cvCreateImage(size, IPL_DEPTH_8U, 1);

		//compute coefficients
		cvEigenDecomposite(newone, k ,eigenObjects, 0,0, avg, coeffs);

		//image reconstruction
		cvEigenProjection( eigenObjects, k, 0, 0, coeffs, avg, out);

		sprintf(buf, "reconstruction/rest_%d.jpg", k);
		cvSaveImage(buf, out);
		cvReleaseImage(&out);
	}

	IplImage* out = cvCreateImage(size, IPL_DEPTH_8U, 1);
	cvCvtScale(avg, out, 1, 0);

	sprintf(buf, "AVG_Face.bmp");
	cvSaveImage(buf, out);
	cvReleaseImage(&out);

}
