2017-02-01 1 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 + + addon 귀하의 자바 스크립트 프로그램의 실행을 차단합니다.

하위 프로세스를 사용하여 기본 실행을 차단하지 않으므로 처리를 중단 할 수 있으므로 중단해서는 안됩니다.

는 충분한 정보가 있어야 당신은 여기 야하기 : https://nodejs.org/api/child_process.html

+0

비동기 사용 및 제한 방법은 어떻습니까? 그것이 충분할 것입니까? – vladimir999

+1

비동기식 lib가 새 스레드를 생성하는 한 실행이 중단되지 않습니다. 진정으로 비동기식이라면 새로운 스레드를 생성하는 과정을 캡슐화해야합니다. 그래서 그것을 풀어서 알아냅니다 :) –