-
Notifications
You must be signed in to change notification settings - Fork 858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
terminating with uncaught exception when running in parallel #156
Comments
What functions are you calling? I've tried processing a couple of images in parallel through a REST API (built myself on top of node-opencv ) and it worked just fine. |
I'm calling function hasFaces (buffer, cb) {
opencv.readImage(buffer, function (err, image) {
if (err) { return cb(err); }
image.detectObject(opencv.FACE_CASCADE, {}, function (err, faces) {
if (err) { return cb(err); }
cb(null, (faces.length > 0));
});
});
} This function is iterated over a set of ~2000 buffers using async with a limit of 16 jobs in parallel. async.eachLimit(buffers, 16, hasFaces, function (err, result) {
if (err) { throw err; }
// result is array of Booleans
}); |
I first ran your example but instead of feeding it the buffers, I read images from my filesystem and it just worked fine. Then I looked at the error message closely and realized that it's not cascade detection issue at all. Unrecognized or unsupported array type OpenCV basically fails to decode your buffer into a valid image. Can you specify how you're populating your buffers? I remember I have to create a new (binary) Buffer before sending it off to node-opencv for proper decoding. It failed otherwise for me. Here's how I did it: // read your in whatever way, maybe just fetching the raw file say http://abc.com/img.png
var opencvBuffer = new Buffer(normalBuffer, 'binary');
opencv.readImage(opencvBuffer, function(err, image){}) Hope this helps. |
I just tried again and I'm very sure that the buffers are alright. I've tried rerunning the script numerous times, only changing the number of jobs that runs in parallel. It also seems like the more concurrency the earlier it crashes. Dragging it up to 128 makes it crash even before it has started running all those jobs. I have a total of 1798 images, as buffers loaded into memory, which makes it easy for me to test this out. How many files do you have? Could you try something like the code below and adjust the var fs = require('fs');
var async = require('async');
var CONCURRENCY = 16;
function hasFaces (buffer, cb) {
opencv.readImage(buffer, function (err, image) {
if (err) { return cb(err); }
image.detectObject(opencv.FACE_CASCADE, {}, function (err, faces) {
if (err) { return cb(err); }
cb(null, (faces.length > 0));
});
});
}
var list = fs.readdirSync('./photos');
var buffers = list.map(function (path) { return fs.readFileSync(path); });
async.eachLimit(buffers, CONCURRENCY, hasFaces, function (err, result) {
if (err) { throw err; }
console.log('IT WORKS!');
}); Thank you for taking time with this :) |
I also tried to remove the |
Don't know if this is relevant but I might have found a bug in the c++ code. Detecting faces is done with the help of The one that starts everything, this is called directly from javascript and is running on the main loop. In this case it comes from the call to This function will collect all the data needed and put it onto a The second function does all the actual work, it runs on a background thread. This function does, among other, three things. Create a new vector, The problem here is that The function that passes everything back to javascript land. It constructs an array out of the The problem here is that it might be garbage in the The only problem is that the error message doesn't really seem to indicate this exact problem. It's more like there is a similar problem but with the image data being |
Even more strangely, the code snippet you shared executes alright on my machine with ocv 2.4.9 but what's strange is that for the exact same image copied ~150 times in the folder which has just 1 face in it, detectObject could only find the face in 92 of them which means that the buffer indeed gets overwritten randomly. @peterbraden do you think it would impact performance if we jumble up the cascade load, image load and running the classifier into a single function? I'll create modify, try out and create a pull request if that works. @LinusU your assessment makes sense and the error does give us the reason but not exactly where and how it happens :) I'll ping on this thread once I fix it. |
@LinusU I need your advice: Instead of loading the cascade file for every buffer you send off -- if you want to do determine if a batch of images have faces in them or not, then it would make a lot more sense to load the cascade just once and then run cascade classifier on them at once (first just single-threaded CPU and then maybe multi-threaded CPU). Thoughts? For this, I propose a new function say |
I'm not too familiar with opencv but from my understanding the code currently just loads the cascade file once inside the The only gain I can see with a I also think that the use case will be limited since having all the photos in memory at the same time is quite bad for performance. That's why I was limiting the whole thing to 16 parallel works to begin with. Since photo collections often can have thousands of photos in them, it's just not a good idea to load them all into memory, then send them all into C++ land, then scan them all, one by one, to finally be able to send back a long array of booleans. The problem I talked about could be solved with a simple |
Okay, so I added in a test case (I didn't really get along with vows, can't I use assert in an async function? wtf?) and I actually got a segmentation fault which was very nice! It shows that I'm on the right track. Most of the times I get the usual I'm just going to clean up the code a bit and submit a patch with an added test. |
+1 |
+1 still experiencing this with opencv 2.4.13 while calling |
OK so the best way to avoid this error and avoid having your nodejs process crash (sometimes silenty with no error!) is to completely avoid async calls to Even though EDIT: as @LinusU pointed out, this seems to be a bug with opencv. |
I have also stumbled open this, node opencv can't handle parallell work on multiple images at the same time. |
@timbrandin: |
Whenever I try and process a large number of images (usually happens around image 150, I'm processing max 16 in parallel)
node-opencv
crashes and brings down the entire node process.If I decrease my parallel limit to 1 everything works as expected.
The text was updated successfully, but these errors were encountered: