2017-02-01 5 views
0

Ich bekomme etwa 20 Bilder pro Sekunde. Wenn ich es so laufe, wird der Computer eingefroren. Ich denke, es ist, weil es eine große Anzahl auf einmal verarbeitet. Wie kann ich eine Funktion auf eine maximale Anzahl von Prozessen begrenzen, die es haben kann? Ich habe auf kue geschaut, aber es erfordert Redis. Wie kann ich damit umgehen? DankeNode.js Verarbeitung von vielen Bildern

Die js nennt ein C++ Addon, um die Arbeiten zu erledigen.

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

C++ Code

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

Die in dieser Funktion.

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

, wenn die Verarbeitung in Ihrem C++ Addon geschehen ist, warum Sie keinen gearbeitet Thread starten und sofort zu js zurückkehren? – pergy

Antwort

2

Dies liegt daran, dass Javascript standardmäßig als einzelner Thread ausgeführt wird. Dein C++ Addon blockiert also die Ausführung deines Javascript Programms.

Sie könnten einen untergeordneten Prozess verwenden, um die Verarbeitung durchzuführen, da Sie auf diese Weise Ihre Hauptausführung nicht blockieren und daher nicht anhalten sollten.

Es sollte genügend Informationen, um Sie hier loslegen: https://nodejs.org/api/child_process.html

+0

Wie wäre es mit Async und begrenzen Sie es. Wird das ausreichen? – vladimir999

+1

Solange Ihre async lib einen neuen Thread erzeugt, stottert Ihre Ausführung nicht. Wenn es wirklich async ist, sollte es den Prozess des Erstellens eines neuen Threads einkapseln, also sage ich, gib es und finde es heraus :) –

Verwandte Themen