var Stream = require('stream').Stream , Buffers = require('buffers') , util = require('util') , path = require('path') , os = require('os'); var cv = module.exports = require('./bindings'); var Matrix = cv.Matrix , ImageStream , ImageDataStream , ObjectDetectionStream , VideoStream; if (cv.CascadeClassifier) { Matrix.prototype.detectObject = function(classifier, opts, cb){ var face_cascade; opts = opts || {}; cv._detectObjectClassifiers = cv._detectObjectClassifiers || {}; if (!(face_cascade = cv._detectObjectClassifiers[classifier])){ face_cascade = new cv.CascadeClassifier(classifier); cv._detectObjectClassifiers[classifier] = face_cascade; } face_cascade.detectMultiScale(this, cb, opts.scale, opts.neighbors , opts.min && opts.min[0], opts.min && opts.min[1]); } } else { cv.Matrix.prototype.detectObject = function() { throw new Error("You need to install OpenCV with OBJDETECT module"); } } cv.Matrix.prototype.inspect = function(){ var size = (this.size()||[]).join('x'); return "[ Matrix " + size + " ]"; } // we use the Opencv constants naming convention to extract the number of bytes (8, 16, 32, 64), and the number of channels from constants names var getNumberOfBytesAndChannelsPerType = function(type){ var regExp = /CV_([0-9]+)([A-Z]+)([0-9]+)/; for(var k in cv.Constants) if(cv.Constants.hasOwnProperty(k) && k.match(regExp) && cv.Constants[k] === type){ var bytes, channels, dataType; k.replace(regExp, function(all, b, l, c){ bytes = b; channels = c; dataType = l[0] }); return { bytes : parseInt(bytes), channels : !isNaN(parseInt(channels)) && parseInt(channels), dataType : dataType, label : k }; } }; var getBufferMethodName = function(bytes, dataType, endianness, read){ var fnName; if(read){ fnName = "read"; } else { fnName = "write"; } if (bytes === 32 && (dataType === "F" || dataType === "S")){ if(dataType === "F"){ fnName += "Float"+endianness; } else {//dataType === "S" fnName += "Int32"+endianness; } } else if(bytes === 8){ fnName += (dataType === "U" ? "U" : "")+"Int8"; } else if(bytes === 16){ fnName += (dataType === "U" ? "U" : "")+"Int16"+endianness; } else { throw("This matrix type (CV_"+bytes+dataType+") is not compatible with fromArray/toArray") } return fnName; }; Matrix.fromArray = function(arr, type){ var n_bytes; var bytesAndChannels = getNumberOfBytesAndChannelsPerType(type); var bytes = bytesAndChannels.bytes; var channels = bytesAndChannels.channels; var dataType = bytesAndChannels.dataType; var label = bytesAndChannels.label; if(!Array.isArray(arr) ||!Array.isArray(arr[0]) || !Array.isArray(arr[0][0]) || (channels && arr[0][0].length !== channels)) { throw(new Error("Input array must be a 3-level array/matrix with size rows x cols x channels corresponding to dataType ("+label+")")); } if(!channels){ channels = 1; } var rows = arr.length; var cols = arr[0].length; var mat = new cv.Matrix(rows, cols, type); var n_bytes = bytes/8; var buf = new Buffer(rows * cols * channels * n_bytes); buf.fill(0); var fnName = getBufferMethodName(bytes, dataType, os.endianness(), false) for(var i=0;i