platform: Ubuntu 12.04 LTS 64bit OpenCV version: 2.4.2 I am trying to make a program that captures face (say user 1) using haarcascade.I then run the crop the face are of image and add it to a vector<mat>.I then add diff faces(say user 2) using the same method to the same vector. But I add different labels (say 0 and 1) for the 2 different cases. After some kind of keyboard interrupt,I train the FaceRecognizer using train() with both the vector (Mat and int). From the next frame onwards I take the face area and try to predict the label.
The code is compiling and running fine.But the outputs are a little irritating. It always outputs the same label( on more inspection I found, the label that I "push_back" for the very first frame) and the confidence is always 0.
What I am basically trying to achieve is a kind of online learning FaceRecognizer. But Since the predicted labels are not correct,I assume I have done something wrong. Is online learning even possible with PCA/LDA/LBPH?? I have tried using the same model as well as saving and opening with another model. Below is my code.Am I doing something wrong??Any help will be much appreciated!!! Thanks
#include <opencv/highgui.h>
include <opencv cv.h="">
include <opencv2 contrib="" contrib.hpp="">
include "opencv2/objdetect/objdetect.hpp"
include <iostream>
using namespace cv; using namespace std; vector< Rect_<int> > faces;
vector<cv::mat> learnt_face; vector<int> learnt_label;
bool pred = false; bool pos_ex = false;
int main(int argc,char* argv[]) { cv::CascadeClassifier haar_cascade;
Ptr<cv::FaceRecognizer> model = cv::createEigenFaceRecognizer(0,140.0);
Ptr<cv::FaceRecognizer> model0 = cv::createEigenFaceRecognizer(0,140.0);
string fn_haar = string("haarcascade_frontalface_alt.xml");
haar_cascade.load(fn_haar);
VideoCapture cap(0);
Mat img,gray_img,crop_face,crop_face_res;
for(;;)
{
cap>>img;
cv::cvtColor(img,gray_img,CV_RGB2GRAY);
haar_cascade.detectMultiScale(gray_img, faces);
Rect face_i = faces[0]; //Take only one face at a time * For debugging Purposes
//Crop and Resize
crop_face = gray_img(face_i);
cv::resize(crop_face, crop_face_res, Size(100,100), 1.0, 1.0, INTER_CUBIC);
if((!crop_face.empty()) && pred == false && pos_ex == true ) //If cropped,not predicting and learning positive images
{
cout<<"Learning"<<endl;
learnt_face.push_back(crop_face_res);
learnt_label.push_back(0);
if(learnt_face.size() >= 100)
{
learnt_face.erase( learnt_face.begin());
learnt_label.erase( learnt_label.begin());
}
rectangle(img, face_i, CV_RGB(0, 255,0), 1); //Green Faces label 0.
model->train(learnt_face,learnt_label);
}
//If cropped,not predicting and learning negetive images
else if((!crop_face.empty()) && pred == false && pos_ex == false )
{
cout<<"Learning"<<endl;
learnt_face.push_back(crop_face_res);
learnt_label.push_back(1);
if(learnt_face.size() >= 100)
{
learnt_face.erase( learnt_face.begin());
learnt_label.erase( learnt_label.begin());
}
rectangle(img, face_i, CV_RGB(255, 0,0), 1); //Red faces label 1.
model->train(learnt_face,learnt_label);
}
//If cropped and predicting
else if((!crop_face.empty()) && pred == true)
{
//model->save("model.xml");
//model0->load("model.xml");
cout<<"Predicting"<<endl;
int prediction = -1;
double predicted_confidence = 0.0;
cout<<model->getDouble("threshold")<<endl;
model->predict(crop_face_res,prediction,predicted_confidence);
rectangle(img, face_i, CV_RGB(0, 0,255), 1);
string box_text = format("Prediction = %d Confidence = %f", prediction,predicted_confidence);
int pos_x = std::max(face_i.tl().x - 10, 0);
int pos_y = std::max(face_i.tl().y - 10, 0);
putText(img, box_text, Point(pos_x, pos_y), FONT_HERSHEY_PLAIN, 1.0, CV_RGB(0,255,0), 2.0);
}
imshow("LEARN",img);
char esc = cv::waitKey(33);
if( esc == 27) break;
if( esc == 48) pos_ex = !pos_ex;
if ( esc == 32) pred = !pred;
}
std::cout<<learnt_face.size();
cap.release();
}