mirror of
https://github.com/peterbraden/node-opencv.git
synced 2025-12-08 19:45:55 +00:00
1100 lines
31 KiB
JavaScript
1100 lines
31 KiB
JavaScript
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
|
|
//********************
|