diff --git a/.gitignore b/.gitignore index 3534ce0..160a3a9 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ npm-debug.log out*.jpg out*.png examples/*.avi +examples/tmp/* diff --git a/README.md b/README.md index 6d79131..7c2f4e6 100755 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ $ node-gyp rebuild ### Face Detection ```javascript -cv.readImage("./examples/test.jpg", function(err, im){ +cv.readImage("./examples/files/mona.png", function(err, im){ im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){ for (var i=0;i maxArea) { - var moments = contours.moments(i); - var cgx = Math.round(moments.m10/moments.m00); - var cgy = Math.round(moments.m01/moments.m00); - big.drawContour(contours, i, GREEN); - big.line([cgx - 5, cgy], [cgx + 5, cgy], RED); - big.line([cgx, cgy - 5], [cgx, cgy + 5], RED); - } - } + for(i = 0; i < contours.size(); i++) { + if(contours.area(i) > maxArea) { + var moments = contours.moments(i); + var cgx = Math.round(moments.m10 / moments.m00); + var cgy = Math.round(moments.m01 / moments.m00); + big.drawContour(contours, i, GREEN); + big.line([cgx - 5, cgy], [cgx + 5, cgy], RED); + big.line([cgx, cgy - 5], [cgx, cgy + 5], RED); + } + } - all.drawAllContours(contours, WHITE); + all.drawAllContours(contours, WHITE); - - big.save('./big.png'); - all.save('./all.png'); + big.save('./tmp/big.png'); + all.save('./tmp/all.png'); + console.log('Image saved to ./tmp/big.png && ./tmp/all.png'); }); diff --git a/examples/convert-image.js b/examples/convert-image.js new file mode 100755 index 0000000..7f62ff3 --- /dev/null +++ b/examples/convert-image.js @@ -0,0 +1,21 @@ +var cv = require('../lib/opencv'); + +cv.readImage('./files/mona.png', function(err, im) { + if (err) throw err; + if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size'); + + img_hsv = im.copy(); + img_gray = im.copy(); + + img_hsv.convertHSVscale(); + img_gray.convertGrayscale(); + + im.save('./tmp/nor.png'); + img_hsv.save('./tmp/hsv.png'); + img_gray.save('./tmp/gray.png'); + + img_crop = im.crop(50,50,250,250); + img_crop.save('./tmp/crop.png'); + + console.log('Image saved to ./tmp/{crop|nor|hsv|gray}.png'); +}); diff --git a/examples/convert_image.js b/examples/convert_image.js deleted file mode 100755 index db6d31a..0000000 --- a/examples/convert_image.js +++ /dev/null @@ -1,24 +0,0 @@ -var cv = require('../lib/opencv'); - - -cv.readImage("./mona.png", function(err, im) { - - img_hsv = im.copy(); - img_gray = im.copy(); - - - img_hsv.convertHSVscale(); - img_gray.convertGrayscale(); - - console.log(img_gray.pixel(100,100)); - - im.save("/tmp/nor.png"); - img_hsv.save("/tmp/hsv.png"); - img_gray.save("/tmp/gray.png"); - - img_crop = im.crop(50,50,250,250); - img_crop.save("crop.png"); - - console.log("Guardado"); -}); - diff --git a/examples/detect-shapes.js b/examples/detect-shapes.js index 1fa49c2..f465d23 100755 --- a/examples/detect-shapes.js +++ b/examples/detect-shapes.js @@ -1,9 +1,4 @@ -#!/usr/bin/env node - -// // Detects triangles and quadrilaterals -// - var cv = require('../lib/opencv'); var lowThresh = 0; @@ -11,42 +6,46 @@ var highThresh = 100; var nIters = 2; var minArea = 2000; -var BLUE = [0, 255, 0]; //B, G, R -var RED = [0, 0, 255]; //B, G, R -var GREEN = [0, 255, 0]; //B, G, R -var WHITE = [255, 255, 255]; //B, G, R +var BLUE = [0, 255, 0]; // B, G, R +var RED = [0, 0, 255]; // B, G, R +var GREEN = [0, 255, 0]; // B, G, R +var WHITE = [255, 255, 255]; // B, G, R -cv.readImage('./shapes.jpg', function(err, im) { +cv.readImage('./files/shapes.jpg', function(err, im) { + if (err) throw err; - var out = new cv.Matrix(im.height(), im.width()); + width = im.width() + height = im.height() + if (width < 1 || height < 1) throw new Error('Image has no size'); - im.convertGrayscale(); - im_canny = im.copy(); + var out = new cv.Matrix(height, width); + im.convertGrayscale(); + im_canny = im.copy(); + im_canny.canny(lowThresh, highThresh); + im_canny.dilate(nIters); - im_canny.canny(lowThresh, highThresh); - im_canny.dilate(nIters); + contours = im_canny.findContours(); - contours = im_canny.findContours(); + for (i = 0; i < contours.size(); i++) { - for(i = 0; i < contours.size(); i++) { + if (contours.area(i) < minArea) continue; - if(contours.area(i) < minArea) continue; + var arcLength = contours.arcLength(i, true); + contours.approxPolyDP(i, 0.01 * arcLength, true); - var arcLength = contours.arcLength(i, true); - contours.approxPolyDP(i, 0.01 * arcLength, true); + switch(contours.cornerCount(i)) { + case 3: + out.drawContour(contours, i, GREEN); + break; + case 4: + out.drawContour(contours, i, RED); + break; + default: + out.drawContour(contours, i, WHITE); + } + } - switch(contours.cornerCount(i)) { - case 3: - out.drawContour(contours, i, GREEN); - break; - case 4: - out.drawContour(contours, i, RED); - break; - default: - out.drawContour(contours, i, WHITE); - } - } - - out.save('./out.png'); + out.save('./tmp/detect-shapes.png'); + console.log('Image saved to ./tmp/detect-shapes.png'); }); diff --git a/examples/face-detection-rectangle.js b/examples/face-detection-rectangle.js new file mode 100755 index 0000000..f108eee --- /dev/null +++ b/examples/face-detection-rectangle.js @@ -0,0 +1,22 @@ +var cv = require('../lib/opencv'); + +var COLOR = [0, 255, 0]; // default red +var thickness = 2; // default 1 + +cv.readImage('./files/mona.png', function(err, im) { + if (err) throw err; + if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size'); + + im.detectObject('../data/haarcascade_frontalface_alt2.xml', {}, function(err, faces) { + if (err) throw err; + + for (var i = 0; i < faces.length; i++) { + face = faces[i]; + im.rectangle([face.x, face.y], [face.x + face.width, face.y + face.height], COLOR, 2); + } + + im.save('./tmp/face-detection-rectangle.png'); + console.log('Image saved to ./tmp/face-detection-rectangle.png'); + }); + +}); diff --git a/examples/face-detection.js b/examples/face-detection.js new file mode 100755 index 0000000..0cc5fee --- /dev/null +++ b/examples/face-detection.js @@ -0,0 +1,18 @@ +var cv = require('../lib/opencv'); + +cv.readImage("./files/mona.png", function(err, im){ + if (err) throw err; + if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size'); + + im.detectObject("../data/haarcascade_frontalface_alt.xml", {}, function(err, faces){ + if (err) throw err; + + for (var i = 0; i < faces.length; i++){ + var face = faces[i]; + im.ellipse(face.x + face.width / 2, face.y + face.height / 2, face.width / 2, face.height / 2); + } + + im.save('./tmp/face-detection.png'); + console.log('Image saved to ./tmp/face-detection.png'); + }); +}); diff --git a/examples/face-proxy.js b/examples/face-proxy.js index 93c04c1..541ba7b 100755 --- a/examples/face-proxy.js +++ b/examples/face-proxy.js @@ -1,46 +1,30 @@ -/* +// Face recognition proxy +var http = require('http'), + request = require('request'), + cv = require('../lib/opencv'); -Face recognition proxy +http.createServer(function(req, resp){ + var url = req.url.slice(1); + request({uri:url, encoding:'binary'}, function(err, r, body){ + if (err) return resp.end(err.stack); + if (!/image\//.test(r.headers['content-type'])) return resp.end('Not an image'); -*/ + cv.readImage(new Buffer(body, 'binary'), function(err, im){ + if (err) return resp.end(err.stack); + if (im.width() < 1 || im.height() < 1) return resp.end('Image has no size'); -var http = require('http') - , request = require('request') - , cv = require('../lib/opencv') - , face_cascade = new cv.CascadeClassifier("./data/haarcascade_frontalface_alt.xml") - - - - http.createServer(function(req, resp){ - var url = req.url.slice(1); - console.log(url); - - if (url.indexOf('http') != 0){ - return request({uri:'http://google.com'}).pipe(resp) - } + im.detectObject('../data/haarcascade_frontalface_alt.xml', {}, function(err, faces) { + if (err) return resp.end(err.stack); - // TODO make sure image - if (url.indexOf(".jpg", url.length - 4) !== -1 || - url.indexOf(".png", url.length - 4) !== -1){ - - request({uri:url, encoding:'binary'}, function(err, r, body){ - if (err) throw err; - - cv.readImage(new Buffer(body, 'binary'), function(err, im){ - im.faceDetect(im, {}, function(err, faces){ - for (var i=0;i>", x, ":" , rec) + console.log('>>', x, ':' , rec) if (x % 10 == 0){ m2.rectangle([rec[0], rec[1]], [rec[2], rec[3]]) - // m2.save('./out-motiontrack-' + x + '.jpg') + // m2.save('./out-motiontrack-' + x + '.jpg') } if (x<100) iter(); @@ -22,4 +24,3 @@ vid.read(function(err, mat){ } iter(); }) - diff --git a/examples/quad-crosses.js b/examples/quad-crosses.js index 3632f9f..341631f 100755 --- a/examples/quad-crosses.js +++ b/examples/quad-crosses.js @@ -1,9 +1,4 @@ -#!/usr/bin/env node - -// // Finds quadrilaterals and fills them with an X -// - var cv = require('../lib/opencv'); var lowThresh = 0; @@ -17,39 +12,41 @@ var RED = [0, 0, 255]; //B, G, R var GREEN = [0, 255, 0]; //B, G, R var WHITE = [255, 255, 255]; //B, G, R +cv.readImage('./files/quads.jpg', function(err, im) { + if (err) throw err; + if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size'); -cv.readImage('./quads.jpg', function(err, im) { + var out = im.copy(); - var out = im.copy(); + im.convertGrayscale(); + im_canny = im.copy(); - im.convertGrayscale(); - im_canny = im.copy(); + im_canny.canny(lowThresh, highThresh); + im_canny.dilate(nIters); - im_canny.canny(lowThresh, highThresh); - im_canny.dilate(nIters); + contours = im_canny.findContours(); - contours = im_canny.findContours(); + for (i = 0; i < contours.size(); i++) { - for(i = 0; i < contours.size(); i++) { + var area = contours.area(i); + if (area < minArea || area > maxArea) continue; - var area = contours.area(i); - if(area < minArea || area > maxArea) continue; + var arcLength = contours.arcLength(i, true); + contours.approxPolyDP(i, 0.01 * arcLength, true); - var arcLength = contours.arcLength(i, true); - contours.approxPolyDP(i, 0.01 * arcLength, true); + if (contours.cornerCount(i) != 4) continue; - if(contours.cornerCount(i) != 4) continue; + var points = [ + contours.point(i, 0), + contours.point(i, 1), + contours.point(i, 2), + contours.point(i, 3) + ] - var points = [ - contours.point(i, 0), - contours.point(i, 1), - contours.point(i, 2), - contours.point(i, 3) - ] + out.line([points[0].x,points[0].y], [points[2].x, points[2].y], RED); + out.line([points[1].x,points[1].y], [points[3].x, points[3].y], RED); + } - out.line([points[0].x,points[0].y], [points[2].x, points[2].y], RED); - out.line([points[1].x,points[1].y], [points[3].x, points[3].y], RED); - } - - out.save('./out.png'); + out.save('./tmp/quad-crosses.png'); + console.log('Image saved to ./tmp/quad-crosses.png'); }); diff --git a/examples/salt.js b/examples/salt.js index 9c22b6e..d3212b2 100755 --- a/examples/salt.js +++ b/examples/salt.js @@ -1,27 +1,20 @@ var cv = require('../lib/opencv'); - -cv.readImage("./mona.png", function(err, im) { - salt(im, 3000); - im.save("/tmp/salt.png"); +cv.readImage("./files/mona.png", function(err, im) { + salt(im, 1000); + im.save("./tmp/salt.png"); + console.log('Image saved to ./tmp/salt.png'); }); - - function salt(img, n) { + var channels; + if ((channels = img.channels()) != 3) return console.log('Image has only %s Channel. It\'s not possible to salt this image.', channels) - - if (img.channels() == 1) { - - console.log("1 Canales"); - } else if (img.channels() == 3) { - - for(k = 0; k < n; k ++) { - i = Math.random() * img.width(); - j = Math.random() * img.height(); - - img.set(j, i, 255); - } - } - + var width = img.width(); + var height = img.height(); + for(var i = 0; i < n; i ++) { + x = Math.random() * width; + y = Math.random() * height; + img.set(y, x, 255); + } } diff --git a/examples/take-face-pics.js b/examples/take-face-pics.js index 7f6efa2..418809b 100644 --- a/examples/take-face-pics.js +++ b/examples/take-face-pics.js @@ -1,31 +1,24 @@ -var cv = require('../lib/opencv') +var cv = require('../lib/opencv'); +var vid = new cv.VideoCapture(0); -var vid = new cv.VideoCapture(0) +vid.read(function(err, im){ + if (err) throw err; + im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){ + if (err) throw err; + if (!faces.length) return console.log("No Faces"); -var snap = function(){ - vid.read(function(err, im){ - im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){ - - if (!faces){ - console.log("No Faces") - return; - } - var face = faces[0] - , ims = im.size() - - var im2 = im.roi(face.x, face.y, face.width, face.height) - /* - im.adjustROI( - -face.y - , (face.y + face.height) - ims[0] - , -face.x - , (face.x + face.width) - ims[1]) - */ - im2.save('out.jpg') - }) - - - }); -} -snap() + var face = faces[0]; + var ims = im.size(); + var im2 = im.roi(face.x, face.y, face.width, face.height) + /* + im.adjustROI( + -face.y + , (face.y + face.height) - ims[0] + , -face.x + , (face.x + face.width) - ims[1]) + */ + im2.save('./tmp/take-face-pics.jpg') + console.log('Image saved to ./tmp/take-face-pics.jpg'); + }) +}); diff --git a/examples/tmp/.gitkeep b/examples/tmp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/warp-image.js b/examples/warp-image.js new file mode 100644 index 0000000..5b6d32d --- /dev/null +++ b/examples/warp-image.js @@ -0,0 +1,16 @@ +var cv = require('../lib/opencv'); + +cv.readImage("./mona.png", function(err, im) { + if (err) throw err; + + var width = im.width(); + var height = im.height(); + if (width < 1 || height < 1) throw new Error('Image has no size'); + + var srcArray = [0, 0, width, 0, width, height, 0, height]; + var dstArray = [0, 0, width * 0.9, height * 0.1, width, height, width * 0.2, height * 0.8]; + var xfrmMat = im.getPerspectiveTransform(srcArray, dstArray); + im.warpPerspective(xfrmMat, width, height, [255, 255, 255]); + im.save("./warp-image.png"); + console.log('Image saved to ./tmp/warp-image.png'); +}); diff --git a/examples/warp_image.js b/examples/warp_image.js deleted file mode 100644 index 9b11178..0000000 --- a/examples/warp_image.js +++ /dev/null @@ -1,23 +0,0 @@ -var cv = require('../lib/opencv'); - -cv.readImage("./mona.png", function(err, im) { - - var srcArray = [ - 0,0, - im.width(),0, - im.width(),im.height(), - 0,im.height()]; - var dstArray = [ - 0,0, - im.width()*.9,im.height()*.1, - im.width(),im.height(), - im.width()*.2,im.height()*.8]; - - var xfrmMat = im.getPerspectiveTransform(srcArray,dstArray); - img_warp = im.copy(); - img_warp.warpPerspective(xfrmMat,im.width,im.height,[255,255,255]); - - img_warp.save("/tmp/mona_warp.png"); - -}); - diff --git a/smoke/smoketest.js b/smoke/smoketest.js index 15ab1aa..d26d474 100755 --- a/smoke/smoketest.js +++ b/smoke/smoketest.js @@ -10,7 +10,7 @@ for (var i = 1; i< 41; i++){ cv.readImage("/Users/peterbraden/Downloads/orl_faces/s6/10.pgm", function(e, im){ - var facerec = cv.FaceRecognizer.createEigenFaceRecognizer(); + var facerec = cv.FaceRecognizer.createEigenFaceRecognizer(); //facerec.trainSync(trainingData); facerec.loadSync("/Users/peterbraden/Desktop/ORL") @@ -20,9 +20,7 @@ cv.readImage("/Users/peterbraden/Downloads/orl_faces/s6/10.pgm", function(e, im) */ -cv.readImage("examples/mona.png", function(e, mat){ +cv.readImage("./examples/files/mona.png", function(e, mat){ var th = mat.threshold(200, 200, "Threshold to Zero Inverted"); - th.save('out.png') - + th.save('./examples/tmp/out.png') }) - diff --git a/test/unit.js b/test/unit.js index 763ae2f..3c2c968 100755 --- a/test/unit.js +++ b/test/unit.js @@ -4,7 +4,7 @@ var vows = require('vows') assertDeepSimilar = function(res, exp){ for (var i = 0; i < res.length; i++){ - // res[i] = Math.round(res[i]/100)*100; + // res[i] = Math.round(res[i]/100)*100; } assert.deepEqual(res, exp) } @@ -34,27 +34,27 @@ vows.describe('Smoke Tests OpenCV').addBatch({ , '.Point imports': function(topic){ assert.ok(!!topic.Point) - } - + } + , '.Matrix imports': function(topic){ assert.ok(!!topic.Matrix) - } + } , 'importing library multiple times is ok' : function(){ var cv1 = require('../lib/opencv') , cv2 = require('../lib/opencv') - cv1.readImage('./examples/mona.png', function(){}); - cv2.readImage('./examples/mona.png', function(){}); + cv1.readImage('./examples/files/mona.png', function(){}); + cv2.readImage('./examples/files/mona.png', function(){}); } } , "Point" : { topic : require('../lib/opencv') - + , 'constructor' : function(cv){ assert.ok(!!new cv.Point(1, 2)) assert.throws(function () { cv.Point(1, 2)}, TypeError); // cannot call without new - } + } , 'accessors' : function(cv){ assert.equal(new cv.Point(1, 2).x, 1) @@ -144,20 +144,20 @@ vows.describe('Smoke Tests OpenCV').addBatch({ } , "toBuffer": function(cv){ - var buf = fs.readFileSync('./examples/mona.png') - + var buf = fs.readFileSync('./examples/files/mona.png') + cv.readImage(buf.slice(0), function(err, mat){ var buf0 = mat.toBuffer() - + assert.ok(buf0); //assert.equal(buf.toString('base64'), buf0.toString('base64')); }) } - + , "toBuffer Async": { topic: function(cv){ - var buf = fs.readFileSync('./examples/mona.png') + var buf = fs.readFileSync('./examples/files/mona.png') , cb = this.callback cv.readImage(buf.slice(0), function(err, mat){ var buff = mat.toBuffer(function(){ @@ -173,14 +173,14 @@ vows.describe('Smoke Tests OpenCV').addBatch({ } , "detectObject": { - + topic : function(){ var cv = require('../lib/opencv') , cb = this.callback - cv.readImage("./examples/mona.png", function(err, im){ + cv.readImage("./examples/files/mona.png", function(err, im){ im.detectObject(cv.FACE_CASCADE, {}, cb) - }) + }) } , "finds face": function(err, faces){ @@ -191,8 +191,8 @@ vows.describe('Smoke Tests OpenCV').addBatch({ } , ".absDiff and .countNonZero" : function(cv) { - cv.readImage("./examples/mona.png", function(err, im) { - cv.readImage("./examples/mona.png", function(err, im2){ + cv.readImage("./examples/files/mona.png", function(err, im) { + cv.readImage("./examples/files/mona.png", function(err, im2){ assert.ok(im); assert.ok(im2); @@ -226,20 +226,20 @@ vows.describe('Smoke Tests OpenCV').addBatch({ topic : require('../lib/opencv') , ".readImage from file": function(cv){ - cv.readImage("./examples/mona.png", function(err, im){ + cv.readImage("./examples/files/mona.png", function(err, im){ assert.ok(im); assert.equal(im.width(), 500); assert.equal(im.height(), 756) - assert.equal(im.empty(), false) + assert.equal(im.empty(), false) }) } , ".readImage from buffer" : function(cv){ - cv.readImage(fs.readFileSync('./examples/mona.png'), function(err, im){ + cv.readImage(fs.readFileSync('./examples/files/mona.png'), function(err, im){ assert.ok(im); assert.equal(im.width(), 500); assert.equal(im.height(), 756) - assert.equal(im.empty(), false) + assert.equal(im.empty(), false) }) } @@ -258,10 +258,10 @@ vows.describe('Smoke Tests OpenCV').addBatch({ topic : function(){ var cv = require('../lib/opencv') , self = this - - cv.readImage("./examples/mona.png", function(err, im){ + + cv.readImage("./examples/files/mona.png", function(err, im){ cascade = new cv.CascadeClassifier("./data/haarcascade_frontalface_alt.xml"); - cascade.detectMultiScale(im, self.callback)//, 1.1, 2, [30, 30]); + cascade.detectMultiScale(im, self.callback)//, 1.1, 2, [30, 30]); }) } @@ -289,7 +289,7 @@ vows.describe('Smoke Tests OpenCV').addBatch({ assert.equal(im.empty(), false); self.callback() }) - fs.createReadStream('./examples/mona.png').pipe(s); + fs.createReadStream('./examples/files/mona.png').pipe(s); } , "loaded" : function(im){ @@ -305,7 +305,7 @@ vows.describe('Smoke Tests OpenCV').addBatch({ , "write" : { topic: function(cv){ var s = new cv.ImageStream() - , im = fs.readFileSync('./examples/mona.png') + , im = fs.readFileSync('./examples/files/mona.png') , self = this; s.on('data', function(m){ @@ -330,14 +330,14 @@ vows.describe('Smoke Tests OpenCV').addBatch({ topic : function(){ var cv = require('../lib/opencv') , self = this - - cv.readImage('./examples/coin1.jpg', function(e, im){ - cv.readImage('./examples/coin2.jpg', function(e, im2){ + + cv.readImage('./examples/files/coin1.jpg', function(e, im){ + cv.readImage('./examples/files/coin2.jpg', function(e, im2){ self.callback(im, im2, cv) }) }) } - + , "create TrackedObject" : function(im, im2, cv){ var tracked = new cv.TrackedObject(im, [420, 110, 490, 170]); assert.ok(tracked); @@ -348,15 +348,15 @@ vows.describe('Smoke Tests OpenCV').addBatch({ assertWithinRanges(tracked.track(im2), [386, 112, 459, 166], 10); } } - + } , "putText": { topic: function() { var cv = require('../lib/opencv') , self = this - - cv.readImage('./examples/coin1.jpg', function(e, im){ + + cv.readImage('./examples/files/coin1.jpg', function(e, im){ self.callback(null, im); }); }, @@ -381,7 +381,7 @@ vows.describe('Smoke Tests OpenCV').addBatch({ im.putText("Some text", 0, y += 20, font, [rnd(), rnd(), rnd()]); }); - im.save("./examples/coin1-with-text.jpg"); + im.save("./examples/tmp/coin1-with-text.jpg"); } }