Senior PHP Developer at XSolve, former QA and .NET dev. A stickler for clean, testable and maintainable code.
Have you ever used an application to upload a profile picture? Sure you have. That picture then shows up with every reference to the user. In the systems we create, this function is a frequent requirement and as such, we’re used to it. However, recently we’ve been working on an app with an added requirement: the system must verify whether the photo sent by the user really contains a human face. What’s more, the system should also check if the face is sufficiently exposed if the photo isn’t too blurred, and that the person in the photo isn’t wearing sunglasses. As a result, we’ve created Face Validator – open source Symfony3 face detection bundle.
Our project team hasn’t dealt with the issue of facial recognition before so we decided to approach this task methodically, starting with an analysis of possible solutions. First, we looked into the availability of readymade facial recognition solutions we could implement in our system at a relatively low cost. We came across a few that could potentially meet our expectations:
Lambda Labs Face Recognition API
Google Vision API
MS Azure Face API
We tested all of them in order to select the best one, taking into consideration various factors: reliability, speed, and accuracy, as well as the costs of implementation and use.
Lambda Labs Face Recognition API
Lambda Labs REST API allows, among other things, facial recognition in a photo sent as a URL to public storage. It also offers face recognition and album algorithm training (using collections of tagged pictures). When it comes to detection, you receive the coordinates of several points on the face and its size, as well as whether or not the person is smiling. Unfortunately, it provides no data on the level of blurring or face rotation and it doesn’t detect whether the face is covered by something.
In the free version, you get 1,000 face detection requests and 1,000 face recognition requests.
After analyzing and testing this solution, we came to the conclusion that the data provided by this API is not sufficient to create a complex face validator. Besides, the free trial – in comparison with other competitive solutions – doesn’t offer enough requests.
Another solution we considered was OpenFace. This is an open source library written in Python which provides a convenient API for photo pre-processing (preparing photos for use in neural networks), model training, and classification. It’s a really flexible tool which can be useful both in facial recognition and clustering. It contains ready mechanisms which make it easier for developers to use neural networks for these purposes. It also provides pre-trained models which can shorten the training process. Also, thanks to its use of the Torch framework, actions that require high computing power are transferred to the graphics card.
OpenFace is certainly a great library which considerably simplifies the use of advanced tools for face classification, but face detection itself is a problem of a slightly different nature and cannot be easily handled by this tool.
Google Cloud Vision API
Google Cloud Vision API (REST, RPC) enables the detection of one or more faces in a photo sent directly as payload or as a URL to public storage. It offers details concerning the location of particular elements of the face in the picture in the form of coordinates. Besides this, it also provides information about the size and location of the square which contains the face and additional data, including the level of rotation in three axes and the emotions which have been recognized – joy, sadness, anger, and surprise. You can also learn what the levels of blurring and exposure are and if the person is wearing a hat.
The free version of the API offers, just like Lambda Labs, 1,000 requests per month. Face detection in Cloud Vision provides a lot of details about the location of particular points in the picture, which is very useful but not actually necessary for a validator. The levels of rotation, blurring, or exposure are undoubtedly positive features of this tool. There is no information about sunglasses, though. In fact, this API could be a good engine for our validator but we haven’t chosen it due to the small number of requests available in the free trial when compared to other solutions.
This is another REST API, offering two types of service: facial recognition and detection. In the case of recognition, you can train the model with your own tags. What interested us more was the API/faces/detect method: after you send a photo as an URL to a public storage or within the payload, you receive information about the location of the most important parts of the face and the square outline, the angle of face rotation in three axes, gender, estimated age, and the presence or absence of a smile. The API tells you if the person is wearing glasses too, differentiating between clear and dark lenses. Apart from that, it analyzes the person’s mood: anger, disgust, fear, joy, sadness, and surprise.
In comparison with the solutions analyzed above, this free trial looks more promising: you can send 5,000 reqs/month, 2,400 reqs/day, and 100 reqs/hour. SkyBiometry is a tool that can be successfully used to build a face validator, and the info it provides is really useful for our purposes. Still, there is no data about blurring, exposure, or hats. The free trial seems sufficient for small apps with low traffic.
Amazon offers a complex Rekognition REST API which uses neural networks for face detection and comparison, detection of offensive content, recognition of the faces of famous people, and classification with the option of model training with your own photos and tags.
The DetectFaces method allows you to detect all the faces in the payload photo or the one uploaded to S3 (PNG or JPG). For each face, the endpoint returns data concerning the estimated age (from… to…), square outline, coordinates of facial elements coordinates, face rotation in three axes, photo quality (focus and brightness), beard, mustache, smile, glasses (both corrective and sunglasses varieties), and emotions (joy, sadness, anger, confusion, disgust, surprise, and calmness).
The free trial offers 5,000 requests per month without additional daily or hourly limits. The data actually contains everything we could need to make a validator. The free trial, compared to the previous options, is the most profitable. This API seems to fit our profile perfectly and might help us build our validator. However, there is one solution left, offered by the Redmond giant.
MS Azure Face API
Just like most of the other solutions we’ve tested, Microsoft REST API offers both face detection and recognition. We’ve concentrated on the former to run our tests. The /detect API method for a JPEG, PNG, BMP, or GIF provides the following details: square outline coordinates, 27 face point coordinates, estimated age, gender, level of smiling, length of mustache, beard, and sideburns, type of glasses worn by the person (corrective, sunglasses, and swimming goggles), rotation in two axes, probability of emotions felt by the person (anger, contempt, disgust, fear, happiness, indifference, sadness, and surprise), hair color, baldness, makeup, face covering (if the person covers some element of his or her face, such as forehead, eyes, mouth), blurring, exposure, and noise.
The free trial offers 30,000 requests per month with a limit of 20 requests per minute. We’re really impressed by the number of details detected by Face API. Obviously, they contain all that our validator needs. Moreover, the free trial is more than enough for a small application.
After analyzing all the solutions, we decided to use the MS Azure Face API to build the face validator. Both in terms of the informativeness of the data and the price (or, actually, the options offered by the free version) made the Microsoft API an unrivaled choice. All the APIs were checked by us using sample photos. Face API proved to be reliable and fast when compared to the competition.
Implementation: Face Detection Open Source Bundle
We implemented the Face Validator in the form of a reusable, open source Symfony3 bundle. The code has been written in PHP 7.1, however, we decided to temporarily remove any changes which are incompatible with 7.0 to enable as many potential projects as possible to add our library to their dependencies.
Our goal was to make our list of dependencies short so that the solution could be used in projects based only on particular components of Symfony, not necessarily requiring the full framework.
The API client uses the Guzzle library, which is well-known and widely used by us.
To lighten the class of the validator, we’ve used a specification pattern to verify its particular conditions, so that the rules could be placed in separate, easily testable classes. Thanks to this approach, it is easier to expand the Face Validator with new conditions: you just need to add a new class implementing an adequate interface and register it in the dependency injection container.
Most classes have been tested by unit test. We’ve also managed to create an integration test, where a test kernel instance is built to test the functioning of the Face Validator in a working Symfony3 app. The tests are isolated from the actual Face API and its responses are mocked in order not to determine the test results by an external API.
The source code is available at GitHub. In README.md, you can find brief documentation containing a description of the Face Validator’s options, installation, and configuration.
Feel free to use it in your own projects, to contribute, and to share your own reflections, comments, and ideas. Your feedback is really welcome!
Featured image: Rokas Niparavičius via unsplash.com