mirror of
https://github.com/peterbraden/node-opencv.git
synced 2025-12-08 19:45:55 +00:00
commit
649df8f8de
@ -16,6 +16,8 @@ cv.readImage("./files/mona.png", function(err, im) {
|
||||
}
|
||||
img.save("./tmp/resize-async-image.png");
|
||||
console.log('Image saved to ./tmp/resize-async-image.png at '+img.width()+'x'+img.height());
|
||||
img.release();
|
||||
delete img;
|
||||
};
|
||||
|
||||
var newwidth = width*0.95;
|
||||
@ -25,6 +27,8 @@ cv.readImage("./files/mona.png", function(err, im) {
|
||||
if (Async){
|
||||
// note - generates a new image
|
||||
im.resize(newwidth, newheight, AfterResize);
|
||||
im.release(); // test release image before resize if done
|
||||
delete im;
|
||||
} else {
|
||||
// sync - note - modifies the input image
|
||||
im.resize(newwidth, newheight);
|
||||
|
||||
@ -3,9 +3,10 @@ var path = require('path'),
|
||||
|
||||
var bg = null;
|
||||
|
||||
require("v8").setFlagsFromString('--expose_gc');
|
||||
|
||||
var gc = require("vm").runInNewContext('gc');
|
||||
// gc stuff which we shojld not need with release() begin used
|
||||
//require("v8").setFlagsFromString('--expose_gc');
|
||||
//var gc = require("vm").runInNewContext('gc');
|
||||
|
||||
var do_sync = function(done){
|
||||
// When opening a file, the full path must be passed to opencv
|
||||
@ -17,15 +18,20 @@ var do_sync = function(done){
|
||||
vid.read(function(err, m2){
|
||||
if (err) throw err;
|
||||
var mat = bg.apply(m2);
|
||||
m2.release();
|
||||
delete m2;
|
||||
// mat is a monochrome img where moving objects are white
|
||||
// do something with the return data
|
||||
// we are done with the return data
|
||||
mat.release();
|
||||
delete mat;
|
||||
if (x++<100){
|
||||
//console.log("iter "+x);
|
||||
setTimeout(iter, 1);
|
||||
} else {
|
||||
delete vid;
|
||||
console.log("bg sync done");
|
||||
gc();
|
||||
// gc(); - no need to gc if we release both m2 and mat
|
||||
if (undefined !== done)
|
||||
done();
|
||||
}
|
||||
@ -45,7 +51,10 @@ var do_async = function(done){
|
||||
vid.read(function(err, m2){
|
||||
if (err) throw err;
|
||||
bg.apply(m2, function(err, mat){
|
||||
delete mat;
|
||||
// do something with the return data
|
||||
// we are done with the return data
|
||||
mat.release();
|
||||
delete mat;
|
||||
if (err) throw err;
|
||||
// mat is a monochrome img where moving objects are white
|
||||
if (x++<100){
|
||||
@ -54,11 +63,12 @@ var do_async = function(done){
|
||||
} else {
|
||||
console.log("bg async done");
|
||||
delete vid;
|
||||
gc();
|
||||
// gc(); - no need to gc if we release both m2 and mat
|
||||
if (undefined !== done)
|
||||
done();
|
||||
}
|
||||
});
|
||||
m2.release();
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@ -27,3 +27,33 @@ vid.read(function(err, mat) {
|
||||
});
|
||||
|
||||
|
||||
|
||||
// restart video read
|
||||
var vid2 = new cv.VideoCapture(path.join(__dirname, 'files', 'motion.mov'));
|
||||
|
||||
var filename2 = './tmp/output-async-'+new Date().getTime()+'.avi';
|
||||
var writer2 = null;
|
||||
var x = 0;
|
||||
|
||||
// do the same write async
|
||||
var iter = function () {
|
||||
vid2.read(function (err, m2) {
|
||||
if (writer2 === null)
|
||||
writer2 = new cv.VideoWriter(filename2, 'DIVX', vid2.getFPS(), m2.size(), true);
|
||||
|
||||
x++;
|
||||
writer2.write(m2, function(err){
|
||||
if (x < 100) {
|
||||
iter();
|
||||
} else {
|
||||
vid2.release();
|
||||
writer2.release();
|
||||
}
|
||||
});
|
||||
m2.release();
|
||||
delete m2;
|
||||
});
|
||||
};
|
||||
|
||||
// kick it off
|
||||
iter();
|
||||
|
||||
@ -313,13 +313,15 @@ public:
|
||||
AsyncBackgroundSubtractorWorker(
|
||||
Nan::Callback *callback,
|
||||
BackgroundSubtractorWrap *bg,
|
||||
Matrix *img) :
|
||||
cv::Mat &img_mat):
|
||||
Nan::AsyncWorker(callback),
|
||||
bg(bg),
|
||||
img(img) {
|
||||
img_mat(img_mat) { // note: this makes a new cv::Mat, and so increments the ref count for the data without copying it
|
||||
|
||||
}
|
||||
|
||||
~AsyncBackgroundSubtractorWorker() {
|
||||
// upon destroy, img_mat will reduce refcount on data by one
|
||||
}
|
||||
|
||||
// Executed inside the worker-thread.
|
||||
@ -330,9 +332,9 @@ public:
|
||||
// wait here if already in apply - auto-release on scope exit
|
||||
BGAutoMutex(bg->applymutex);
|
||||
#if CV_MAJOR_VERSION >= 3
|
||||
bg->subtractor->apply(this->img->mat, _fgMask);
|
||||
bg->subtractor->apply(this->img_mat, _fgMask);
|
||||
#else
|
||||
bg->subtractor->operator()(this->img->mat, _fgMask);
|
||||
bg->subtractor->operator()(this->img_mat, _fgMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -360,7 +362,7 @@ public:
|
||||
|
||||
private:
|
||||
BackgroundSubtractorWrap *bg;
|
||||
Matrix *img;
|
||||
cv::Mat img_mat;
|
||||
cv::Mat _fgMask;
|
||||
};
|
||||
|
||||
@ -399,8 +401,8 @@ NAN_METHOD(BackgroundSubtractorWrap::Apply) {
|
||||
}
|
||||
|
||||
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
|
||||
Matrix *_img = Nan::ObjectWrap::Unwrap<Matrix>(info[0]->ToObject());
|
||||
Nan::AsyncQueueWorker(new AsyncBackgroundSubtractorWorker( callback, self, _img));
|
||||
Matrix *_img = Nan::ObjectWrap::Unwrap<Matrix>(info[0]->ToObject());
|
||||
Nan::AsyncQueueWorker(new AsyncBackgroundSubtractorWorker( callback, self, _img->mat));
|
||||
return;
|
||||
} else { //synchronous - return the image
|
||||
|
||||
|
||||
@ -769,21 +769,22 @@ NAN_METHOD(Matrix::ToBuffer) {
|
||||
|
||||
class AsyncToBufferWorker: public Nan::AsyncWorker {
|
||||
public:
|
||||
AsyncToBufferWorker(Nan::Callback *callback, Matrix* matrix, std::string ext,
|
||||
AsyncToBufferWorker(Nan::Callback *callback, cv::Mat mat, std::string ext,
|
||||
std::vector<int> params) :
|
||||
Nan::AsyncWorker(callback),
|
||||
matrix(matrix),
|
||||
mat(mat), // dulipcate mat, adding ref, but not copying data
|
||||
ext(ext),
|
||||
params(params) {
|
||||
}
|
||||
|
||||
~AsyncToBufferWorker() {
|
||||
// mat is released, decrementing refcount
|
||||
}
|
||||
|
||||
void Execute() {
|
||||
std::vector<uchar> vec(0);
|
||||
// std::vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
|
||||
cv::imencode(ext, this->matrix->mat, vec, this->params);
|
||||
cv::imencode(ext, this->mat, vec, this->params);
|
||||
res = vec;
|
||||
}
|
||||
|
||||
@ -813,7 +814,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Matrix* matrix;
|
||||
cv::Mat mat;
|
||||
std::string ext;
|
||||
std::vector<int> params;
|
||||
std::vector<uchar> res;
|
||||
@ -853,7 +854,7 @@ NAN_METHOD(Matrix::ToBufferAsync) {
|
||||
}
|
||||
|
||||
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
|
||||
Nan::AsyncQueueWorker(new AsyncToBufferWorker(callback, self, ext, params));
|
||||
Nan::AsyncQueueWorker(new AsyncToBufferWorker(callback, self->mat, ext, params));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1046,9 +1047,9 @@ NAN_METHOD(Matrix::Save) {
|
||||
// https://github.com/rvagg/nan/blob/c579ae858ae3208d7e702e8400042ba9d48fa64b/examples/async_pi_estimate/async.cc
|
||||
class AsyncSaveWorker: public Nan::AsyncWorker {
|
||||
public:
|
||||
AsyncSaveWorker(Nan::Callback *callback, Matrix* matrix, char* filename) :
|
||||
AsyncSaveWorker(Nan::Callback *callback, cv::Mat mat, char* filename) :
|
||||
Nan::AsyncWorker(callback),
|
||||
matrix(matrix),
|
||||
mat(mat),
|
||||
filename(filename) {
|
||||
}
|
||||
|
||||
@ -1060,7 +1061,7 @@ public:
|
||||
// here, so everything we need for input and output
|
||||
// should go on `this`.
|
||||
void Execute() {
|
||||
res = cv::imwrite(this->filename, this->matrix->mat);
|
||||
res = cv::imwrite(this->filename, this->mat);
|
||||
}
|
||||
|
||||
// Executed when the async work is complete
|
||||
@ -1082,7 +1083,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Matrix* matrix;
|
||||
cv::Mat mat;
|
||||
std::string filename;
|
||||
int res;
|
||||
};
|
||||
@ -1099,7 +1100,7 @@ NAN_METHOD(Matrix::SaveAsync) {
|
||||
REQ_FUN_ARG(1, cb);
|
||||
|
||||
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
|
||||
Nan::AsyncQueueWorker(new AsyncSaveWorker(callback, self, *filename));
|
||||
Nan::AsyncQueueWorker(new AsyncSaveWorker(callback, self->mat, *filename));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1892,9 +1893,9 @@ cv::Rect* setRect(Local<Object> objRect, cv::Rect &result) {
|
||||
|
||||
class ResizeASyncWorker: public Nan::AsyncWorker {
|
||||
public:
|
||||
ResizeASyncWorker(Nan::Callback *callback, Matrix *image, cv::Size size, double fx, double fy, int interpolation) :
|
||||
ResizeASyncWorker(Nan::Callback *callback, cv::Mat image, cv::Size size, double fx, double fy, int interpolation) :
|
||||
Nan::AsyncWorker(callback),
|
||||
image(image),
|
||||
image(image), // here, the cv::Mat is duplicated, adding to refcount without data copy
|
||||
dest(NULL),
|
||||
size(size),
|
||||
fx(fx),
|
||||
@ -1908,12 +1909,13 @@ public:
|
||||
// could happen if NaN does not call HandleSuccess?
|
||||
delete dest;
|
||||
dest = NULL;
|
||||
// cv::Mat image will be deleted, which will reduce refcount
|
||||
}
|
||||
|
||||
void Execute() {
|
||||
try {
|
||||
dest = new Matrix();
|
||||
cv::resize(image->mat, dest->mat, size, fx, fy, interpolation);
|
||||
cv::resize(image, dest->mat, size, fx, fy, interpolation);
|
||||
success = 1;
|
||||
} catch(...){
|
||||
success = 0;
|
||||
@ -1973,7 +1975,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Matrix *image;
|
||||
cv::Mat image;
|
||||
Matrix *dest;
|
||||
cv::Size size;
|
||||
double fx;
|
||||
@ -2039,7 +2041,7 @@ NAN_METHOD(Matrix::Resize) {
|
||||
if (isAsync){
|
||||
REQ_FUN_ARG(numargs-1, cb);
|
||||
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
|
||||
Nan::AsyncQueueWorker(new ResizeASyncWorker(callback, self, size, fx, fy, interpolation));
|
||||
Nan::AsyncQueueWorker(new ResizeASyncWorker(callback, self->mat, size, fx, fy, interpolation));
|
||||
info.GetReturnValue().Set(Nan::Null());
|
||||
} else {
|
||||
try{
|
||||
|
||||
@ -90,10 +90,10 @@ NAN_METHOD(VideoWriterWrap::Release) {
|
||||
|
||||
class AsyncVWWorker: public Nan::AsyncWorker {
|
||||
public:
|
||||
AsyncVWWorker(Nan::Callback *callback, VideoWriterWrap *vw, Matrix *im) :
|
||||
AsyncVWWorker(Nan::Callback *callback, VideoWriterWrap *vw, cv::Mat mat) :
|
||||
Nan::AsyncWorker(callback),
|
||||
vw(vw),
|
||||
im(im) {
|
||||
mat(mat) {
|
||||
}
|
||||
|
||||
~AsyncVWWorker() {
|
||||
@ -104,7 +104,7 @@ public:
|
||||
// here, so everything we need for input and output
|
||||
// should go on `this`.
|
||||
void Execute() {
|
||||
this->vw->writer.write(im->mat);
|
||||
this->vw->writer.write(mat);
|
||||
}
|
||||
|
||||
// Executed when the async work is complete
|
||||
@ -126,7 +126,7 @@ public:
|
||||
|
||||
private:
|
||||
VideoWriterWrap *vw;
|
||||
Matrix* im;
|
||||
cv::Mat mat;
|
||||
};
|
||||
|
||||
NAN_METHOD(VideoWriterWrap::Write) {
|
||||
@ -137,7 +137,7 @@ NAN_METHOD(VideoWriterWrap::Write) {
|
||||
REQ_FUN_ARG(1, cb);
|
||||
|
||||
Nan::Callback *callback = new Nan::Callback(cb.As<Function>());
|
||||
Nan::AsyncQueueWorker(new AsyncVWWorker(callback, v, im));
|
||||
Nan::AsyncQueueWorker(new AsyncVWWorker(callback, v, im->mat));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user