2017-05-04 74 views
1

我已經設法將dlib視頻跟蹤器集成到我的節點應用程序中。我現在面臨的問題是讓它無阻塞。任何幫助將不勝感激。謝謝。使C++ addon異步

這裏是我的代碼

#ifndef MYOBJECT_H 
#define MYOBJECT_H 

#include "ImageDetails.h" 
#include "opencv2/core/core_c.h" 
#include "../dlib/opencv/cv_image.h" 
#include "../dlib/image_processing.h" 
#include "../dlib/gui_widgets.h" 
#include "../dlib/image_io.h" 
#include "../dlib/dir_nav.h" 

#include "/home/pi/projects/lib/node-opencv-master/src/Matrix.h" 
#include "/home/pi/projects/lib/node-opencv-master/src/Contours.h" 


#include <nan.h> 
//#include <node_object_wrap.h> 
using namespace dlib; 
using namespace cv; 
using namespace std; 

class MyObject : public Nan::ObjectWrap { 
public: 
    static void Init(v8::Local<v8::Object> exports); 

private: 
    explicit MyObject(std::vector<ImageDetails> details, cv::Mat img); 
    ~MyObject(); 

    static void New(const Nan::FunctionCallbackInfo<v8::Value>& args); 
    static void UpdateImage(const Nan::FunctionCallbackInfo<v8::Value>& args); 
    static Nan::Persistent<v8::Function> constructor; 
    std::vector <correlation_tracker> value_; 
}; 


#endif 

Imagedetails.h

#ifndef IMAGEDETAILS_H 
#define IMAGEDETAILS_H 



class ImageDetails { 
public: 
    int width; 
    int height; 
    int xpoint; 
    int ypoint; 
}; 



#endif 

//

#include "VideoTracking.h" 


Nan::Persistent<v8::Function> MyObject::constructor; 
ImageDetails unpack_details(Isolate * , const Handle<Object> sample_obj); 

MyObject::MyObject(std::vector<ImageDetails> details, cv::Mat img){ 

value_.resize(details.size()); 
dlib::array2d<bgr_pixel> dlibImage; 
dlib::assign_image(dlibImage, dlib::cv_image<bgr_pixel>(img)); 

//value_.start_track(dlibImage, centered_rect(point(93,110), 38, 86)); 

    for (unsigned int i=0; i < details.size(); i++){ 
    cout << details[i].xpoint << endl; 
    cout << details[i].ypoint << endl; 
    cout << details[i].width << endl; 
    cout << details[i].height << endl; 

     value_[i].start_track(dlibImage, centered_rect(point(details[i].xpoint, details[i].ypoint), details[i].width, details[i].height)); 
    } 
} 

MyObject::~MyObject() { 
} 

void MyObject::Init(v8::Local<v8::Object> exports) { 
Nan::HandleScope scope; 

    // Prepare constructor template 
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New); 
    tpl->SetClassName(Nan::New("MyObject").ToLocalChecked()); 
    tpl->InstanceTemplate()->SetInternalFieldCount(1); 

    Nan::SetPrototypeMethod(tpl, "updateImage", UpdateImage); 
    constructor.Reset(tpl->GetFunction()); 
    exports->Set(Nan::New("MyObject").ToLocalChecked(), tpl->GetFunction()); 
} 

void MyObject::New(const Nan::FunctionCallbackInfo<v8::Value>& args) { 
     Isolate* isolate = args.GetIsolate(); 


     v8::Local<v8::Object> location_obj = args[1]->ToObject(); 
     v8::Handle<v8::Value> img_Value = location_obj->Get(v8::String::NewFromUtf8(isolate,"img")); 
     v8::Local<v8::Array> input = v8::Local<v8::Array>::Cast(args[0]); 
     unsigned int num_locations = input->Length(); 

      std::vector<ImageDetails> tmp; 
//   tmp.resize(num_locations); 

     for (unsigned int i = 0; i < num_locations; i++) { 
      tmp.push_back(unpack_details(isolate, v8::Local<v8::Object>::Cast(input->Get(i)))); 
     } 

    MyObject* obj = new MyObject(tmp, Nan::ObjectWrap::Unwrap<node_opencv::Matrix>(img_Value->ToObject())->mat); 
    obj->Wrap(args.This()); 
    args.GetReturnValue().Set(args.This()); 

} 

