#include "CascadeClassifierWrap.h" #include "OpenCV.h" #include "Matrix.h" void AsyncDetectMultiScale(uv_work_t *req); void AfterAsyncDetectMultiScale(uv_work_t *req); Persistent CascadeClassifierWrap::constructor; void CascadeClassifierWrap::Init(Handle target) { HandleScope scope; // Constructor constructor = Persistent::New(FunctionTemplate::New(CascadeClassifierWrap::New)); constructor->InstanceTemplate()->SetInternalFieldCount(1); constructor->SetClassName(String::NewSymbol("CascadeClassifier")); // Prototype //Local proto = constructor->PrototypeTemplate(); NODE_SET_PROTOTYPE_METHOD(constructor, "detectMultiScale", DetectMultiScale); target->Set(String::NewSymbol("CascadeClassifier"), constructor->GetFunction()); }; NAN_METHOD(CascadeClassifierWrap::New() { HandleScope scope; if (args.This()->InternalFieldCount() == 0) return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new"))); CascadeClassifierWrap *pt = new CascadeClassifierWrap(*args[0]); pt->Wrap(args.This()); return args.This(); } CascadeClassifierWrap::CascadeClassifierWrap(v8::Value* fileName){ std::string filename; filename = std::string(*v8::String::AsciiValue(fileName->ToString())); if (!cc.load(filename.c_str())){ v8::ThrowException(v8::Exception::TypeError(v8::String::New("Error loading file"))); } } struct classifier_baton_t { CascadeClassifierWrap *cc; Persistent cb; Matrix *im; double scale; int neighbors; int minw; int minh; int sleep_for; std::vector res; uv_work_t request; }; NAN_METHOD(CascadeClassifierWrap::DetectMultiScale){ HandleScope scope; CascadeClassifierWrap *self = ObjectWrap::Unwrap(args.This()); if (args.Length() < 2){ v8::ThrowException(v8::Exception::TypeError(v8::String::New("detectMultiScale takes at least 2 args"))); } Matrix *im = ObjectWrap::Unwrap(args[0]->ToObject()); REQ_FUN_ARG(1, cb); double scale = 1.1; if (args.Length() > 2 && args[2]->IsNumber()) scale = args[2]->NumberValue(); int neighbors = 2; if (args.Length() > 3 && args[3]->IsInt32()) neighbors = args[3]->IntegerValue(); int minw = 30; int minh = 30; if (args.Length() > 5 && args[4]->IsInt32() && args[5]->IsInt32()){ minw = args[4]->IntegerValue(); minh = args[5]->IntegerValue(); } classifier_baton_t *baton = new classifier_baton_t(); baton->cc = self; baton->cb = Persistent::New(cb); baton->im = im; baton->scale = scale; baton->neighbors = neighbors; baton->minw = minw; baton->minh = minh; baton->sleep_for = 1; baton->request.data = baton; // self->Ref(); // eio_custom(EIO_DetectMultiScale, EIO_PRI_DEFAULT, EIO_AfterDetectMultiScale, baton); // ev_ref(EV_DEFAULT_UC); uv_queue_work(uv_default_loop(), &baton->request, AsyncDetectMultiScale, (uv_after_work_cb)AfterAsyncDetectMultiScale); return Undefined(); } void AsyncDetectMultiScale(uv_work_t *req) { classifier_baton_t *baton = static_cast(req->data); // sleep(baton->sleep_for); std::vector objects; cv::Mat gray; if(baton->im->mat.channels() != 1) cvtColor(baton->im->mat, gray, CV_BGR2GRAY); equalizeHist( gray, gray); baton->cc->cc.detectMultiScale(gray, objects, baton->scale, baton->neighbors, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(baton->minw, baton->minh)); baton->res = objects; } void AfterAsyncDetectMultiScale(uv_work_t *req) { HandleScope scope; classifier_baton_t *baton = static_cast(req->data); // ev_unref(EV_DEFAULT_UC); // baton->cc->Unref(); Local argv[2]; argv[0] = Local::New(Null()); v8::Local arr = v8::Array::New(baton->res.size()); for(unsigned int i = 0; i < baton->res.size(); i++ ){ v8::Local x = v8::Object::New(); x->Set(v8::String::New("x"), v8::Number::New(baton->res[i].x)); x->Set(v8::String::New("y"), v8::Number::New(baton->res[i].y)); x->Set(v8::String::New("width"), v8::Number::New(baton->res[i].width)); x->Set(v8::String::New("height"), v8::Number::New(baton->res[i].height)); arr->Set(i, x); } argv[1] = arr; TryCatch try_catch; baton->cb->Call(Context::GetCurrent()->Global(), 2, argv); if (try_catch.HasCaught()) { FatalException(try_catch); } baton->cb.Dispose(); delete baton; // return 0; }