さて、OpenCVで画像をロードするのを速くしたくて、JPEGについてはlibjpeg-turboというのが使えることを知りました。
libjpeg-turboはlibjpegをSIMDなどによって高速化したものでAPIレベルの互換性を保っています。
条件が良ければデコードが数倍速くなるということで、これをOpenCVに組み込んでビルドする方法をメモ。
OpenCVビルド職人の朝は早い。「contribが必要な仕事だと緊張が走るね」プロセッサやOSに応じて最適な設定でビルドするのが彼の仕事だ。ARMへは人一倍のこだわりを見せる。「CUDAさえ切ればものの数分で終わるんだがな…」そう語る背中には、積み重ねた経験値の高さがにじむ。
— おさかなさん (@sakanazensen) 2017年2月1日
libjpeg-turboのダウンロード&ビルド
最近のubuntuの場合はapt-getで入るそうです。ここでは野良ビルドから説明していきます。
libjpeg-turboの最新版はこちらでダウンロードできます。
https://sourceforge.net/projects/libjpeg-turbo/files/
% sudo apt-get install nasm % cd /tmp % wget https://jaist.dl.sourceforge.net/project/libjpeg-turbo/1.5.1/libjpeg-turbo-1.5.1.tar.gz % tar xf libjpeg-turbo-1.5.1.tar.gz % cd libjpeg-turbo-1.5.1 % CFLAGS='-O3' ./configure --prefix=$HOME % make % make install
$HOME下のincludeおよびlibの中にインストールされます。
make中、下記のようなエラー?が出ましたが、手元では放置して問題なさそうでした(放置せずに頑張ったらもっと速くなる、とかあるのかもしれませんが、とりあえず深追いしていません)。
libtool: error: ignoring unknown tag NASM
OpenCVのビルド
基本的には手動でOpenCVをビルドするときに、cmakeに対していくつかのパラメータを追加するのみです。
% cd /tmp % git clone https://github.com/opencv/opencv.git % cd opencv % mkdir build % cd build % cmake -D WITH_JPEG=ON -D BUILD_JPEG=OFF -D JPEG_INCLUDE_DIR=$HOME/include -D JPEG_LIBRARY=$HOME/lib/libjpeg.so .. % make -j128 % make install
BUILD_JPEGは3rdpartyに含まれたlibjpegをOpenCVと一緒にビルドする設定なのでオフにします。
JPEG_INCLUDE_DIRおよびJPEG_LIBRARY_PATHに指定するパスは、libjpeg-turboのビルド時に指定した場所に従ってよろしく書き換えてください。
ベンチマーク
下記のようなかんたんなPython3コードで、JPEG画像のデコード速度を測ってみました。
なお、このベンチマークを走らせるにはPython3サポートつきでのOpenCVビルドが必要になります(上記cmakeオプションには含まれていません)。
OpenCV with Pythonサポートのビルド方法については他をご参照ください。
OpenCV野良ビルド時にCMakeが指定したPythonのライブラリをうまく見つけてくれない時は | さかな前線などが参考になればと思います。
Before
mean=16.60989224910736ms, stdev=1.9476584857329726ms
After
mean=9.50382836163044ms, stdev=1.1629280634224415ms
2倍近く高速になりました。
圧縮率や画像サイズやもちろん画像の内容によっても変わるとは思いますが、これはおいしいフリーランチです。