UNPKG

opencv

Version:
1,100 lines (785 loc) 31.6 kB
require("v8").setFlagsFromString('--expose_gc'); var gc = require("vm").runInNewContext('gc'); var fs = require('fs') , path = require('path') , test = require('tape') , cv = require('../lib/opencv'); var IMAGE_PATH = path.resolve(__dirname, '../examples/files', 'mona.png'); var VIDEO_PATH = path.resolve(__dirname, '../examples/files', 'motion.mov'); var TEMP_SAVE_PATH = path.resolve(__dirname, '../examples/tmp', 'out.jpg'); var TEMP_VIDEO_PATH = path.resolve(__dirname, '../examples/tmp', 'out.mp4'); // These tests check that every function that creates or modifies a Matrix handles its externally tracked memory correctly. // Since the memory tracker uses OpenCV's reference counting to determine when to tell Node about memory changes, // it is important that only Matrix objects that Javascript knows about retain references to internal OpenCV Mat objects. // Reference counts for newly created objects should ususally therefore be 1, and releasing them should alter the // externally tracked memory appropriately. // Note that garbage collection could run at any time, which could interfere with measurements of external memory, // so these tests manually run garbage collection as part of their setup to minimize this possibility. //******************** // Image Reading //******************** test("readImage", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = cv.readImage(IMAGE_PATH); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 1134000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("readImage creating a new 100x100 matrix", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = cv.readImage(100,100); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 80000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("readImage from data buffer", t=>{ gc(); var buffer = fs.readFileSync(IMAGE_PATH); var startingMemory = process.memoryUsage().external; var image = cv.readImage(buffer); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 1134000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("readImage (callback pattern)", t=>{ gc(); var startingMemory = process.memoryUsage().external; cv.readImage(IMAGE_PATH, (err, image) => { t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 1134000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("readImage creating a new 100x100 matrix (callback pattern)", t=>{ gc(); var startingMemory = process.memoryUsage().external; cv.readImage(100, 100, (err, image) => { t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 80000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("readImage from data buffer (callback pattern)", t=>{ gc(); var buffer = fs.readFileSync(IMAGE_PATH); var startingMemory = process.memoryUsage().external; cv.readImage(buffer, (err, image) => { t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 1134000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("readImageAsync", t=>{ gc(); var startingMemory = process.memoryUsage().external; cv.readImageAsync(IMAGE_PATH, (err, image) => { t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 1134000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("readImageAsync creating a new 100x100 matrix", t=>{ gc(); var startingMemory = process.memoryUsage().external; cv.readImageAsync(100, 100, (err, image) => { t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 80000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("readImageAsync from data buffer", t=>{ gc(); var buffer = fs.readFileSync(IMAGE_PATH); var startingMemory = process.memoryUsage().external; cv.readImageAsync(buffer, (err, image) => { t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 1134000); //image is tracked as external memory image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("video capture async", t=>{ gc(); var vid = new cv.VideoCapture(path.resolve(__dirname, '../examples/files', 'motion.mov')); var startingMemory = process.memoryUsage().external; vid.read( (err, im) => { t.equal(im.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 545280); //image is tracked as external memory im.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("video capture sync", t=>{ gc(); var vid = new cv.VideoCapture(path.resolve(__dirname, '../examples/files', 'motion.mov')); var startingMemory = process.memoryUsage().external; var im = vid.readSync(); t.equal(im.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 545280); im.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); //******************** // Matrix Constructors //******************** // Base constructor, doesn't actually allocate any memory test("Matrix()", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(); t.equal(image.getrefCount(), -1); t.equal(process.memoryUsage().external - startingMemory, 0); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); // Constructor with a size test("Matrix(int, int)", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 120000); //100 * 100 * size of CV_32FC3 (12) image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); // Constructor with a size and type test("Matrix(int, int, type)", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC1); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 10000); //100 * 100 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); // Constructor with a size, type, and initial values test("Matrix(int, int, type, [values])", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); // Constructor with an existing matrix and a region of interest test("Matrix(Matrix, x, y, w, h)", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(originalImage.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var image = new cv.Matrix(originalImage, 25, 25, 50, 50); //this should share memory with the original t.equal(image.getrefCount(), 2); //so the refcount goes up t.equal(process.memoryUsage().external - startingMemory, 30000); //but the memory usage does not originalImage.release(); t.equal(originalImage.getrefCount(), -1); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix.Zeros", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = cv.Matrix.Zeros(100, 100); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 80000); //100 * 100 * size of CV_64FC1 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix.Ones", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = cv.Matrix.Ones(100, 100); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 80000); //100 * 100 * size of CV_64FC1 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix.Eye", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = cv.Matrix.Eye(100, 100); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 80000); //100 * 100 * size of CV_64FC1 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); //******************** // Matrix Functions //******************** test("Matrix clone", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(originalImage.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var image = originalImage.clone(); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 60000); originalImage.release(); t.equal(originalImage.getrefCount(), -1); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix crop", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(originalImage.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 t.equal(originalImage.height(), 100); var image = originalImage.crop(25, 25, 50, 50); //crops share memory with the original t.equal(originalImage.height(), 100); t.equal(image.height(), 50); t.equal(image.getrefCount(), 2); t.equal(process.memoryUsage().external - startingMemory, 30000); originalImage.release(); t.equal(originalImage.getrefCount(), -1); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); //ROI in this implementation is basically the same thing as crop test("Matrix roi", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(originalImage.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 t.equal(originalImage.height(), 100); var image = originalImage.roi(25, 25, 50, 50); //ROIs share memory with the original t.equal(originalImage.height(), 100); t.equal(image.height(), 50); t.equal(image.getrefCount(), 2); t.equal(process.memoryUsage().external - startingMemory, 30000); originalImage.release(); t.equal(originalImage.getrefCount(), -1); t.equal(image.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000); image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix convertGrayscale", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 originalImage.convertGrayscale(); t.equal(process.memoryUsage().external - startingMemory, 10000); //grayscale takes less space t.equal(originalImage.getrefCount(), 1); originalImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix sobel", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var resultImage = originalImage.sobel(cv.Constants.CV_16S, 1, 1); t.equal(process.memoryUsage().external - startingMemory, 90000); //our original 30k image plus our new 60k one t.equal(originalImage.getrefCount(), 1); t.equal(resultImage.getrefCount(), 1); originalImage.release(); resultImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix copy", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var resultImage = originalImage.copy(0); t.equal(process.memoryUsage().external - startingMemory, 60000); //our original image plus our new one t.equal(originalImage.getrefCount(), 1); t.equal(resultImage.getrefCount(), 1); originalImage.release(); resultImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix flip", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var resultImage = originalImage.flip(0); t.equal(process.memoryUsage().external - startingMemory, 60000); //our original image plus our new one t.equal(originalImage.getrefCount(), 1); t.equal(resultImage.getrefCount(), 1); originalImage.release(); resultImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix dct", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_32F); t.equal(process.memoryUsage().external - startingMemory, 40000); //100 * 100 * 4 var resultImage = originalImage.dct(); t.equal(process.memoryUsage().external - startingMemory, 80000); //our original image plus our new one t.equal(originalImage.getrefCount(), 1); t.equal(resultImage.getrefCount(), 1); originalImage.release(); resultImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix idct", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_32F); t.equal(process.memoryUsage().external - startingMemory, 40000); //100 * 100 * 4 var resultImage = originalImage.idct(); t.equal(process.memoryUsage().external - startingMemory, 80000); //our original image plus our new one t.equal(originalImage.getrefCount(), 1); t.equal(resultImage.getrefCount(), 1); originalImage.release(); resultImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix add", t=>{ gc(); var startingMemory = process.memoryUsage().external; var src1 = new cv.Matrix.Ones(100, 100); var src2 = new cv.Matrix.Ones(100, 100); t.equal(process.memoryUsage().external - startingMemory, 160000); var resultMatrix = src1.add(src2); t.equal(resultMatrix.get(0,0), 2); //just making sure the result is correct t.equal(process.memoryUsage().external - startingMemory, 240000); t.equal(src1.getrefCount(), 1); t.equal(src2.getrefCount(), 1); t.equal(resultMatrix.getrefCount(), 1); src1.release(); src2.release(); resultMatrix.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix resize", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 image.resize(50, 50); t.equal(process.memoryUsage().external - startingMemory, 7500); //50 * 50 * 3 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix resize async", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 image.resize(50, 50, (err, resizedImage)=>{ t.equal(image.height(), 100); //we have both the original and the resized image t.equal(resizedImage.height(), 50); t.equal(image.getrefCount(), 1); t.equal(resizedImage.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 37500); image.release(); resizedImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("Matrix resize async edge case", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(1000, 1000, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 3000000); //100 * 100 * 3 image.resize(50, 50, (err, resizedImage)=>{ t.equal(image.getrefCount(), -1); //this happens second, image should have been released already t.equal(resizedImage.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 7500); resizedImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); image.release(); //this happens first }); test("Matrix threshold", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8U); t.equal(process.memoryUsage().external - startingMemory, 10000); //100 * 100 var resultImage = originalImage.threshold(1,1); t.equal(process.memoryUsage().external - startingMemory, 20000); //our original image plus our new one t.equal(originalImage.getrefCount(), 1); t.equal(resultImage.getrefCount(), 1); originalImage.release(); resultImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix adaptiveThreshold", t=>{ gc(); var startingMemory = process.memoryUsage().external; var originalImage = new cv.Matrix(100, 100, cv.Constants.CV_8U); t.equal(process.memoryUsage().external - startingMemory, 10000); //100 * 100 var resultImage = originalImage.adaptiveThreshold(255, 0, 0, 15, 2); t.equal(process.memoryUsage().external - startingMemory, 20000); //our original image plus our new one t.equal(originalImage.getrefCount(), 1); t.equal(resultImage.getrefCount(), 1); originalImage.release(); resultImage.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix meanStdDev", t=>{ gc(); var startingMemory = process.memoryUsage().external; var matrix = new cv.Matrix.Ones(100, 100, cv.Constants.CV_8UC3); t.equal(process.memoryUsage().external - startingMemory, 30000); var result = matrix.meanStdDev(); t.equal(result.mean.getrefCount(), 1); t.equal(result.stddev.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30048); matrix.release(); result.mean.release(); result.stddev.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix copyTo", t=>{ gc(); var startingMemory = process.memoryUsage().external; var smallImg = new cv.Matrix.Ones(25, 25, cv.Constants.CV_8UC3); var bigImg = cv.Matrix.Zeros(100, 100, cv.Constants.CV_8UC3); t.equal(process.memoryUsage().external - startingMemory, 30000 + 1875); smallImg.copyTo(bigImg, 0, 0); t.equal(smallImg.getrefCount(), 1); t.equal(bigImg.getrefCount(), 1); t.equal(process.memoryUsage().external - startingMemory, 30000 + 1875); smallImg.release(); bigImg.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix cvtColor", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 image.cvtColor("CV_BGR2GRAY"); t.equal(process.memoryUsage().external - startingMemory, 10000); //grayscale is smaller image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix split", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var result = image.split(); t.equal(process.memoryUsage().external - startingMemory, 60000); image.release(); t.equal(process.memoryUsage().external - startingMemory, 30000); result.forEach(m => m.release()); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix merge", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image1 = new cv.Matrix(100, 100, cv.Constants.CV_8UC1, [0]); var image2 = new cv.Matrix(100, 100, cv.Constants.CV_8UC1, [0]); var image3 = new cv.Matrix(100, 100, cv.Constants.CV_8UC1, [0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var result = new cv.Matrix(10,10); t.equal(process.memoryUsage().external - startingMemory, 30000 + 1200); result.merge([image1, image2, image3]); t.equal(process.memoryUsage().external - startingMemory, 60000); result.release(); image1.release(); image2.release(); image3.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix reshape", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 var result = image.reshape(2); t.equal(process.memoryUsage().external - startingMemory, 30000); //reshape does not copy data, so the allocated size hasn't changed image.release(); t.equal(process.memoryUsage().external - startingMemory, 30000); result.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix pyrDown", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 image.pyrDown(); t.equal(process.memoryUsage().external - startingMemory, 7500); //50 * 50 * 3 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); test("Matrix pyrUp", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(100, 100, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 30000); //100 * 100 * 3 image.pyrUp(); t.equal(process.memoryUsage().external - startingMemory, 120000); //200 * 200 * 3 image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); //******************** // Additional Asynchronous Matrix Functions //******************** test("Matrix toBuffer async edge case", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(1000, 1000, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 3000000); //100 * 100 * 3 image.toBufferAsync((err, buffer)=>{ t.equal(image.getrefCount(), -1); //this happens second, image should have been released already var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 33006); //the size of the buffer, which hasn't been released yet t.end(); }); image.release(); }); test("Matrix save async edge case", t=>{ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(1000, 1000, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 3000000); //100 * 100 * 3 image.saveAsync(TEMP_SAVE_PATH, (err, buffer)=>{ t.equal(image.getrefCount(), -1); //this happens second, image should have been released already var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); fs.unlinkSync(TEMP_SAVE_PATH); t.end(); }); image.release(); }); //******************** // Background Subtractors //******************** function testSyncBackgroundSubtractor(t, subtractor){ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(1000, 1000, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 3000000); //100 * 100 * 3 var output = subtractor.apply(image); t.equal(image.getrefCount(), 1); t.equal(output.getrefCount(), 1); image.release(); output.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); } function testAsyncBackgroundSubtractor(t, subtractor){ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(1000, 1000, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 3000000); //100 * 100 * 3 subtractor.apply(image, (err, output) => { t.equal(image.getrefCount(), 1); t.equal(output.getrefCount(), 1); image.release(); output.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); } function testAsyncBackgroundSubtractorEarlyRelease(t, subtractor){ gc(); var startingMemory = process.memoryUsage().external; var image = new cv.Matrix(1000, 1000, cv.Constants.CV_8UC3, [0,0,0]); t.equal(process.memoryUsage().external - startingMemory, 3000000); //100 * 100 * 3 subtractor.apply(image, (err, output) => { t.equal(image.getrefCount(), -1); t.equal(output.getrefCount(), 1); output.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); image.release(); } test("default background subtractor", t=>{ testSyncBackgroundSubtractor(t, new cv.BackgroundSubtractor()); }); test("MOG background subtractor", t=>{ testSyncBackgroundSubtractor(t, cv.BackgroundSubtractor.createMOG()); }); test("MOG2 background subtractor", t=>{ testSyncBackgroundSubtractor(t, cv.BackgroundSubtractor.createMOG2()); }); test("GMG background subtractor", t=>{ testSyncBackgroundSubtractor(t, cv.BackgroundSubtractor.createGMG()); }); test("default background subtractor async", t=>{ testAsyncBackgroundSubtractor(t, new cv.BackgroundSubtractor()); }); test("MOG background subtractor async", t=>{ testAsyncBackgroundSubtractor(t, cv.BackgroundSubtractor.createMOG()); }); test("MOG2 background subtractor async", t=>{ testAsyncBackgroundSubtractor(t, cv.BackgroundSubtractor.createMOG2()); }); test("GMG background subtractor async", t=>{ testAsyncBackgroundSubtractor(t, cv.BackgroundSubtractor.createGMG()); }); test("default background subtractor async early release", t=>{ testAsyncBackgroundSubtractorEarlyRelease(t, new cv.BackgroundSubtractor()); }); test("MOG background subtractor async early release", t=>{ testAsyncBackgroundSubtractorEarlyRelease(t, cv.BackgroundSubtractor.createMOG()); }); test("MOG2 background subtractor async early release", t=>{ testAsyncBackgroundSubtractorEarlyRelease(t, cv.BackgroundSubtractor.createMOG2()); }); test("GMG background subtractor async early release", t=>{ testAsyncBackgroundSubtractorEarlyRelease(t, cv.BackgroundSubtractor.createGMG()); }); //******************** // cascade classifier //******************** test("cascade classifier async", t=> { gc(); var startingMemory = process.memoryUsage().external; var image = new cv.readImage(path.resolve(__dirname, '../examples/files', 'mona.png')); t.equal(process.memoryUsage().external - startingMemory, 1134000); //100 * 100 * 3 var classifier = new cv.CascadeClassifier(cv.FACE_CASCADE); classifier.detectMultiScale(image, (err, faces) =>{ t.equal(image.getrefCount(), 1); image.release(); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); }); test("cascade classifier async early release", t=> { gc(); var startingMemory = process.memoryUsage().external; var image = new cv.readImage(path.resolve(__dirname, '../examples/files', 'mona.png')); t.equal(process.memoryUsage().external - startingMemory, 1134000); var classifier = new cv.CascadeClassifier(cv.FACE_CASCADE); classifier.detectMultiScale(image, (err, faces) =>{ t.equal(image.getrefCount(), -1); var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); t.end(); }); image.release(); }); //******************** // VideoWriter //******************** test("Video writer async edge case", t=>{ gc(); var startingMemory = process.memoryUsage().external; var reader = new cv.VideoCapture(VIDEO_PATH); reader.read((err, image)=>{ t.equal(process.memoryUsage().external - startingMemory, 545280); var writer = new cv.VideoWriter(TEMP_VIDEO_PATH, 'mp4v', 1, image.size(), true); writer.write(image, err=>{ t.equal(image.getrefCount(), -1); //this happens second, image should have been released already var endingMemory = process.memoryUsage().external; t.equal(endingMemory - startingMemory, 0); writer.release(); fs.unlinkSync(TEMP_VIDEO_PATH); t.end(); }); image.release(); }); }); //******************** // Face Recognizer //********************