【问题标题】:Make c++ addon asynchronous使 c++ 插件异步
【发布时间】:2017-05-04 10:35:32
【问题描述】:

我已设法将 dlib 视频跟踪器集成到我的节点应用程序中。我现在的问题是使它成为非阻塞的。任何帮助将不胜感激。谢谢。

这是我的代码

#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();

谢谢。

【问题讨论】:

    标签: c++ node.js asynchronous nan node.js-addon


    【解决方案1】:

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

    有两种常见的方法:

    1. 您连接到libuv 事件循环,然后在任务完成时调用javascript 完成回调。这种方式在nodejs中比较常用。
    2. 您使用自己的线程/任务。这样 javascript 代码负责查询结果。这种方法更容易实现,特别是如果您的插件已经使用了一些线程/任务,但需要额外的 javascript 代码来处理。

    【讨论】:

    • 我认为选项 2 听起来不错。让我看看。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多