diff --git a/smoke/smoketest.js b/smoke/smoketest.js index d8ed244..8029faa 100755 --- a/smoke/smoketest.js +++ b/smoke/smoketest.js @@ -11,7 +11,7 @@ for (var i = 1; i< 41; i++){ cv.readImage("/Users/peterbraden/Downloads/orl_faces/s6/10.pgm", function(e, im){ var facerec = cv.FaceRecognizer.createFisherFaceRecognizer(); - facerec.train(trainingData); + facerec.trainSync(trainingData); console.log(facerec.predictSync(im)); diff --git a/src/FaceRecognizer.cc b/src/FaceRecognizer.cc index 4244b38..ac1fe83 100644 --- a/src/FaceRecognizer.cc +++ b/src/FaceRecognizer.cc @@ -5,6 +5,9 @@ #include "Matrix.h" +#define EIGEN 0 +#define LBPH 1 +#define FISHER 2 // Todo, move somewhere useful cv::Mat fromMatrixOrFilename(Local v){ @@ -39,7 +42,7 @@ FaceRecognizerWrap::Init(Handle target) { NODE_SET_METHOD(constructor, "createEigenFaceRecognizer", CreateEigen); NODE_SET_METHOD(constructor, "createFisherFaceRecognizer", CreateFisher); - NODE_SET_PROTOTYPE_METHOD(constructor, "train", Train); + NODE_SET_PROTOTYPE_METHOD(constructor, "trainSync", TrainSync); NODE_SET_PROTOTYPE_METHOD(constructor, "predictSync", PredictSync); @@ -55,7 +58,7 @@ FaceRecognizerWrap::New(const Arguments &args) { // By default initialize LBPH cv::Ptr f = cv::createLBPHFaceRecognizer(1, 8, 8, 8, 80.0); - FaceRecognizerWrap *pt = new FaceRecognizerWrap(f); + FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, LBPH); pt->Wrap(args.This()); return args.This(); @@ -82,7 +85,7 @@ FaceRecognizerWrap::CreateLBPH(const Arguments &args) { cv::Ptr f = cv::createLBPHFaceRecognizer( radius, neighbors, grid_x, grid_y, threshold ); - FaceRecognizerWrap *pt = new FaceRecognizerWrap(f); + FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, LBPH); pt->Wrap(n); return n; @@ -103,7 +106,7 @@ FaceRecognizerWrap::CreateEigen(const Arguments &args) { cv::Ptr f = cv::createEigenFaceRecognizer( components, threshold ); - FaceRecognizerWrap *pt = new FaceRecognizerWrap(f); + FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, EIGEN); pt->Wrap(n); return n; @@ -124,23 +127,21 @@ FaceRecognizerWrap::CreateFisher(const Arguments &args) { cv::Ptr f = cv::createFisherFaceRecognizer( components, threshold ); - FaceRecognizerWrap *pt = new FaceRecognizerWrap(f); + FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, FISHER); pt->Wrap(n); return n; } -FaceRecognizerWrap::FaceRecognizerWrap(cv::Ptr f){ - rec = f; +FaceRecognizerWrap::FaceRecognizerWrap(cv::Ptr f, int type){ + rec = f; + typ = type; } -Handle -FaceRecognizerWrap::Train(const Arguments& args){ - SETUP_FUNCTION(FaceRecognizerWrap) - cv::vector images; - cv::vector labels; +Handle UnwrapTrainingData(const Arguments& args, cv::vector* images, cv::vector* labels){ + if (args.Length() < 1 || !args[0]->IsArray()){ JSTHROW("FaceRecognizer.train takes a list of [ label, image] tuples") @@ -166,8 +167,22 @@ FaceRecognizerWrap::Train(const Arguments& args){ cv::Mat im = fromMatrixOrFilename(valarr->Get(1)); im = im.clone(); cv::cvtColor(im, im, CV_RGB2GRAY); - labels.push_back(label); - images.push_back(im); + labels->push_back(label); + images->push_back(im); + } + return v8::Undefined(); +} + +Handle +FaceRecognizerWrap::TrainSync(const Arguments& args){ + SETUP_FUNCTION(FaceRecognizerWrap) + + cv::vector images; + cv::vector labels; + + Handle exception = UnwrapTrainingData(args, &images, &labels); + if (!exception->IsUndefined()){ + return exception; } self->rec->train(images, labels); @@ -175,6 +190,32 @@ FaceRecognizerWrap::Train(const Arguments& args){ return scope.Close(v8::Undefined()); } +Handle +FaceRecognizerWrap::UpdateSync(const Arguments& args){ + SETUP_FUNCTION(FaceRecognizerWrap) + + + if (self->typ == EIGEN){ + JSTHROW("Eigen Recognizer does not support update") + } + if (self->typ == FISHER){ + JSTHROW("Fisher Recognizer does not support update") + } + + cv::vector images; + cv::vector labels; + + + Handle exception = UnwrapTrainingData(args, &images, &labels); + if (!exception->IsUndefined()){ + return exception; + } + + self->rec->update(images, labels); + + return scope.Close(v8::Undefined()); +} + Handle FaceRecognizerWrap::PredictSync(const Arguments& args){ @@ -194,4 +235,9 @@ FaceRecognizerWrap::PredictSync(const Arguments& args){ return scope.Close(res); } + + + + + #endif // End version > 2.4 diff --git a/src/FaceRecognizer.h b/src/FaceRecognizer.h index 8cc45f0..96b7974 100644 --- a/src/FaceRecognizer.h +++ b/src/FaceRecognizer.h @@ -7,21 +7,25 @@ class FaceRecognizerWrap: public node::ObjectWrap { public: cv::Ptr rec; + int typ; static Persistent constructor; static void Init(Handle target); static Handle New(const Arguments &args); - FaceRecognizerWrap(cv::Ptr f); + FaceRecognizerWrap(cv::Ptr f, int type); JSFUNC(CreateLBPH) JSFUNC(CreateEigen) JSFUNC(CreateFisher) - JSFUNC(Train) - JSFUNC(Update) + JSFUNC(TrainSync) + //JSFUNC(Train) + JSFUNC(UpdateSync) + //JSFUNC(Update) JSFUNC(PredictSync) + // JSFUNC(Predict) //static void EIO_Predict(eio_req *req); //static int EIO_AfterPredict(eio_req *req);