Deploy Python face recognition model on Heroku and use it from Flutter ①

We have deployed Python's powerful facial recognition model on Heroku so that it can be called from a mobile app.

Part 1 will introduce the code on the Python side and deployment to Heroku, and Part 2 will introduce the part that calls the deployed process with Flutter.

Please refer to the following article for the call part in the second Flutter. Deploy Python face recognition model to Heroku and use it from Flutter②

About the poster of this article

We are tweeting about application development utilizing face recognition on Twitter. https://twitter.com/studiothere2

The diary of application development is serialized in note. https://note.com/there2

Face recognition model

Library used

I am using Python face_recognition. https://github.com/ageitgey/face_recognition

The documentation is very rich and very easy to use. With an accuracy of 99.38% in the benchmark, you can expect performance equal to or better than humans.

Other libraries used

I don't think too much about it, but I chose the one that seems to be lightweight and is often used on Heroku.

--Web development framework: Flask --HTTP server: Gunicorn

Python source code commentary

It's the minimum necessary, but you can see the gist.

run.py


import face_recognition
from flask import Flask, jsonify, request, redirect
app = Flask(__name__)
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

First, import the required libraries and declare constants. The variable name of app is also used when starting Gunicorn.

run.py


@app.route('/')
def hello_world():
    return 'hello'

When called as root, it simply displays only hello. This is useful for checking if the server is alive.

run.py


def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

When the image file is sent, make sure that the extension of the file is png, jpg, jpeg, or gif. Other than these, face recognition processing is excluded.

run.py


@app.route('/embedding', methods=['GET', 'POST'])
def get_embedding():
    # Check if a valid image file was uploaded
    if request.method == 'POST':
        if 'file' not in request.files:
            print("file not in request.files")
            return redirect(request.url)

        file = request.files['file']

        if file.filename == '':
            print("file name is blank")
            return redirect(request.url)

This is the main face recognition processing unit. Call it with / embedding. Only when the input type is file and the file name is one of the above png, jpg, jpeg, gif by POST. Otherwise, redirect back to the caller. In that case, the response code will be 302.

run.py


        if file and allowed_file(file.filename):
            print("file found")

            # The image file seems valid! Detect faces and return the result.
            img = face_recognition.load_image_file(file)
            emb = face_recognition.face_encodings(img)[0]
            return jsonify(emb.tolist())

If it has been POSTed in the correct file format, have face_recognition read the file and use it to get the Embedding of the 128-dimensional Float. With this embedding, you can calculate the similarity with other faces. Since this part is implemented separately on the mobile application side, only the embedded facial feature amount information is returned on the Python side. The return value of face_recognition is a Numpy array, so you need to call tolist () to make it a Python array. I will return the Jsonized version of it.

run.py


    # If no valid image file was uploaded, show the file upload form:
    return '''
    <!doctype html>
    <title>upload</title>
    <h1>Please select image and upload</h1>
    <form method="POST" enctype="multipart/form-data">
      <input type="file" name="file">
      <input type="submit" value="Upload">
    </form>
    '''

When called by GET, HTML for file upload is output so that the file can be uploaded directly.

run.py


if __name__ == "__main__":
    app.run(host='0.0.0.0')

In the main process, start Flask. By setting host to 0.0.0.0, you can use it with the URL of the Heroku deployment destination.

Operation check

pip install -r requirements.txt

The required libraries are put together in requirements.txt, so you can install them all together with the above command. This requirements.txt is also required when deploying to Heroku. Depending on the version, there was information that it could not be deployed successfully on Heroku unless it was installed in the order of cmake, dlib, face_recognition, so I wrote it in requirements.txt as follows.

requirements.txt


boost==0.1
cmake
boost-py
dlib
face_recognition_models
face-recognition
Flask==1.1.2
gunicorn==20.0.4

Try launching it locally using gunicorn.

gunicorn run:app --log-file -

If it starts up successfully, you should see something like the following.

$ gunicorn run:app --log-file -
[2020-05-15 09:02:24 +0900] [11143] [INFO] Starting gunicorn 20.0.4
[2020-05-15 09:02:24 +0900] [11143] [INFO] Listening at: http://127.0.0.1:8000 (11143)
[2020-05-15 09:02:24 +0900] [11143] [INFO] Using worker: sync
[2020-05-15 09:02:24 +0900] [11146] [INFO] Booting worker with pid: 11146

