Hello!

In some scenarios with web application development it may be necessary to be able to detect the facial features of a photo. For example an application that detects how many people are in a picture, or perhaps an app that modifies the faces of the people in a photo.

Whether you’re making a mobile app or a web application that does this, there are many methods to use. There is 3rd party API services such as Face Recognition API.

In our scenario we wanted to build an interface where images could be uploaded via a POST and the X and Y coordinates of the face, eyes nose and mouth regions plotted or returned as a json response. This way if you wanted to build a mobile and web application, they could both use the detection service to return the plot points in a centralized way.

We decided to test the PHP Facedetect extension

git clone https://github.com/infusion/PHP-Facedetect.git cd PHP-Facedetect phpize ./configure make && make install echo "extension=facedetect.so" >> /etc/php.ini apachectl graceful 1 2 3 4 5 6 7 git clone https : //github.com/infusion/PHP-Facedetect.git cd PHP - Facedetect phpize . / configure make && make install echo "extension=facedetect.so" >> / etc / php . ini apachectl graceful

Once installed and activated in your php.ini , you can start using the face detection functions. Basically how it works is you pass the image path and an accompanying XML document containing a number of algorithms for detecting the areas of the face (see OpenCV library).

What you might want to do is utilize the detection library to identify a few core things, namely the number of people that are detected in the picture, including the different parts of each found face.

$total = face_count($path . '/file.jpg',$path . '/haarcascade_frontalface_alt.xml'); 1 $ total = face_count ( $ path . '/file.jpg' , $ path . '/haarcascade_frontalface_alt.xml' ) ;

The $total variable will contain an integer that represents the number of people detected in a picture. You can use this number as a core condition for subsequent processing, or you can ignore it. Assuming, for simplicity’s sake, that there is only one person in the photo, you can do subsequent facial feature detections :

$face_coord = face_detect($path . '/file.jpg',$path . '/haarcascade_frontalface_alt.xml'); $eye_coord = face_detect($path . '/file.jpg',$path . '/haarcascade_mcs_eyepair_small.xml'); $mouth_coord = face_detect($path . '/file.jpg',$path . '/Mouth.xml'); $nose_coord = face_detect($path . '/file.jpg',$path . '/haarcascade_mcs_nose.xml'); 1 2 3 4 $ face_coord = face_detect ( $ path . '/file.jpg' , $ path . '/haarcascade_frontalface_alt.xml' ) ; $ eye_coord = face_detect ( $ path . '/file.jpg' , $ path . '/haarcascade_mcs_eyepair_small.xml' ) ; $ mouth_coord = face_detect ( $ path . '/file.jpg' , $ path . '/Mouth.xml' ) ; $ nose_coord = face_detect ( $ path . '/file.jpg' , $ path . '/haarcascade_mcs_nose.xml' ) ;

One of the above variables, when detection is completed, will contain an array of coordinates. In the image at the top of this post, the mouth coordinates will be represented by a series of X & Y axis coordinates as well as W (width) and H (height) variables do determine the content area of the detected face point. In the specific example of the image at the top of this post, the mouth area is represented by the following coordinates :

Array ( [0] => Array ( [x] => 213 [y] => 351 [w] => 106 [h] => 64 ) [1] => Array ( [x] => 52 [y] => 375 [w] => 71 [h] => 43 ) [2] => Array ( [x] => 274 [y] => 232 [w] => 98 [h] => 59 ) [3] => Array ( [x] => 230 [y] => 321 [w] => 78 [h] => 47 ) [4] => Array ( [x] => 217 [y] => 9 [w] => 98 [h] => 59 ) [5] => Array ( [x] => 134 [y] => 223 [w] => 129 [h] => 78 ) ) 1 Array ( [ 0 ] = > Array ( [ x ] = > 213 [ y ] = > 351 [ w ] = > 106 [ h ] = > 64 ) [ 1 ] = > Array ( [ x ] = > 52 [ y ] = > 375 [ w ] = > 71 [ h ] = > 43 ) [ 2 ] = > Array ( [ x ] = > 274 [ y ] = > 232 [ w ] = > 98 [ h ] = > 59 ) [ 3 ] = > Array ( [ x ] = > 230 [ y ] = > 321 [ w ] = > 78 [ h ] = > 47 ) [ 4 ] = > Array ( [ x ] = > 217 [ y ] = > 9 [ w ] = > 98 [ h ] = > 59 ) [ 5 ] = > Array ( [ x ] = > 134 [ y ] = > 223 [ w ] = > 129 [ h ] = > 78 ) )

Well – what do you do with these coordinates? It depends on why you are wanting to do this in the first place! In the context of a web application such as Facebook, the facial recognition is designed to detect faces for the purposes of tagging in uploaded photos. But it has also been recently published that facebook is now detecting who is in your pictures to automatically “pre-tag” your photos for you. Scary isnt it?

If you wanted to have your web application conduct image modifications such as an app that “ages” your photo, you could work with those coordinates and modify the mouth, nose, eyes and face regions of an image separately to dynamically modify an image.

Combining Javascript and jQuery technology with this PHP extension, you could do some fancy dynamic changes to the image in question :

// eyes foreach ($eye_coord as $arr) { echo "var recteye = document.createElement('div'); document.querySelector('.demo-container').appendChild(recteye); recteye.classList.add('recteye'); recteye.id = 'recteye'; recteye.style.width = " . $arr['w'] . " + 'px'; recteye.style.height = " . $arr['h'] . " + 'px'; recteye.style.left = (img.offsetLeft + " . $arr['x'] . ") + 'px'; recteye.style.top = (img.offsetTop + " . $arr['y'] . ") + 'px';"; } 1 2 3 4 5 6 7 8 9 10 11 // eyes foreach ( $ eye_coord as $ arr ) { echo "var recteye = document.createElement('div'); document.querySelector('.demo-container').appendChild(recteye); recteye.classList.add('recteye'); recteye.id = 'recteye'; recteye.style.width = " . $ arr [ 'w' ] . " + 'px'; recteye.style.height = " . $ arr [ 'h' ] . " + 'px'; recteye.style.left = (img.offsetLeft + " . $ arr [ 'x' ] . ") + 'px'; recteye.style.top = (img.offsetTop + " . $ arr [ 'y' ] . ") + 'px';" ; }

What are we doing in the above code snippet? Well, while still in PHP, we are outputting jQuery code to append CSS styling in order to create a rectangle region that outlines the recently detected eye area. The CSS classes referenced are very simple, defining a border and color that is then shaped by the dynamically generated variables of X,Y,W,H coordinates / integers.

The recteye class is simply defined as something like this :

.recteye { border: 1px solid #a64ceb; left: -1000px; position: absolute; top: -1000px; z-index:10010; } 1 2 3 4 5 6 7 . recteye { border : 1px solid #a64ceb; left : - 1000px ; position : absolute ; top : - 1000px ; z - index : 10010 ; }

Once the code is run against the image, the rectangle is generated over the eye area and you have something similar to the image at the top of this post. Pretty easy , right? 🙂