2017-02-01 152 views
0

我得到大约每秒20帧。如果我这样运行它,它会导致计算机冻结。我认为这是因为它一次处理大量数据。我怎么能限制一个函数的最大数量的进程,我看着kue,但它需要redis。我该如何处理?谢谢Node.js处理大量图像

js调用C++插件来完成这些工作。

addon.addonFunction(img, function(err, detobjs) {//this takes about 1sec 
    //do stuff 
}); 

C++代码

#include "HogPeopleDetectdvr.h" 
#include <string> 
#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <chrono> 
#include <thread> 
// #include "inc/Matrix.h" 
// Nan::Persistent<FunctionTemplate> Matrix::constructor1; 

// #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
using namespace v8; 
using v8::Local; 
using v8::Object; 

// Nan::Persistent<FunctionTemplate> Matrix::constructor; 
// Nan::Persistent<FunctionTemplate> Matrix::constructor; 
location unpack_location(Isolate * , const Handle<Object> sample_obj); 

struct Work { 
    uv_work_t request; 
    Persistent<Function> callback; 

    std::vector<location> locations; 
    std::vector<detect_result> results; 
}; 

// called by libuv worker in separate thread 
static void WorkAsync(uv_work_t *req) 
{ 
    Work *work = static_cast<Work *>(req->data); 

    work->results.resize(work->locations.size()); 
    std::transform(work->locations.begin(), work->locations.end(), work->results.begin(), CalculateRectHog); 
} 

static void WorkAsyncComplete(uv_work_t *req,int status) 
{ 
    Isolate * isolate = Isolate::GetCurrent(); 

    v8::HandleScope handleScope(isolate); 

    Work *work = static_cast<Work *>(req->data); 

    Local<Array> arr = Array::New(isolate); 

    for (unsigned int i = 0; i < work->results[0].found.size(); i++) { 
     v8::Local <v8::Object> x = Nan::New<v8::Object>(); 
     x->Set(Nan::New("x").ToLocalChecked(), Nan::New <Number> (work->results[0].found[i].x)); 
     x->Set(Nan::New("y").ToLocalChecked(), Nan::New <Number> (work->results[0].found[i].y)); 
     x->Set(Nan::New("width").ToLocalChecked(), Nan::New <Number> (work->results[0].found[i].width)); 
     x->Set(Nan::New("height").ToLocalChecked(), Nan::New <Number> (work->results[0].found[i].height)); 
     arr->Set(i, x); 
    } 

    Handle<Value> argv1[] = { Null(isolate) , arr}; 

    // execute the callback 
    // https://stackoverflow.com/questions/13826803/calling-javascript-function-from-a-c-callback-in-v8/28554065#28554065 
    Local<Function>::New(isolate, work->callback)->Call(isolate->GetCurrentContext()->Global(), 2, argv1); 

    work->callback.Reset(); 
    delete work; 

} 

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

    Work * work = new Work(); 
    work->request.data = work; 

    Local<Array> input = Local<Array>::Cast(args[0]); 
    unsigned int num_locations = input->Length(); 
    for (unsigned int i = 0; i < num_locations; i++) { 
     work->locations.push_back(unpack_location(isolate, Local<Object>::Cast(input->Get(i)))); 
    } 

    Local<Function> callback = Local<Function>::Cast(args[1]); 
    work->callback.Reset(isolate, callback); 

    uv_queue_work(uv_default_loop(),&work->request,WorkAsync,WorkAsyncComplete); 

    args.GetReturnValue().Set(Undefined(isolate)); 

} 


location unpack_location(Isolate * isolate, const Handle<Object> location_obj) { 
    location loc; 
    Handle<Value> hit_threshold = location_obj->Get(v8::String::NewFromUtf8(isolate,"hit_threshold")); 
    Handle<Value> wins_tride = location_obj->Get(v8::String::NewFromUtf8(isolate,"wins_tride")); 
    Handle<Value> padding = location_obj->Get(v8::String::NewFromUtf8(isolate,"padding")); 
    Handle<Value> scale = location_obj->Get(v8::String::NewFromUtf8(isolate,"scale")); 
    Handle<Value> group_threshold = location_obj->Get(v8::String::NewFromUtf8(isolate,"group_threshold")); 
    Handle<Value> img_Value = location_obj->Get(v8::String::NewFromUtf8(isolate,"img")); 

    loc.hit_threshold = hit_threshold->NumberValue(); 
    loc.wins_tride = wins_tride->NumberValue(); 
    loc.padding = padding->NumberValue(); 
    loc.scale = scale->NumberValue(); 
    loc.group_threshold = group_threshold->NumberValue(); 
    loc.img = Nan::ObjectWrap::Unwrap<node_opencv::Matrix>(img_Value->ToObject())->mat; 
    return loc; 
} 

void init(Handle <Object> exports, Handle<Object> module) { 
    Nan::HandleScope scope; 
    NODE_SET_METHOD(exports, "HogPeopleDetectorDvr", PeopleDetectdvr); 

} 

NODE_MODULE(hog_people_detect, init) 

及其在此功能。

detect_result CalculateRectHog(location &loc) { 

    detect_result result; 

    HOGDescriptor hog; 
    hog.winSize = Size(48, 96); 
    hog.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector()); 

    vector<Rect> found, found_filtered; 

    hog.detectMultiScale(loc.img, found, loc.hit_threshold, Size(), 
    Size(), loc.scale, loc.group_threshold); //this line 

     result.img = loc.img; 
     result.found = found; 
     // imwrite("wwww.jpg",loc.img); 

    return result; 
} 
+0

如果处理在C++插件做,你为什么不启动一个线程工作,并立即返回到JS? – pergy

回答

2

这是由于javascript默认情况下作为单个线程运行。所以你的C++插件会阻止你的JavaScript程序的执行。

您可能希望使用子进程执行处理,因为这样您不会阻止主执行,因此它不应该停止。

应该有足够的信息,让你去这里: ​​

+0

如何使用异步并限制它。这将是充足的吗? – vladimir999

+1

只要异步库产生一个新的线程,那么你的执行就不会结束。如果它真的是异步的,它应该封装产生一个新线程的过程,所以我说,给它一个去找出:) –