Human beings have an innate ability to detect, process and recognize faces — we’re born with it. Computers can do it, too — it just takes some clever algorithms, reams of code and some training of the algorithms.
Face detection is the process of identifying faces in digital images. It shouldn’t be confused with facial recognition — i.e., trying to work out who someone is from a photograph — but it’s the first part of the process. Facial recognition is a huge topic for another time, but face detection is the subject of this article.
To illustrate the process, here’s an example image:
…and here’s what the face detection does:
(Original image from Wikipedia)
Applications of Face Detection
There are numerous applications of face detection. Some modern biometrics systems detect faces and then use facial recognition to compare those faces to images in their databases, in order to try and identify someone without having to resort to good old-fashioned passwords. Some cameras use face detection for auto focussing. And like so many things, it also has applications in marketing.
For the purposes of this tutorial, we’ll replicate a feature that you may well have used yourself if you’re a Facebook user. When you upload a photo of your friends, Facebook often shows it back to you with any faces highlighted, in order to prompt you to “tag” people in it. We’re going to build something similar.
A Little Background
Before we dig into the code, let’s look at some of the tools and concepts we’re going to be using.
OpenCV and the Viola-Jones Object Detection Algorithm
OpenCV (Open Source Computer Vision) is an open-source library of hundreds of computer vision algorithms. Although OpenCV is written in C++, we can use it in Node.js applications thanks to the opencv package.
Amongst the algorithms implemented in OpenCV is the Viola-Jones object detection framework, which is used to detect features in images.
Face detection is simply a sub-set of feature (object) detection, but the algorithm is geared towards the challenges involved in detecting faces specifically.
Of course when we talk about feature detection in this context, it’s nothing to do with the sort of feature detection provided by libraries such as Modernizr and yepnope!
First presented in a 2004 article by Paul Viola and Michael J. Jones, this approach has become the de facto standard for face detection.
You’ll find some additional resources on the framework listed under Further Reading later on in this tutorial.
Cascades and Classifiers
[author_more]
An important aspect of the Viola-Jones algorithm is a cascade of classifiers, which is described as “a cascade of boosted classifiers working with haar-like features”. In practical terms, what this means is that it’s a set of visual features that OpenCV has been “trained” to look for in an image, in order to identify a particular type of object — in our case, faces. You’ll find more information about cascades and classifiers in the documentation. A cascade designed specifically for identifying faces is provided for us, as we’ll see when we look at the implementation.
Installation
Before we can start playing with face detection, we need to install a few pre-requisites.
The easiest (and recommended) way to get up-and-running is to use Vagrant. You’ll find the necessary configuration and provisioning script in the repository which accompanies this article. If you use this approach, there’s no need to go through these installation steps.
Installing OpenCV
Linux (Debian-based systems)
OpenCV has a number of pre-requisites itself, which we can install using apt-get
:
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
There are also some optional dependencies:
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
The easiest way to install OpenCV itself it is to use apt-get
:
sudo apt-get install libopencv-dev
At time of writing, this installs version 2.4.8, although the latest 2.x version is 2.4.11 and there is currently a version 3.0.0. However, there are currently issues with the Node.js wrapper on version 3.0.0., so this version is just fine.
Building from Source
If you want to build from source, start by installing the dependencies listed above, then download and extract the files from the downloads page.
As noted above, there are currently issues with the 3.0.0. in conjunction with the Node.js module, so it’s best to download version 2.4.11.
Now we need to build it:
cd ~/opencv-2.4.11
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make
sudo make install
Be warned, that last step might take a while!
Windows
If you’re using Windows, installation is as simple as downloading and running an executable file from the website. You’ll find a direct link to the latest version (at time of writing) right here.
Mac OSX
The easiest way to install on OSX is to use Homebrew:
brew tap homebrew/science
brew install opencv
You’ll find further instructions here.
Imagemagick
You’ll also need Imagemagick, which is a dependency of the image-processing library we’re going to be using.
Debian-based Systems
apt-get install imagemagick
Mac OSX
brew install imagemagick
Windows
Download and run the appropriate Windows Binary Release — which is an executable file — from this page.
Building Our Application
A reminder that all the source code for this tutorial is available on Github.
Let’s start by defining a a few dependencies:
- We’re using express as the basis of our web application
- Handlebars is for templating, along with express-handlebars
- The lodash utility library
- multer is a middleware for handling file uploads
- easyimage is an image-handling package
- Lastly, we’re using async to try and avoid callback hell
So without further ado, here’s our package.json
:
{
"name": "sitepoint/face-detection",
"version": "1.0.0",
"description": "A simple application which demonstrates face detection in Node.js",
"main": "index.js",
"author": "Lukas White",
"license": "MIT",
"dependencies": {
"async": "^1.4.2",
"busboy": "^0.2.9",
"connect-busboy": "0.0.2",
"easyimage": "^2.0.3",
"express": "^4.13.3",
"express-handlebars": "^2.0.1",
"lodash": "^3.10.1",
"multer": "^1.0.3",
"opencv": "^3.0.0"
}
}
Install the dependencies with npm install
.
Next, create a few directories:
mkdir public
mkdir public/css
mkdir public/images
mkdir views
mkdir views/layouts
mkdir uploads
Now create a basic layout for our application (views/layouts/default.hbs
):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Face Detection Example</title>
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Face Detection Example</a>
</div>
</div>
</nav>
<div id="main" class="container">
{{{body}}}
</div>
</body>
</html>
I’m referencing the Bootstrap framework to prettify the application slightly, but this is optional. Either download the files yourself, or you’ll find them in the repository which accompanies this article.
Add some basic styles (public/css/styles.css
):
#main {
margin-top: 50px;
}
.frame {
position: relative;
}
.frame a {
display: block;
position: absolute;
border: solid 2px #fff;
border-radius: 50%;
}
.frame a:hover {
background: rgba(0,0,0,0.5);
}
Continue reading %Build a Face Detection App Using Node.js and OpenCV%