Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

facerecognition using fisherfaces

Hello.. Iam trying to recognize face using fisherfaces, am using opencv 3.2.0 on ubuntu 16.04.I want to recognize face through web cam and also from image file path. But am unable to get the output. Any help would be appreciated. Thanks in advance..

Sample.cpp

#include "lda_mine.h"
#include "unistd.h"

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 SetLabelInfo( Ptr<BasicFaceRecognizer> model, int Id, string name)
{
model->setLabelInfo(Id,name);
cout << model->getLabelInfo(Id);
return;
} 

void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator ) 
 {
    std::ifstream file(filename.c_str(), ifstream::in);
    if (!file) 
       {
        string error_message = "No valid input file was given, please check the given filename.";
        CV_Error(Error::StsBadArg, error_message);
       }
    string line, path, classlabel;
    while (getline(file, line)) 
      {
        stringstream liness(line);
        getline(liness, path, separator);
        getline(liness, classlabel);
        if(!path.empty() && !classlabel.empty()) 
          {
        Mat I = imread(path, 0);
            images.push_back(I);
            labels.push_back(atoi(classlabel.c_str()));  
         char* db = getenv("ENHANCE_DB");
        if(db && strcmp(db,"1") == 0)
        {
        Mat flip;
        cv::flip(I,flip,1);
        images.push_back(flip);
        labels.push_back(atoi(classlabel.c_str()));
        if(0)
        {
            int x,y;
            x = flip.rows;
            y = flip.cols;
            Point2f p (x/2,y/2);
            Mat A = I(Range(0,x-1),Range(0,y/2)); 
            Mat B = flip(Range(0,x-1),Range(y/2+1,y)); 
            Mat C = Mat::zeros(x,y,I.type());
            cv::hconcat(A, B, C);

            images.push_back(C);
            labels.push_back(atoi(classlabel.c_str()));
            A = I(Range(0,x-1),Range(y/2+1,y)); 
            B = flip(Range(0,x-1),Range(0,y/2)); 
            C = Mat::zeros(x,y,I.type());
            cv::hconcat(A, B, C);

            images.push_back(C);
            labels.push_back(atoi(classlabel.c_str()));
        }
     }  
        }
      } 
 } 
