JPEG を爆速でデコードできる OpenCV をビルドして Python から使う

深層学習の計算のボトルネックGPU にできないことは、意外としょっちゅうである。結構よくあるのが、入力の読み込み・デコードがボトルネックになるパターンである。

JPEG データの場合、libturbojpeg というライブラリを使って読み込むと CPU 利用率がめっちゃ抑えられる。以下では、OpenCV を libturbojpeg を使うようにビルドして Python から叩く方法をまとめる。

ビルド

すっ飛ばしていきなり結論みたいになってますが、シェルスクリプトにまとめました。

install_opencv.sh · GitHub

libturbojpeg と OpenCV をビルドしてカレントディレクトリ下の .local ってディレクトリに配置します。Python は pyenv 使ってる想定で、今読み込まれてるバージョンを使ってビルドします。詳しくはスクリプト読んでちょ。

Python から読む

方法1: PYTHONPATH を通す

.local/lib/python3.6/site-packages/cv2.soPython から読めるようにする必要があるので、 PYTHONPATH にこのディレクトリを追加する。

export PYTHONPATH=/ほげほげ/ぴよぴよ/lib/python3.6/site-packages :$PYTHONPATH

あとは import cv2 ってやって怒られなければ OK。cv2.imread が爆速になってるはず。

方法2: Python の中で syspath を追加する

プロジェクトごとに違うビルドをしたりしてると、上みたいな設定をグローバルに適用することに抵抗があることがある。その場合は、ややお行儀が悪い感じがするが、実行する Python スクリプトの最初に上と同じような設定をしてやれば良い。下の関数を最初に他の import よりも前に呼んでおく。

def add_local_lib_dir_to_syspath():
    import sys
    import os

    local_lib_dir_path = os.path.join(
        os.path.dirname(__file__),
        '.local',
        'lib/python{}.{}/site-packages'.format(sys.version_info[0], sys.version_info[1]))
    sys.path.append(local_lib_dir_path)