Let's open http://127.0.0.1:8000 in your browser. If "hello`" is displayed, it is successful.

Next, when you access http://127.0.0.1:8000/embedding, you will see the HTML for file selection as shown below. Try uploading a human face image file.

image.png

If you see an array of 128 Float as shown below, you are successful. This is the content of Embedding, which is the feature of the uploaded image.

image.png

Cloud environment

Using Heroku

https://jp.heroku.com/

I chose Heroku as the destination for deploying the web service. I chose Heroku because it's available in Python, it's easy to deploy and scale, and I felt it was reasonably priced. You can use it for free if you use it as a trial.

As a countermeasure, I also considered Firebase's Cloud Function, but since this model will take some load to load, I thought that the VM type that is always running is better than the Cloud Function that is started every time.

If Heroku is also a free version, the instance will drop if it is not used for 30 minutes and it will start when calling, but if you use the paid version, the instance will not drop. You can move to the paid version if necessary.

Deploy to Heroku

Deploying is not difficult. You can register as a user on Heroku and follow the setup steps below. https://devcenter.heroku.com/articles/getting-started-with-python

Install Heroku command line tools.

sudo snap install heroku --classic

Log in to Heroku. The browser will be launched and you can log in from the browser.

heroku login

Register the app on Heroku. The app will be registered with a suitable name and can be confirmed on the Heroku dashboard.

heroku create

Create a Procfile. This file is a file that teaches Heroku how to start the server. Write the instruction to start gunicorn as WEB as follows.

web: gunicorn run:app --log-file -

That's all for preparation. Then push it to heroku's repository with the git command and it will be deployed.

git push heroku master

Now it will be deployed on Heroku and the URL will be displayed, so please access that URL and check that it works.

Please note that the first deployment will take a considerable amount of time. Especially since dlib is a library written in C ++ and needs to be compiled, I had to wait a long time to complete the installation. It may have taken about 30 minutes. If it doesn't end with an error, feel free to wait.

Next time, I would like to introduce the part that calls this WEB service from Flutter.

Recommended Posts

Deploy Python face recognition model on Heroku and use it from Flutter ②
Deploy Python face recognition model on Heroku and use it from Flutter ①
Deploy and use the prediction model created in Python on SQL Server
Read and use Python files from Python
Use fastText trained model from Python
Install mecab on Sakura shared server and call it from python
Deploy a Python app on Google App Engine and integrate it with GitHub
Firebase: Use Cloud Firestore and Cloud Storage from Python
PHP and Python integration from scratch on Laravel
Until you use PhantomJS with Python on Heroku
Use python on Raspberry Pi 3 and turn on the LED when it gets dark!
Install selenium on Mac and try it with python
I sent regular emails from sendgrid on heroku, on python
Get mail from Gmail and label it with Python3
Ubuntu 20.04 on raspberry pi 4 with OpenCV and use with python
Use thingsspeak from python
Use fluentd from python
Use MySQL from Python
Use MySQL from Python
Use BigQuery from python.
Use mecab-ipadic-neologd from python
Install Mecab and CaboCha on ubuntu16.04LTS so that it can be used from python3 series
Put Ubuntu in Raspi, put Docker on it, and control GPIO with python from the container
How to deploy the easiest python textbook pybot on Heroku
A note on touching Microsoft's face recognition API in Python
Install pyenv on MacBook Air and switch python to use
I tried face recognition from the video (OpenCV: python version)
[Python] I installed the game from pip and played it
Python on Ruby and angry Ruby on Python
Use MySQL from Anaconda (python)
Deploy masonite app on Heroku 2020
Use django model from interpreter
Try face recognition with Python
Use Python on Windows (PyCharm)
Use e-Stat API from Python
processing to use notMNIST data in Python (and tried to classify it)
How to install OpenCV on Cloud9 and run it in Python
Get data from MySQL on a VPS with Python 3 and SQLAlchemy
[Python + heroku] From the state without Python to displaying something on heroku (Part 1)
Install lp_solve on Mac OS X and call it with python.
[Python + heroku] From the state without Python to displaying something on heroku (Part 2)
Everything from building a Python environment to running it on Windows
I want to pass an argument to a python function and execute it from PHP on a web server