Skip to content

Commit

Permalink
eigenfaces
Browse files Browse the repository at this point in the history
add option to display the eigenfaces, fisherfaces and training images
  • Loading branch information
stephanschulz committed Feb 15, 2015
1 parent 9d21312 commit 9bf2f6a
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 7 deletions.
123 changes: 123 additions & 0 deletions src/ofxFaceRecognizer.cpp
Expand Up @@ -70,6 +70,9 @@ void ofxFaceRecognizer::setup(int method_used, int _maxFaces, bool bAlreadySaved
}


if(methodId == 0 || methodId == 1) generateEigenFishFaces();


}

void ofxFaceRecognizer::update(ofImage _img){
Expand Down Expand Up @@ -144,6 +147,126 @@ void ofxFaceRecognizer::loadTrainingImages(string _folderName, int _maxFaces){

}

static Mat norm_0_255(InputArray _src) {
Mat src = _src.getMat();
// Create and return normalized image:
Mat dst;
switch(src.channels()) {
case 1:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
break;
case 3:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
}

void ofxFaceRecognizer::generateEigenFishFaces(){
int height = allTrainingMats[0].rows;

// Here is how to get the eigenvalues of this Eigenfaces model:
Mat eigenvalues = model->getMat("eigenvalues");
cout<<"eigenvalues.row "<<eigenvalues.rows<<endl;
cout<<"eigenvalues.cols "<<eigenvalues.cols<<endl;

// And we can do the same to display the Eigenvectors (read Eigenfaces):
Mat W = model->getMat("eigenvectors");
cout<<"W.row "<<W.rows<<endl;
cout<<"W.cols "<<W.cols<<endl;

// Get the sample mean from the training data
Mat mean = model->getMat("mean");
cout<<"mean.row "<<mean.rows<<endl;
cout<<"mean.cols "<<mean.cols<<endl;

// Display or save the first, at most 16 Fisherfaces:
cgrayscaleJET_array.clear();
cgrayscaleBONE_array.clear();

for (int a = 0; a < min(16, W.cols); a++) {
//for (int i = 0; i < 16; i++) {
string msg = format("Eigenvalue #%d = %.5f", a, eigenvalues.at<double>(a));
cout << msg << endl;
// get eigenvector #a
Mat ev = W.col(a).clone();
// Reshape to original size & normalize to [0...255] for imshow.
Mat grayscale = norm_0_255(ev.reshape(1, height));
// Show the image & apply a Bone colormap for better sensing.
Mat cgrayscale;
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);

// Display or save:
ofImage ti;
toOf(cgrayscale,ti);
cgrayscaleJET_array.push_back(ti);

applyColorMap(grayscale, cgrayscale, COLORMAP_BONE);
toOf(cgrayscale,ti);
cgrayscaleBONE_array.push_back(ti);

}


reconstruction_array.clear();
// Display or save the image reconstruction at some predefined steps:
if(methodId == 0){
for(int num_component = min(W.cols, 10); num_component < min(W.cols, 300); num_component+=15) {
Mat evs = Mat(W, Range::all(), Range(0, num_component));
Mat projection = subspaceProject(evs, mean, allTrainingMats[0].reshape(1,1));
Mat reconstruction = subspaceReconstruct(evs, mean, projection);
// Normalize the result:
reconstruction = norm_0_255(reconstruction.reshape(1, allTrainingMats[0].rows));

// Normalize the result:
reconstruction = norm_0_255(reconstruction.reshape(1, allTrainingMats[0].rows));
// Display or save:

ofImage ti;
toOf(reconstruction,ti);
//reconstruction_array[num_component] = ti;
reconstruction_array.push_back(ti);
}
}
if(methodId == 1){
for(int num_component = 0; num_component < min(16, W.cols); num_component++) {
// Slice the Fisherface from the model:
Mat ev = W.col(num_component);
Mat projection = subspaceProject(ev, mean, allTrainingMats[0].reshape(1,1));
Mat reconstruction = subspaceReconstruct(ev, mean, projection);

// Normalize the result:
reconstruction = norm_0_255(reconstruction.reshape(1, allTrainingMats[0].rows));

// Display or save:
ofImage ti;
toOf(reconstruction,ti);
reconstruction_array.push_back(ti);
}
}

}

int ofxFaceRecognizer::getEigenfaceSize(){
return cgrayscaleJET_array.size();
}
int ofxFaceRecognizer::getReconstructionSize(){
return reconstruction_array.size();
}
void ofxFaceRecognizer::drawEigefaceJET(int _id, float _x, float _y, float _w, float _h){
cgrayscaleJET_array[_id].draw(_x, _y, _w, _h);
}
void ofxFaceRecognizer::drawEigenfaceBONE(int _id, float _x, float _y, float _w, float _h){
cgrayscaleBONE_array[_id].draw(_x, _y, _w, _h);
}

void ofxFaceRecognizer::drawReconstructionImage(int _id, float _x, float _y, float _w, float _h){
reconstruction_array[_id].draw(_x, _y, _w, _h);
}

int ofxFaceRecognizer::getPrediction(){
return prediction;
}
Expand Down
20 changes: 13 additions & 7 deletions src/ofxFaceRecognizer.h
Expand Up @@ -40,20 +40,21 @@ class ofxFaceRecognizer {
int getMethodId();
string getMethodName();

void generateEigenFishFaces();
void drawEigefaceJET(int _id, float _x, float _y, float _w, float _h);
void drawEigenfaceBONE(int _id, float _x, float _y, float _w, float _h);
void drawReconstructionImage(int _id, float _x, float _y, float _w, float _h);
int getEigenfaceSize();
int getReconstructionSize();

vector<int> allTrainingLabels;
protected:

int databaseImage_width,databaseImage_height;
Ptr<FaceRecognizer> model;

int maxFaces;

/*
int method_used;
int maxFaces;
bool bAlreadySavedModel;
string folderName;
*/


vector<ofImage> allTrainingImages;
vector<ofImage> oneImagePerPerson;
Expand All @@ -70,4 +71,9 @@ class ofxFaceRecognizer {
string methodName;
int methodId;

vector<ofImage>cgrayscaleJET_array;
vector<ofImage>cgrayscaleBONE_array;
vector<ofImage>reconstruction_array;


};

0 comments on commit 9bf2f6a

Please sign in to comment.