🐡

wand/imagemagickは処理が遅いことがあるのでPILで済む処理ならPILがお勧め

2022/12/13に公開約2,400字

色々なサイトで、python2|3での 画像処理の実装として、ImageMagick/wandをおすすめしてるが、実はやや処理が遅い。

Wand — Wand 0.6.10

GitHub - emcconville/wand: The ctypes-based simple ImageMagick binding for Python

小生の場合、連続して画像処理をさせているスクリプトがあり、straceしてたまたま気づいたのだが結構怪しい処理を色々やってる。

wandとPILで処理時間を比較してみる。

中央にポツンと小さい模様があるだけの 4000バイト以下のモノクロ画像 test.pngを使った例をあげる。増色&減色をするだけの簡単な実装である。

画像の詳細は本件の本質にはあまり影響しないため割愛する。

wandの実装例は次の通り。

w.py
import wand
import wand.image

aa = wand.image.Image(filename="test.png")
aa.type = "truecolor"
aa.type = "palette"
#aa.auto_level()

PIL/pillow の実装例は次の通り。

Pillow (PIL Fork) 9.2.0 documentation

p.py
import PIL.Image

aa = PIL.Image.open("test.png")
aa.convert("RGBA")
aa.convert("P")
#aa.auto_level()

これを小生の約7000bogomipsの環境で実行するとこうなる。

$ time python3 p.py 

real    0m0.073s
user    0m0.059s
sys     0m0.014s
$ time python3 w.py 

real    0m0.454s
user    0m0.440s
sys     0m0.099s

PIL版の0.07秒は十分納得できる数字だが、wand版の0.4秒が明らかに遅いことがわかるだろう。

wandで0.4秒掛かってる理由

紆余曲折あったが、理由はわかった。

Imagemagickのライブラリを探すために複雑な処理をしているためだ。

https://github.com/emcconville/wand/blame/master/wand/api.py#L103-L100

ctypes.util.find_libraryが曲者なのだが、実は内部でgccを実行して、ライブラリのpathを探そうとしてる。

https://github.com/python/cpython/blame/main/Lib/ctypes/util.py#L118

これは imagemagickの方も問題で、非標準なディレクトリへのインストールも提唱してるためだ。

ImageMagick – Download

Set the MAGICK_HOME environment variable to the path where you extracted the ImageMagick files. For example:
$ export MAGICK_HOME="$HOME/ImageMagick-7.1.0"

wand側でもこのあたりの言及はしている。

https://github.com/emcconville/wand/blob/master/docs/guide/install.rst

PIL(pillow)+α で行こう

手っ取り早く、PILで行くことにした。

前述の通り、減色程度ならPILで容易に代替可能である。
また代表的な画像処理であろう crop および resize==transform も類似の機能があるため、概ねPILで実装可能である。

小生の運用では、さらにこれに明度レベル調整が必要だった。 wandでは非常に簡単に使える機能なので、このためにwandを使うのなくはない。

https://github.com/emcconville/wand/blob/master/wand/image.py#L2981

auto_levelはPILには機能がないため、自作する必要がある。が、これはすぐ見つかる。例えば次のリンクでは numpy+cv2を使って自分で計算する。

image - Doing the same as ImageMagick's "-level" in python / PIL? - Stack Overflow

wand/imagemagickを辞めて。PILに加えてopencv+numpyまで使うなら本末転倒では?と思う方も居るだろう。 が、小生の場合では、それでもwandより何割か処理が早いことを確認した。そのため、wandを廃止してPIL+opencv/numpyに切り替えた。

Discussion

ログインするとコメントできます