// int main(int argc, const char *argv[]) 
Ptr<BasicFaceRecognizer> lda_train(int argc, const char *argv[])
 {

      Mat image;
 if (argc != 3) {
        cout << "usage: " << argv[0] << " -train" <<  " <train.csv> " << endl;
        exit(1);
}   
      string output_folder = ".";
    if (argc == 3) {
        output_folder = string(argv[2]);
  }  
  string fn_csv = string(argv[2]);

  vector<Mat> images;
  vector<int> labels;

  try{
    read_csv(fn_csv,images,labels,';');
    }
   catch (cv::Exception& e) {
        cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
        exit(1);
  }


  if(images.size()<=1)
  {
  string error_message="This demo needs atleast 2 images.";
  CV_Error(Error::StsError, error_message);
  }

  int height= images[0].rows;

    Mat testSample = image;
    int testLabel = 1;
    //images.pop_back();
   // labels.pop_back();



Ptr<BasicFaceRecognizer>model = createFisherFaceRecognizer(num_components, threshold);
   if(access("train_csv.xml", F_OK ) != -1 )
 {
  model->load("train_csv.xml");
//  model->update(images,labels);
}
 else
  { 
    model->train(images,labels);
/*  int predicted = model->predict(testSample);
    int predictedLabel = -1;
    double confidence = 0.0;
    model->predict(testSample,predictedLabel,confidence);
*/ 
    Mat eigenvalues = model->getEigenValues();
    Mat vec = model->getEigenVectors(); 
    Mat mean = model->getMean();
    if(argc==2)
    {
     imshow("mean",norm_0_255(mean.reshape(1,images[0].rows)));
    }
     else
     {
      imwrite(format("%s/mean.png", output_folder.c_str()), mean.reshape(1, images[0].rows));
     }

    for(int i=0;i<min(300, vec.cols);i++)
    {
     String msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
     cout<<msg<<endl;
     Mat ev = vec.col(i).clone();


    Mat grayscale = norm_0_255(ev.reshape(1,height)); 
    Mat cgrayscale;
    applyColorMap(grayscale, cgrayscale, COLORMAP_BONE);

/*    if(argc==2)
    {
     imshow(format("fisherface_%d", i), cgrayscale);

    }
     else
     {
      imwrite(format("%s/fisherface.png", output_folder.c_str(),i), cgrayscale);
     }
*/
    }

    for(int num_component = 0; num_component < min(300, vec.cols); num_component++) 
     {

     Mat ev = vec.col(num_component);
     Mat projection = LDA::subspaceProject(ev, mean, images[0].reshape(1,1));
     Mat reconstruction = LDA::subspaceReconstruct(ev, mean, projection);
    // Normalize the result:
     reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows));
    // Display or save:
    if(argc == 2) 
      {
         imshow(format("fisherface_reconstruction_%d", num_component), reconstruction);
      } 
     else 
      {
        imwrite(format("%s/fisherface_reconstruction_%d.png", output_folder.c_str(), num_component), reconstruction);
      }

    }
}   

    char* disp = getenv("DISP");
    if(disp && strcmp(disp,"1") == 0)
    cout << "Image is : " << images[0] << endl; 
    model->save("train_csv.xml");    
    return model;


} 

 int lda_classify(Mat testSample, Ptr<BasicFaceRecognizer>model)
 {
  int predictedLabel = -1;
  double confidence = 0.0;
  model->predict(testSample, predictedLabel, confidence);
  char* disp = getenv("DISP");
  if(disp && strcmp(disp,"1") == 0)
  cout << "Test Image: " << testSample << endl;
  Mat eigenvalues = model->getEigenValues();
  Mat vec = model->getEigenVectors();     
  Mat mean = model->getMean();
  string output_folder = ".";
  for(int i=0;i<min(5, vec.cols);i++)
    {
     String msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
     cout<<msg<<endl;                  
     disp = getenv("DISP");
     if(disp && strcmp(disp,"1") == 0)
//  cout<<"Eigenvalue is:"<<endl; 
   String msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
    cout<<msg<<endl;


     if ( confidence > threshold)
     return -1;
     return predictedLabel;

    }
return 0;

  } 



                     **sampledetect.cpp**

#include "lda_mine.h"
#include "unistd.h"



void  detectAndDisplay( Mat frame,Ptr<BasicFaceRecognizer> model, int update,int Id );
String face_cascade_name = "/home/veena/Downloads/opencv-3.2.0/data/lbpcascades/lbpcascade_frontalface.xml";
CascadeClassifier face_cascade;
String window_name = "Capture - Face detection";



int lda_detect(Ptr<BasicFaceRecognizer> model,const char* fn_csv, int update, int Id)
{
    VideoCapture capture;
    Mat frame;

    //-- 1. Load the cascade
    if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face cascade\n"); return -1; };
    //if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading eyes cascade\n"); return -1; };

    //-- 2. Read the video stream
    if (strcmp(fn_csv,"video") == 0)
    { 
    capture.open(0);
    if ( ! capture.isOpened() ) { printf("--(!)Error opening video capture\n"); return -1; }
        if (access( "train_vid.xml", F_OK ) != -1 )
            model->load("train_vid.xml");   
        while ( capture.read(frame) )
        {
            if( frame.empty() )
            {
                printf(" --(!) No captured frame -- Break!");
                break;
            }

            //-- 3. Apply the classifier to the frame
            detectAndDisplay( frame, model, update,Id);

            //-- bail out if escape was pressed
            int c = waitKey(10);
            if( (char)c == 27 ) { break; }
        }

    return 0;
    }
else
{

//frame = imread("/home/veena/Desktop/9.pgm",CV_LOAD_IMAGE_COLOR);
//Mat image;
vector<Mat>images;
vector<int>labels;
try{
    String s = fn_csv;
// frame = imread("/home/veena/Desktop/9.pgm",CV_LOAD_IMAGE_COLOR);
read_csv(s, images,  labels,';');
// detectAndDisplay(frame,model,update,Id);

}
catch(cv::Exception& e)
{
cerr<<"Error opening file\""<<fn_csv<<"\".reason:"<<e.msg<<endl;
exit(1);
 }

// frame = imread("/home/veena/Desktop/9.pgm",CV_LOAD_IMAGE_COLOR);
waitKey(10);
return 0; 
}

}

void detectAndDisplay( Mat frame, Ptr<BasicFaceRecognizer> model, int update,int Id )
{
vector<Mat>newimages;
vector<int>newlabels;
Mat frame_gray;

std::vector<Rect>faces;
cvtColor(frame,frame_gray,COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
face_cascade.detectMultiScale(frame_gray, faces, 1.05,2,0|CV_HAAR_SCALE_IMAGE, Size(80,80));    
for(size_t i=0;i<faces.size();i++)
{
Mat faceROI = frame_gray(faces[i]);
if(update == 1)
{
// vector<Mat> images;
//vector<int> labels;
newimages.push_back(faceROI);
newlabels.push_back(Id);
rectangle(frame,faces[i], Scalar(0,255,0));
}
else
{
int predictedLabel = lda_classify(faceROI, model);
rectangle(frame, faces[i],Scalar(0,255,0));
String s = model->getLabelInfo(predictedLabel);
std::string str = s.operator std::string();
string box_text = format("ID = %d and Name: %s", predictedLabel, str.c_str());
int pos_x = std::max(faces[i].x - 10, 0);
int pos_y = std::max(faces[i].y - 10, 0);
putText(frame, box_text, Point(pos_x, pos_y), FONT_HERSHEY_PLAIN, 1.0, CV_RGB(0,0,255), 2.0);
}

imshow(window_name, frame);
}
if(update == 1)
{
model->update(newimages,newlabels);
model->save("train_csv.xml");

}


}



     **Main.cpp**

#include "lda_mine.h"
#include <cstdio>
#include <ctime>
#include <chrono>

int main(int argc, const char *argv[])
{
std::clock_t startcputime = std::clock();
int status;
for (int i = 1; i < argc; ++i) 
{
    cout << argv[i] << endl;
}
Ptr<BasicFaceRecognizer> model ; 
if ((argc > 1) && strcmp(argv[1],"-update") == 0 )
{
        int Id = 0;
        cout << "Enter  Unique ID: " ;
        cin >> Id; 
        string name;
        cout << "Enter  Name: " ;
        cin >> name; 
        std::ofstream fs;
        fs.open ("id_name.txt", ios::app);
        fs << Id << ":" << name << endl;
        fs.close();
        model = createFisherFaceRecognizer(num_components, threshold);
        SetLabelInfo(model,Id,name);
        status = lda_detect(model,argv[2],1,Id);

}
else if ((argc > 1) && strcmp(argv[1],"-train") == 0 )
{
    model =  lda_train(argc, argv);
}
else if((argc > 1) && strcmp(argv[1], "-test") == 0 )
{
    model = createFisherFaceRecognizer(num_components, threshold);
    status = lda_detect(model,argv[2],0,-1);
    return status;
}
else
{
    cout << "Help for Face Recognition Application: " << endl;
    cout << "For New Face Training : ./FaceRecognition -update video" << endl; 
    cout << "For Training : ./FaceRecognition -train <train.csv>" << endl; 
    cout << "For RealTime Video Testing: ./FaceRecognition -test video" << endl; 
    cout << "For Image Testing: ./FaceRecognition -test <test.csv>" << endl;
    return 0; 

}
double cpu_duration = (std::clock() - startcputime) / (double)CLOCKS_PER_SEC;
std::cout << "Finished in " << cpu_duration << " seconds [CPU Clock] " << std::endl;
return 0;
}


 **lda_mine.h**


#ifndef LBP_MINE_FILE_H
#define LBP_MINE_FILE_H 1

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/face.hpp"



#include <iostream>
#include <stdio.h>
#include <fstream>
#include <sstream>

using namespace cv;
using namespace cv::face;
using namespace std;    
#define num_components 0
#define threshold 100.0


int lda_detect(Ptr<BasicFaceRecognizer> model, const char* fn_csv, int update, int Id);
Ptr<BasicFaceRecognizer> lda_train(int argc, const char *argv[]);
int lda_classify (Mat testSample,Ptr<BasicFaceRecognizer> model );

void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator ); 

void SetLabelInfo( Ptr<BasicFaceRecognizer> model);
void SetLabelInfo( Ptr<BasicFaceRecognizer> model,int Id, string name);


#endif