ImageDetails unpack_details(Isolate * isolate, const v8::Handle<v8::Object> location_obj) { 
    ImageDetails tmp; 
    v8::Handle<v8::Value> width = location_obj->Get(v8::String::NewFromUtf8(isolate,"width")); 
    v8::Handle<v8::Value> heigth = location_obj->Get(v8::String::NewFromUtf8(isolate,"heigth")); 
    v8::Handle<v8::Value> xpoint = location_obj->Get(v8::String::NewFromUtf8(isolate,"xpoint")); 
    v8::Handle<v8::Value> ypoint = location_obj->Get(v8::String::NewFromUtf8(isolate,"ypoint")); 

    tmp.width = width->NumberValue(); 
    tmp.height = heigth->NumberValue(); 
    tmp.xpoint = xpoint->NumberValue(); 
    tmp.ypoint = ypoint->NumberValue(); 

    return tmp; 
} 

void MyObject::UpdateImage(const Nan::FunctionCallbackInfo<v8::Value>& args) { 
// image_window win; 
    Isolate* isolate = args.GetIsolate(); 

    v8::Local<v8::Object> location_obj = args[0]->ToObject(); 
    v8::Handle<v8::Value> img_Value = location_obj->Get(v8::String::NewFromUtf8(isolate,"img")); 

    dlib::array2d<bgr_pixel> dlibImage; 
    dlib::assign_image(dlibImage, dlib::cv_image<bgr_pixel>(Nan::ObjectWrap::Unwrap<node_opencv::Matrix>(img_Value->ToObject())->mat)); 

    MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); 
    v8::Local<v8::Array> arr = Array::New(isolate); 

    for (unsigned int i=0; i < obj->value_.size(); i++){ 
     obj->value_[i].update(dlibImage); 

     cv::Rect r = cv::Rect(obj->value_[i].get_position().left(), obj->value_[i].get_position().top(), obj->value_[i].get_position().width(), obj->value_[i].get_position().height()); 

      v8::Local <v8::Object> x = Nan::New<v8::Object>(); 
      x->Set(Nan::New("x").ToLocalChecked(), Nan::New <Number> (r.x)); 
      x->Set(Nan::New("y").ToLocalChecked(), Nan::New <Number> (r.y)); 
      x->Set(Nan::New("width").ToLocalChecked(), Nan::New <Number> (r.width)); 
      x->Set(Nan::New("height").ToLocalChecked(), Nan::New <Number> (r.height)); 
      arr->Set(i, x); 
    } 
// obj->value_.update(dlibImage); 
// 
//  win.set_image(dlibImage); 
//  win.clear_overlay(); 
//  win.add_overlay(obj->value_.get_position()); 
////  sleep(10000); 
// cout << obj->value_.get_position().top() <<endl; 
// cin.get(); 
//  Handle<Value> argv1[] = { Null(isolate) , arr}; 
    args.GetReturnValue().Set(arr); 
} 

基本上我需要創建跟蹤器,後來更新它的一種方式。因此,我決定在創建一個新對象時創建跟蹤器,並在什麼後面更新它。目前這是它在我的js文件中被調用的方式。

這是我如何創建它

var loc = { 
         xpoint: detobj.x, 
         ypoint: detobj.y, 
         heigth: detobj.height, 
         width: detobj.width 
        }; 
        details.push(loc); 
var image_obj = new addon.MyObject(details, obj1); 

這是我如何更新圖像

var obj = {img:matrix} 
    var detobjs = image_obj.updateImage(obj1); 
    for(var i =0; i < detobjs.length; i++){ 
     var detobj = detobjs[i]; 
    matrix.rectangle([detobj.x, detobj.y], [detobj.width, detobj.height], COLORRED, 1); 

    } 
procobj.frame.imagejpg = matrix.toBuffer(); 

謝謝。

回答

1

有很多教程描述如何做到這一點。例如Building an Asynchronous C++ Addon for Node.js using Nan

Therea兩種常用的方法:

  1. 您掛鉤到libuv事件循環以後調用JavaScript完成回調,當任務完成。這種方法通常用於nodejs。
  2. 您使用自己的線程/任務。這種方式的JavaScript代碼負責查詢結果。這種方法更容易實現,特別是如果你的插件已經使用了一些線程/任務,但需要額外的JavaScript代碼來處理。
+0

我認爲選項2聽起來不錯。讓我看看。謝謝 – vladimir999