With 5G coming, it will take only 0.01 second to upload a 100KB image at a speed of about 100Mbps, so we can deploy almost everything including face recognition as a service on server-side and a light app on client-side. This post will demonstrate how to build a RESTful API for face recognition on Linux servers using Python Flask.
Face recognition is an awesome open source project for face recognition based on dlib, just as described by itself:
The world’s simplest facial recognition api for Python and the command line
With a few lines of Python code, you can compare faces, detect faces and find facial features.
For example, run the sample find_facial_features_in_picture.py (only 40 lines of code) for an Obama image, you can get all facial features drawn as below.
To install it on Linux servers, you can follow the steps in the face_recognition project on github, or just simply download the pre-configured VM.
Let’s define two APIs using the face_recognition package.
Two face recognition functions are defined for the two APIs as util in file face_util.py.
The first function compare_faces compares two image files and returns True if the faces in the two images are the same person.
import face_recognition as fr
def compare_faces(file1, file2):
# Load the jpg files into numpy arrays
image1 = fr.load_image_file(file1)
image2 = fr.load_image_file(file2)
# Get the face encodings for 1st face in each image file
image1_encoding = fr.face_encodings(image1)[0]
image2_encoding = fr.face_encodings(image2)[0]
# Compare faces and return True / False
results = fr.compare_faces([image1_encoding], image2_encoding)
return results[0]
The second function face_rec check if the face in the image file is a known face in the dataset, and return the name of the person. There are two known faces in this example.
import face_recognition as fr
# Each face is tuple of (Name,sample image)
known_faces = [('Obama','sample_images/obama.jpg'),
('Peter','sample_images/peter.jpg'),
]
def face_rec(file):
"""
Return name for a known face, otherwise return 'Uknown'.
"""
for name, known_file in known_faces:
if compare_faces(known_file,file):
return name
return 'Unknown'
With the above functions, we can easily define REST API with Flask as follows.
First API is face_match. It takes two image files from form data of a POST request, and calls compare_faces to check if they are a match, then returns a JSON format result.
from flask import Flask, request
import json
from face_util import compare_faces, face_rec
app = Flask(__name__)
@app.route('/face_match')
def face_match():
if request.method == 'POST':
# check if the post request has the file part
if ('file1' in request.files) and ('file2' in request.files):
file1 = request.files.get('file1')
file2 = request.files.get('file2')
ret = compare_faces(file1, file2)
resp_data = {"match": bool(ret)} # convert numpy._bool to bool for json.dumps
return json.dumps(resp_data)
# When debug = True, code is reloaded on the fly while saved
app.run(host='0.0.0.0', port='5001', debug=True)
The second API is face_rec, whichtakes one image file as input and calls face_rec to check if it is a known face, then returns the name of the person in JSON format.
@app.route('/face_rec')
def face_recognition():
if request.method == 'POST':
# check if the post request has the file part
if 'file' in request.files:
file = request.files.get('file')
name = face_rec(file)
resp_data = {'name': name }
return json.dumps(resp_data)
You can download the full flask_server_v1.py file here.
Install Flask module by pip install -U flask
, then run python flask_server_v1.py
to start the server API. The start-up output looks like below.
* Serving Flask app "flask_server_v1" (lazy loading)
...
* Debug mode: on
* Running on http://0.0.0.0:5001/ (Press CTRL+C to quit)
And you access these two API with below URL in POST form data format:
You can call the API using any programming languages. I just take Python as an example. It requires requests module which you can install by pip install -U requests
.
In the first example, we call face_match API with two images of the same person.
import requests
import json
def test_face_match():
url = 'http://127.0.0.1:5001/face_match'
# open file in binary mode
files = {'file1': open('sample_images/peter.jpg', 'rb'),
'file2': open('sample_images/peter2.jpg', 'rb')}
resp = requests.post(url, files=files)
print( 'face_match response:\n', json.dumps(resp.json()) )
if __name__ == '__main__':
test_face_match()
Run the example by python demo_client_part1.py
and you will get a response as follows:
{"match": true}
In the second example, we call face_rec API to find the name of a person.
import requests
import json
def test_face_rec():
url = 'http://127.0.0.1:5001/face_rec'
# open file in binary mode
files = {'file': open('sample_images/peter2.jpg', 'rb')}
resp = requests.post(url, files = files)
print( 'face_rec response:\n', json.dumps(resp.json()) )
if __name__ == '__main__':
test_face_rec()
Run the script and you will get a response like below:
{"name": "Peter"}
You can add more features to the API, for instance, to return face locations and facial features so that you can implement the same things on mobile devices as you can do on Linux servers.
I implemented a version to draw face location and facial features using REST API and you can download here if interested.
Thanks for reading to this end.
#python #flask #rest #api #linux