Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenFace FeatureExtraction Docker Image #166

Open
SanBingYouYong opened this issue Sep 6, 2024 · 6 comments
Open

OpenFace FeatureExtraction Docker Image #166

SanBingYouYong opened this issue Sep 6, 2024 · 6 comments

Comments

@SanBingYouYong
Copy link

SanBingYouYong commented Sep 6, 2024

OpenFace provided a docker image to use and I extended based on it with conda and flask to provide an api access to get au.csv from videos.

The image is available on aliyun registry: docker pull registry.cn-hangzhou.aliyuncs.com/sanbingyouyong/openface_extract_flask:latest

  • run with docker run -d --name openface_auto -p 8601:8601 openface_extract_flask:latest

The request can be sent using the following Python codes:

with open(video_full_path, 'rb') as f:
    files = {'video': f}
    form = {'video_name': video_name}
    response = requests.post(openface_service_url, files=files, data=form)

And the response is sent with send_file(output_file_path, as_attachment=True) and you can save the csv file like this:

with open(os.path.join(DATA_DIR, f'{video_name}/au.csv'), 'w') as f:
        f.write(response.content.decode('utf-8'))

If people are interested I can also post the Dockerfile (I need to make one then since I commit the image from my working container) and also the flask .py file that runs the service. Or as a PR, idk.

References:
OpenFace docker image from its wiki
Why we need to set OPENBLAS_NUM_THREADS

@ezyfzy
Copy link

ezyfzy commented Sep 20, 2024

@SanBingYouYong this docker image works fine, will it be possible for you to share the dockerfile?

@SanBingYouYong
Copy link
Author

@SanBingYouYong this docker image works fine, will it be possible for you to share the dockerfile?

I currently have network difficulties testing dockerfiles (basically chances that they fail half way during building due to network errors) but here's the python file (and a shell script) that I put in the image, so basically you need to modify the OpenFace docker image to support running a flask application:

The Python file openface_extract.py:

from flask import Flask, request, send_file
import subprocess
import os


'''
copied into openface_auto as openface_extract.py
'''

app = Flask(__name__)

ROOT_DIR = os.path.dirname(os.path.abspath(__file__))

@app.route('/process_video', methods=['POST'])
def process_video():
    # 检查是否有文件在请求中
    if 'video' not in request.files:
        return "No video part", 400
    if 'video_name' not in request.form:
        return "No video name", 400

    video = request.files['video']
    video_name = request.form['video_name']

    # 如果用户没有选择文件,浏览器也会发送一个空的文件名
    if video.filename == '':
        return "No selected video", 400

    if video:
        # 保存文件到此目录
        file_path = os.path.join(ROOT_DIR, f"{video_name}.mp4")
        video.save(file_path)
        
        # command = ['build/bin/FeatureExtraction', '-f', file_path]  # not easy to know when does it finish
        command = ["./run_extraction.sh", file_path]  # remember to chmod +x

        # 执行命令
        try:
            # execute shell script
            subprocess.Popen(command, cwd=ROOT_DIR).wait()

            # check for output in ./processed/video_name.csv
            output_file_path = os.path.join(ROOT_DIR, 'processed', f"{video_name}.csv")
            if not os.path.exists(output_file_path):
                return f"Error processing video: output file not found", 500
        except subprocess.CalledProcessError as e:
            return f"Error processing video: {e}", 500

        response = send_file(output_file_path, as_attachment=True)

        # 删除原始文件
        os.remove(file_path)
        # delete processed file
        # basically video.avi  video.csv  video.hog  video_aligned  video_of_details.txt
        the_file_list = [
            f"{video_name}.avi",
            f"{video_name}.csv",
            f"{video_name}.hog",
            f"{video_name}_of_details.txt"
        ]
        the_dir = f"{video_name}_aligned"  # this is a directory! 
        for file in os.listdir(os.path.join(ROOT_DIR, 'processed')):
            if file in the_file_list:
                os.remove(os.path.join(ROOT_DIR, 'processed', file))
            if file == the_dir:
                os.system(f"rm -rf {os.path.join(ROOT_DIR, 'processed', file)}")
        
        # 返回处理后的文件
        return response

    return "No video to process", 400

if __name__ == '__main__':
    if not os.environ.get("OPENBLAS_NUM_THREADS"):
        os.environ["OPENBLAS_NUM_THREADS"] = "10"  # credit: github issue
    app.run(host='0.0.0.0', port=8601)

The shell script that it executes (so to track task status): run_extraction.sh:

#! /bin/bash

if [ $# -eq 0 ]; then
     echo "Usage: $0 <video_file>"
     exit 1
fi

VIDEO_FILE=$1

build/bin/FeatureExtraction -f $VIDEO_FILE

@ezyfzy
Copy link

ezyfzy commented Sep 20, 2024

@SanBingYouYong Thanks for the quick response. Can you suggest the way to add python3.10 in this image, I was only able to add python3.5 not above that.

@SanBingYouYong
Copy link
Author

@SanBingYouYong Thanks for the quick response. Can you suggest the way to add python3.10 in this image, I was only able to add python3.5 not above that.

IIRC I went with miniconda3 and installed flask and python=3.10 right in the base environment. Try with the following commands to get conda working in docker containers:

ENV PATH="/root/miniconda3/bin:${PATH}"

# SHELL ["conda", "run", "-n", "base", "/bin/bash", "-c"]  # if you want to use RUN to install new packages in the ENV
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "base"]
CMD ["python", "openface_extract.py"]

There might have been some other dependency issues but I'm not sure.

@ezyfzy
Copy link

ezyfzy commented Sep 20, 2024

Thanks a lot for your work on extending the openface image. It works now.

@ezyfzy
Copy link

ezyfzy commented Sep 27, 2024

Sharing my docker file here, so that others facing issue extending or using openface with latest versions of linux can use.

Dockerfile.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants