12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # face-detection-node-opencv
2 |
3 | Real-time face detection using OpenCV, Node.js, and WebSockets.
4 |
5 | Click [here](http://youtu.be/v2SY0naPBFw) to see it in action.
6 |
7 | ## Requirements
8 |
9 | * [Node.js](http://nodejs.org/)
10 | * [OpenCV 3.4.0](http://opencv.org/)
11 | * May also work with older versions of OpenCV, but most recently tested with OpenCV 3.4.0
12 | * A webcam, e.g. laptop-integrated webcam, USB webcam
13 |
14 | ## Installing Node.js packages
15 |
16 | * Navigate to the `server` directory
17 | * To install the packages: `npm install`
18 |
19 | ## Running the demo
20 |
21 | * Make sure you are still in the `server` directory
22 | * To run the server: `node server.js`
23 | * To run the demo locally, open a browser and go to `localhost:8080`
24 |
25 | The app should be up and running!
26 |
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | // modules
2 | var express = require('express')
3 | , http = require('http')
4 | , morgan = require('morgan');
5 |
6 | // configuration files
7 | var configServer = require('./lib/config/server');
8 |
9 | // app parameters
10 | var app = express();
11 | app.set('port', configServer.httpPort);
12 | app.use(express.static(configServer.staticFolder));
13 | app.use(morgan('dev'));
14 |
15 | // serve index
16 | require('./lib/routes').serveIndex(app, configServer.staticFolder);
17 |
18 | // HTTP server
19 | var server = http.createServer(app);
20 | server.listen(app.get('port'), function () {
21 | console.log('HTTP server listening on port ' + app.get('port'));
22 | });
23 |
24 | // WebSocket server
25 | var io = require('socket.io')(server);
26 | io.on('connection', require('./lib/routes/socket'));
27 |
28 | module.exports.app = app;
--------------------------------------------------------------------------------
/client/app.js:
--------------------------------------------------------------------------------
1 | // MODIFY THIS TO THE APPROPRIATE URL IF IT IS NOT BEING RUN LOCALLY
2 | var socket = io.connect('http://localhost');
3 |
4 | var canvas = document.getElementById('canvas-video');
5 | var context = canvas.getContext('2d');
6 | var img = new Image();
7 |
8 | // show loading notice
9 | context.fillStyle = '#333';
10 | context.fillText('Loading...', canvas.width/2-30, canvas.height/3);
11 |
12 | socket.on('frame', function (data) {
13 | // Reference: http://stackoverflow.com/questions/24107378/socket-io-began-to-support-binary-stream-from-1-0-is-there-a-complete-example-e/24124966#24124966
14 | var uint8Arr = new Uint8Array(data.buffer);
15 | var str = String.fromCharCode.apply(null, uint8Arr);
16 | var base64String = btoa(str);
17 |
18 | img.onload = function () {
19 | context.drawImage(this, 0, 0, canvas.width, canvas.height);
20 | };
21 | img.src = 'data:image/png;base64,' + base64String;
22 | });
--------------------------------------------------------------------------------
/server/lib/routes/socket.js:
--------------------------------------------------------------------------------
1 | var cv = require('opencv');
2 |
3 | // camera properties
4 | var camWidth = 320;
5 | var camHeight = 240;
6 | var camFps = 10;
7 | var camInterval = 1000 / camFps;
8 |
9 | // face detection properties
10 | var rectColor = [0, 255, 0];
11 | var rectThickness = 2;
12 |
13 | // initialize camera
14 | var camera = new cv.VideoCapture(0);
15 | camera.setWidth(camWidth);
16 | camera.setHeight(camHeight);
17 |
18 | module.exports = function (socket) {
19 | setInterval(function() {
20 | camera.read(function(err, im) {
21 | if (err) throw err;
22 |
23 | im.detectObject('./node_modules/opencv/data/haarcascade_frontalface_alt2.xml', {}, function(err, faces) {
24 | if (err) throw err;
25 |
26 | for (var i = 0; i < faces.length; i++) {
27 | face = faces[i];
28 | im.rectangle([face.x, face.y], [face.width, face.height], rectColor, rectThickness);
29 | }
30 |
31 | socket.emit('frame', { buffer: im.toBuffer() });
32 | });
33 | });
34 | }, camInterval);
35 | };
36 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Esther Jun Kim
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------