move callbacks to FaceDetection::Start method

parent 4cc3491b
var d=require("./build/Release/face-detection.node"); var d=require("./build/Release/face-detection.node");
d.setWorkingDir(__dirname); d.setWorkingDir(__dirname);
console.log('set wd');
module.exports=d; module.exports=d;
\ No newline at end of file
...@@ -30,19 +30,24 @@ using namespace cv; ...@@ -30,19 +30,24 @@ using namespace cv;
using namespace ppf_match_3d; using namespace ppf_match_3d;
using namespace FaceDetection; using namespace FaceDetection;
string filename;
String face_cascade_name = ""; String face_cascade_name = "";
String eyes_cascade_name = ""; String eyes_cascade_name = "";
cv::CascadeClassifier face_cascade; cv::CascadeClassifier face_cascade;
cv::CascadeClassifier eyes_cascade; cv::CascadeClassifier eyes_cascade;
std::function<void(cv::Mat)> *faceFrameReadyCallback; std::function<void(cv::Mat)> *faceFrameReadyCallback;
std::function<void(std::string)> *faceSaveCallback;
std::function<void(std::string, int)> *faceCheckCallback;
FaceDetection::Mode currentMode;
FaceDetection::Mode newMode; FaceDetection::Mode newMode;
bool started=false;
struct facePosition {int x, y, width, height; }; struct facePosition {int x, y, width, height; };
int Loop(string filename); int Loop();
void FaceDetector::Init(string wd) void FaceDetector::Init(string wd)
{ {
...@@ -50,30 +55,46 @@ void FaceDetector::Init(string wd) ...@@ -50,30 +55,46 @@ void FaceDetector::Init(string wd)
eyes_cascade_name = wd + "/haarcascade_eye_tree_eyeglasses.xml"; eyes_cascade_name = wd + "/haarcascade_eye_tree_eyeglasses.xml";
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return; }; if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return; };
printf("init\n");
} }
///
/// \param faceCallback
void FaceDetector::Start(
std::function<void(cv::Mat)>&& faceCallback,
std::function<void(std::string)>&& saveCallback,
std::function<void(std::string, int)>&& checkCallback)
{
newMode = IDLE;
faceSaveCallback = &saveCallback;
faceCheckCallback = &checkCallback;
void FaceDetector::Start(std::function<void(cv::Mat)>&& faceCallback) { faceFrameReadyCallback = &faceCallback;
started = true;
Loop();
}
currentMode=IDLE; ///
newMode=IDLE; ///
faceFrameReadyCallback=&faceCallback; void FaceDetector::Stop() {
Loop(""); started=false;
} }
/// ///
/// \param filename /// \param filename
void FaceDetector::SaveFace(string filename) void FaceDetector::SaveFace(string file)
{ {
Loop(filename); filename = file;
newMode = TRAIN;
} }
/// ///
/// \param filename /// \param filename
int FaceDetector::CheckFace(string filename) void FaceDetector::CheckFace(string file)
{ {
int res=Loop(filename); filename = file;
return res; newMode = RECOGNIZE;
} }
...@@ -103,14 +124,13 @@ bool detectAndDisplay( Mat frame, facePosition &facePos ) { ...@@ -103,14 +124,13 @@ bool detectAndDisplay( Mat frame, facePosition &facePos ) {
return false; return false;
} }
int Loop(string filename) int Loop()
{ {
try try
{ {
currentMode=IDLE; newMode = IDLE;
newMode=IDLE;
ppf_match_3d::PPF3DDetector detector(1.0 / 4.0,0.05, 20); ppf_match_3d::PPF3DDetector detector(1.0 / 4.0, 0.05, 20);
rs::context ctx; rs::context ctx;
if (ctx.get_device_count() == 0) throw std::runtime_error("No device detected. Is it plugged in?"); if (ctx.get_device_count() == 0) throw std::runtime_error("No device detected. Is it plugged in?");
...@@ -118,20 +138,13 @@ int Loop(string filename) ...@@ -118,20 +138,13 @@ int Loop(string filename)
device->enable_stream(rs::stream::depth, 640, 480, rs::format::z16, 30);//rs::preset::best_quality); device->enable_stream(rs::stream::depth, 640, 480, rs::format::z16, 30);//rs::preset::best_quality);
device->enable_stream(rs::stream::color, 640, 480, rs::format::rgb8, 30);//rs::preset::best_quality); device->enable_stream(rs::stream::color, 640, 480, rs::format::rgb8, 30);//rs::preset::best_quality);
device->enable_stream(rs::stream::infrared, 640, 480, rs::format::y16, 30);//rs::preset::best_quality); device->enable_stream(rs::stream::infrared, 640, 480, rs::format::y16, 30);//rs::preset::best_quality);
device->start(); device->start();
int trainClock = 0; int trainClock = 0;
bool looping = true; while (started)
while (looping)
{ {
currentMode=newMode; FaceDetection::Mode currentMode = newMode;
if (device->is_streaming()) if (device->is_streaming())
device->wait_for_frames(); device->wait_for_frames();
...@@ -148,12 +161,10 @@ int Loop(string filename) ...@@ -148,12 +161,10 @@ int Loop(string filename)
rs::intrinsics color_intrin = device->get_stream_intrinsics(rs::stream::color); rs::intrinsics color_intrin = device->get_stream_intrinsics(rs::stream::color);
float scale = (device->get_depth_scale()); float scale = (device->get_depth_scale());
bool faceDetected = false; bool faceDetected = false;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
facePosition facePos; facePosition facePos;
if (trainClock % 3 == 0) if (trainClock % 5 == 0)
{ {
cv::Mat frame(color_intrin.height, color_intrin.width, CV_8UC3, (uchar *) color_image); cv::Mat frame(color_intrin.height, color_intrin.width, CV_8UC3, (uchar *) color_image);
if (detectAndDisplay(frame, facePos)) if (detectAndDisplay(frame, facePos))
...@@ -192,8 +203,8 @@ int Loop(string filename) ...@@ -192,8 +203,8 @@ int Loop(string filename)
float a = cx - (facePos.x + facePos.width / 2); float a = cx - (facePos.x + facePos.width / 2);
float b = cy - (facePos.y + facePos.height / 2); float b = cy - (facePos.y + facePos.height / 2);
float ry = (facePos.height / 2) * 1.0f; float ry = (facePos.height / 2) * 0.9f;
float rx = (facePos.width / 2) * 0.8f; float rx = (facePos.width / 2) * 0.7f;
bool insideEllipse = ((a * a) / (rx * rx) + (b * b) / (ry * ry)) <= 1; bool insideEllipse = ((a * a) / (rx * rx) + (b * b) / (ry * ry)) <= 1;
...@@ -231,11 +242,23 @@ int Loop(string filename) ...@@ -231,11 +242,23 @@ int Loop(string filename)
switch (currentMode) switch (currentMode)
{ {
case IDLE: case IDLE:
printf("idle"); //printf("idle");
break; break;
case TRAIN: case TRAIN:
{
writePLY(model, filename.c_str()); writePLY(model, filename.c_str());
looping = false; printf("train switch, filename: %s\n",filename.c_str());
(*faceSaveCallback)(filename);
printf("callback fired");
newMode = IDLE;
/*printf("train\n");
detector.trainModel(model);
FileStorage fs("test7777777ss77.yml", FileStorage::WRITE);
detector.write(fs);*/
//looping = false;
}
break; break;
case RECOGNIZE: case RECOGNIZE:
...@@ -248,8 +271,8 @@ int Loop(string filename) ...@@ -248,8 +271,8 @@ int Loop(string filename)
trainClock = 1; trainClock = 1;
if (results.size() > 0) if (results.size() > 0)
{ {
device->stop(); (*faceCheckCallback)(filename, results[0]->numVotes);
return results[0]->numVotes; newMode = IDLE;
} }
break; break;
......
...@@ -23,9 +23,11 @@ namespace FaceDetection ...@@ -23,9 +23,11 @@ namespace FaceDetection
void SaveFace(string); void SaveFace(string);
void Start(std::function<void(cv::Mat)>&&); void Start(std::function<void(cv::Mat)> &&, std::function<void(std::string)> &&, std::function<void(std::string, int)> &&);
int CheckFace(string); void Stop();
void CheckFace(string);
private: private:
}; };
......
...@@ -17,6 +17,7 @@ namespace FaceDetection ...@@ -17,6 +17,7 @@ namespace FaceDetection
using v8::Object; using v8::Object;
using v8::String; using v8::String;
using v8::Number; using v8::Number;
using v8::Int8Array;
using v8::Value; using v8::Value;
using namespace std; using namespace std;
...@@ -25,8 +26,9 @@ namespace FaceDetection ...@@ -25,8 +26,9 @@ namespace FaceDetection
uv_thread_t texample_thread; uv_thread_t texample_thread;
uv_async_t faceCheckAsyncToken; uv_async_t checkAsyncToken;
uv_async_t faceSaveAsyncToken; uv_async_t saveAsyncToken;
uv_async_t frameAsyncToken;
uv_loop_t *loop = uv_default_loop(); uv_loop_t *loop = uv_default_loop();
...@@ -46,40 +48,19 @@ namespace FaceDetection ...@@ -46,40 +48,19 @@ namespace FaceDetection
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// ///
/// \param req
void AfterSave(uv_async_t *req)
{
auto request = (faceRequest *) req->data;
auto isolate = request->isolate;
HandleScope scope(isolate);
const unsigned argc = 1;
Local<Value> argv[argc] = {Number::New(isolate, request->result)};
Local<Function>::New(isolate, request->callback)->
Call(isolate->GetCurrentContext()->Global(), 1, argv);
}
///
/// \param req
void SaveWorker(void *)
{
faceDetector->SaveFace("testFace");
uv_async_send(&faceSaveAsyncToken);
}
///
/// \param args /// \param args
void Save(const FunctionCallbackInfo<Value> &args) void Save(const FunctionCallbackInfo<Value> &args)
{ {
Isolate *isolate = args.GetIsolate(); Isolate *isolate = args.GetIsolate();
faceRequest *request = new faceRequest();
cb = Local<Function>::Cast(args[0]);
auto request = (faceRequest *) saveAsyncToken.data;
auto cb = Local<Function>::Cast(args[1]);
v8::String::Utf8Value filename(args[0]->ToString());
request->callback.Reset(isolate, cb);
request->isolate = isolate; request->isolate = isolate;
faceSaveAsyncToken.data = request; request->callback.Reset(isolate, cb);
uv_async_init(loop, &faceSaveAsyncToken, AfterSave);
uv_thread_create(&texample_thread, SaveWorker, NULL); faceDetector->SaveFace(*filename);
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
...@@ -87,42 +68,19 @@ namespace FaceDetection ...@@ -87,42 +68,19 @@ namespace FaceDetection
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// ///
/// \param req
void AfterCheck(uv_async_t *req)
{
auto request = (faceRequest *) req->data;
auto isolate = request->isolate;
HandleScope scope(isolate);
const unsigned argc = 1;
Local<Value> argv[argc] = {Number::New(isolate, request->result)};
Local<Function>::New(isolate, request->callback)->
Call(isolate->GetCurrentContext()->Global(), 1, argv);
}
///
/// \param req
void CheckWorker(void *)
{
int res = faceDetector->CheckFace("testFace");
auto request = (faceRequest *) faceCheckAsyncToken.data;
request->result=res;
uv_async_send(&faceCheckAsyncToken);
}
///
/// \param args /// \param args
void Check(const FunctionCallbackInfo<Value> &args) void Check(const FunctionCallbackInfo<Value> &args)
{ {
Isolate *isolate = args.GetIsolate(); Isolate *isolate = args.GetIsolate();
faceRequest *request = new faceRequest();
cb = Local<Function>::Cast(args[0]);
request->callback.Reset(isolate, cb);
request->isolate = isolate;
faceCheckAsyncToken.data = request; auto request = (faceRequest *) checkAsyncToken.data;
auto cb = Local<Function>::Cast(args[1]);
v8::String::Utf8Value filename(args[0]->ToString());
uv_async_init(loop, &faceCheckAsyncToken, AfterCheck); request->isolate = isolate;
uv_thread_create(&texample_thread, CheckWorker, NULL); request->callback.Reset(isolate, cb);
faceDetector->CheckFace(*filename);
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
...@@ -131,11 +89,45 @@ namespace FaceDetection ...@@ -131,11 +89,45 @@ namespace FaceDetection
/// ///
/// \param args /// \param args
void SetWorkingDir(const FunctionCallbackInfo<Value> &args) void Init(const FunctionCallbackInfo<Value> &args)
{ {
v8::String::Utf8Value param1(args[0]->ToString()); v8::String::Utf8Value param1(args[0]->ToString());
std::string foo = std::string(*param1); std::string workingDir = std::string(*param1);
faceDetector->Init(foo);
saveAsyncToken.data = new faceRequest();
checkAsyncToken.data = new faceRequest();
faceDetector->Init(workingDir);
uv_async_init(loop, &saveAsyncToken, [](uv_async_t *req)
{
auto request = (faceRequest *) req->data;
auto isolate = request->isolate;
HandleScope scope(isolate);
printf("save callback dispatcher\n");
auto fname = v8::String::NewFromUtf8(isolate, request->filename.c_str());
const unsigned argc = 1;
Local<Value> argv[argc] = {fname};
Local<Function>::New(isolate, request->callback)->
Call(isolate->GetCurrentContext()->Global(), argc, argv);
});
uv_async_init(loop, &checkAsyncToken, [](uv_async_t *req)
{
auto request = (faceRequest *) req->data;
auto isolate = request->isolate;
HandleScope scope(isolate);
auto fname = v8::String::NewFromUtf8(isolate, request->filename.c_str());
auto votes = v8::Integer::New(isolate, request->result);
const unsigned argc = 2;
Local<Value> argv[argc] = {fname, votes};
Local<Function>::New(isolate, request->callback)->
Call(isolate->GetCurrentContext()->Global(), argc, argv);
});
} }
/// ///
...@@ -148,41 +140,56 @@ namespace FaceDetection ...@@ -148,41 +140,56 @@ namespace FaceDetection
request->callback.Reset(isolate, cb); request->callback.Reset(isolate, cb);
request->isolate = isolate; request->isolate = isolate;
faceCheckAsyncToken.data = request; frameAsyncToken.data = request;
uv_async_init(loop, &frameAsyncToken, [](uv_async_t *req)
uv_async_init(loop, &faceCheckAsyncToken, [](uv_async_t* req){ {
auto request = (faceRequest *) req->data; auto request = (faceRequest *) req->data;
auto isolate = request->isolate; auto isolate = request->isolate;
auto frame=request->frame; auto frame = request->frame;
HandleScope scope(isolate); HandleScope scope(isolate);
v8::Local<Array> myArray = v8::Array::New(isolate); size_t size = (size_t) frame.rows * 3;
v8::Local<ArrayBuffer> buff = v8::ArrayBuffer::New(isolate, size);
v8::Local<Int8Array> array = v8::Int8Array::New(buff, 0, size);
for(int i=0;i<frame.rows;i++) for (uint32_t i = 0; i < size; i += 3)
{ {
Local<Array> row = Array::New(isolate); array->Set(i + 0, Integer::New(isolate, (short) (frame.at<float>(i / 3, 0) * 1000)));
row->Set(0,Number::New(isolate,(int)(frame.at<float>(i,0)*1000))); array->Set(i + 1, Integer::New(isolate, (short) (frame.at<float>(i / 3, 1) * 1000)));
row->Set(1,Number::New(isolate,(int)(frame.at<float>(i,1)*1000))); array->Set(i + 2, Integer::New(isolate, (short) ((frame.at<float>(i / 3, 2) + 600) * 1000)));
row->Set(2,Number::New(isolate,(int)(frame.at<float>(i,2)*1000)));
myArray->Set(i,row);
} }
const unsigned argc = 1; const unsigned argc = 1;
Local<Value> argv[argc] = {myArray}; Local<Value> argv[argc] = {array};
Local<Function>::New(isolate, request->callback)-> Local<Function>::New(isolate, request->callback)->
Call(isolate->GetCurrentContext()->Global(), argc, argv); Call(isolate->GetCurrentContext()->Global(), argc, argv);
}); });
uv_thread_create(&texample_thread, [](void*){ uv_thread_create(&texample_thread, [](void *)
faceDetector->Start([](cv::Mat mat){ {
((faceRequest *) faceCheckAsyncToken.data)->frame=mat; faceDetector->Start([](cv::Mat mat)
{
((faceRequest *) frameAsyncToken.data)->frame = mat;
printf("lol, callback\n"); printf("lol, callback\n");
uv_async_send(&faceCheckAsyncToken); uv_async_send(&frameAsyncToken);
},
[](std::string filename) //save callback
{
printf("save callback \n");
((faceRequest *) (saveAsyncToken.data))->filename = filename;
uv_async_send(&saveAsyncToken);
},
[](std::string filename, int votes) //check callback
{
((faceRequest *) (checkAsyncToken.data))->filename = filename;
((faceRequest *) (checkAsyncToken.data))->result = votes;
uv_async_send(&checkAsyncToken);
}); });
}, NULL); }, NULL);
} }
void Stop(const FunctionCallbackInfo<Value> &args) void Stop(const FunctionCallbackInfo<Value> &args)
{ {
faceDetector->Stop();
} }
void init(Local<Object> exports, Local<Object> module) void init(Local<Object> exports, Local<Object> module)
...@@ -191,7 +198,7 @@ namespace FaceDetection ...@@ -191,7 +198,7 @@ namespace FaceDetection
NODE_SET_METHOD(exports, "checkFace", Check); NODE_SET_METHOD(exports, "checkFace", Check);
NODE_SET_METHOD(exports, "start", Start); NODE_SET_METHOD(exports, "start", Start);
NODE_SET_METHOD(exports, "stop", Stop); NODE_SET_METHOD(exports, "stop", Stop);
NODE_SET_METHOD(exports, "setWorkingDir", SetWorkingDir); NODE_SET_METHOD(exports, "setWorkingDir", Init);
} }
NODE_MODULE(addon, init) NODE_MODULE(addon, init)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment