move callbacks to FaceDetection::Start method

parent 4cc3491b
var d=require("./build/Release/face-detection.node");
d.setWorkingDir(__dirname);
console.log('set wd');
module.exports=d;
\ No newline at end of file
......@@ -30,19 +30,24 @@ using namespace cv;
using namespace ppf_match_3d;
using namespace FaceDetection;
string filename;
String face_cascade_name = "";
String eyes_cascade_name = "";
cv::CascadeClassifier face_cascade;
cv::CascadeClassifier eyes_cascade;
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;
bool started=false;
struct facePosition {int x, y, width, height; };
int Loop(string filename);
int Loop();
void FaceDetector::Init(string wd)
{
......@@ -50,30 +55,46 @@ void FaceDetector::Init(string wd)
eyes_cascade_name = wd + "/haarcascade_eye_tree_eyeglasses.xml";
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;
Loop("");
///
///
void FaceDetector::Stop() {
started=false;
}
///
/// \param filename
void FaceDetector::SaveFace(string filename)
void FaceDetector::SaveFace(string file)
{
Loop(filename);
filename = file;
newMode = TRAIN;
}
///
/// \param filename
int FaceDetector::CheckFace(string filename)
void FaceDetector::CheckFace(string file)
{
int res=Loop(filename);
return res;
filename = file;
newMode = RECOGNIZE;
}
......@@ -103,14 +124,13 @@ bool detectAndDisplay( Mat frame, facePosition &facePos ) {
return false;
}
int Loop(string filename)
int Loop()
{
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;
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)
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::infrared, 640, 480, rs::format::y16, 30);//rs::preset::best_quality);
device->start();
int trainClock = 0;
bool looping = true;
while (looping)
while (started)
{
currentMode=newMode;
FaceDetection::Mode currentMode = newMode;
if (device->is_streaming())
device->wait_for_frames();
......@@ -148,12 +161,10 @@ int Loop(string filename)
rs::intrinsics color_intrin = device->get_stream_intrinsics(rs::stream::color);
float scale = (device->get_depth_scale());
bool faceDetected = false;
/////////////////////////////////////////////////////////////////////////////////////////////
facePosition facePos;
if (trainClock % 3 == 0)
if (trainClock % 5 == 0)
{
cv::Mat frame(color_intrin.height, color_intrin.width, CV_8UC3, (uchar *) color_image);
if (detectAndDisplay(frame, facePos))
......@@ -192,8 +203,8 @@ int Loop(string filename)
float a = cx - (facePos.x + facePos.width / 2);
float b = cy - (facePos.y + facePos.height / 2);
float ry = (facePos.height / 2) * 1.0f;
float rx = (facePos.width / 2) * 0.8f;
float ry = (facePos.height / 2) * 0.9f;
float rx = (facePos.width / 2) * 0.7f;
bool insideEllipse = ((a * a) / (rx * rx) + (b * b) / (ry * ry)) <= 1;
......@@ -231,11 +242,23 @@ int Loop(string filename)
switch (currentMode)
{
case IDLE:
printf("idle");
//printf("idle");
break;
case TRAIN:
{
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;
case RECOGNIZE:
......@@ -248,8 +271,8 @@ int Loop(string filename)
trainClock = 1;
if (results.size() > 0)
{
device->stop();
return results[0]->numVotes;
(*faceCheckCallback)(filename, results[0]->numVotes);
newMode = IDLE;
}
break;
......
......@@ -23,9 +23,11 @@ namespace FaceDetection
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:
};
......
......@@ -17,6 +17,7 @@ namespace FaceDetection
using v8::Object;
using v8::String;
using v8::Number;
using v8::Int8Array;
using v8::Value;
using namespace std;
......@@ -25,8 +26,9 @@ namespace FaceDetection
uv_thread_t texample_thread;
uv_async_t faceCheckAsyncToken;
uv_async_t faceSaveAsyncToken;
uv_async_t checkAsyncToken;
uv_async_t saveAsyncToken;
uv_async_t frameAsyncToken;
uv_loop_t *loop = uv_default_loop();
......@@ -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
void Save(const FunctionCallbackInfo<Value> &args)
{
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;
faceSaveAsyncToken.data = request;
uv_async_init(loop, &faceSaveAsyncToken, AfterSave);
uv_thread_create(&texample_thread, SaveWorker, NULL);
request->callback.Reset(isolate, cb);
faceDetector->SaveFace(*filename);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
......@@ -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
void Check(const FunctionCallbackInfo<Value> &args)
{
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);
uv_thread_create(&texample_thread, CheckWorker, NULL);
request->isolate = isolate;
request->callback.Reset(isolate, cb);
faceDetector->CheckFace(*filename);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
......@@ -131,11 +89,45 @@ namespace FaceDetection
///
/// \param args
void SetWorkingDir(const FunctionCallbackInfo<Value> &args)
void Init(const FunctionCallbackInfo<Value> &args)
{
v8::String::Utf8Value param1(args[0]->ToString());
std::string foo = std::string(*param1);
faceDetector->Init(foo);
std::string workingDir = std::string(*param1);
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
request->callback.Reset(isolate, cb);
request->isolate = isolate;
faceCheckAsyncToken.data = request;
uv_async_init(loop, &faceCheckAsyncToken, [](uv_async_t* req){
frameAsyncToken.data = request;
uv_async_init(loop, &frameAsyncToken, [](uv_async_t *req)
{
auto request = (faceRequest *) req->data;
auto isolate = request->isolate;
auto frame=request->frame;
auto frame = request->frame;
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);
row->Set(0,Number::New(isolate,(int)(frame.at<float>(i,0)*1000)));
row->Set(1,Number::New(isolate,(int)(frame.at<float>(i,1)*1000)));
row->Set(2,Number::New(isolate,(int)(frame.at<float>(i,2)*1000)));
myArray->Set(i,row);
array->Set(i + 0, Integer::New(isolate, (short) (frame.at<float>(i / 3, 0) * 1000)));
array->Set(i + 1, Integer::New(isolate, (short) (frame.at<float>(i / 3, 1) * 1000)));
array->Set(i + 2, Integer::New(isolate, (short) ((frame.at<float>(i / 3, 2) + 600) * 1000)));
}
const unsigned argc = 1;
Local<Value> argv[argc] = {myArray};
Local<Value> argv[argc] = {array};
Local<Function>::New(isolate, request->callback)->
Call(isolate->GetCurrentContext()->Global(), argc, argv);
});
uv_thread_create(&texample_thread, [](void*){
faceDetector->Start([](cv::Mat mat){
((faceRequest *) faceCheckAsyncToken.data)->frame=mat;
printf("lol, callback\n");
uv_async_send(&faceCheckAsyncToken);
});
uv_thread_create(&texample_thread, [](void *)
{
faceDetector->Start([](cv::Mat mat)
{
((faceRequest *) frameAsyncToken.data)->frame = mat;
printf("lol, callback\n");
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);
}
void Stop(const FunctionCallbackInfo<Value> &args)
{
faceDetector->Stop();
}
void init(Local<Object> exports, Local<Object> module)
......@@ -191,7 +198,7 @@ namespace FaceDetection
NODE_SET_METHOD(exports, "checkFace", Check);
NODE_SET_METHOD(exports, "start", Start);
NODE_SET_METHOD(exports, "stop", Stop);
NODE_SET_METHOD(exports, "setWorkingDir", SetWorkingDir);
NODE_SET_METHOD(exports, "setWorkingDir", 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