Benchmark of Python Image Processing(resize)
下記記事で、 Imlib2 スゲーよってことで、 Pythonでもベンチマークいるのではないかと思いベンチマークをとってみました。
Imlib2でImageMagickより3倍高速かつ美しいサムネイル画像の生成 - 床のトルストイ、ゲイとするとのこと
対象のモジュールは以下です。
結果としては、PythonでもImlib2速いねってことです、はい。 OpenCVが以外に頑張っています。

出力画像
オリジナルの画像は以下のものを使用しました。
http://upload.wikimedia.org/wikipedia/commons/d/df/SAND_LUE.jpg
pgmagickやPythonMagickのsharpenメソッドを使う以外は、 特に大差無いのではないかと思っています。 gdモジュールではカラー画像にできませんでした。 特に使うことも無いと思うので、深追いはしていません。
左(上)から、gd、imlib2、PythonMagick、PythonMagick(+sharpen)、pgmagick、pgmagick(+sharpen)、 OpenCVの画像です。
















ファイルサイズ
それぞれの画像のファイルサイズは以下になります。(単位はbyteです)
module/size | Small | Medium | Large |
---|---|---|---|
gd | 18816 | 150404 | 488661 |
imlib2 | 7892 | 60862 | 196425 |
PIL | 16826 | 137216 | 454370 |
PythonMagick | 43649 | 156019 | 451105 |
PythonMagick(sharpen) | 45894 | 177725 | 523396 |
pgmagick | 38747 | 181871 | 541675 |
pgmagick(sharpen) | 43016 | 214858 | 636885 |
OpenCV | 16428 | 133913 | 439178 |
ベンチマークスクリプト
4288x2848の画像を180x120、600x400、1200x800にリサイズします。 それぞれ10回ずつの合計値をとっています。JPEGの保存品質(quality)は95にしました。 kaa-imlib2は保存品質を変更できなかったので、値は不明です。
ベンチマーク取得用のスクリプトは以下のような感じです。
from benchmarker import Benchmarker
import Image
#import PythonMagick
import pgmagick
import opencv.cv as cv
import opencv.highgui as highgui
import kaa.imlib2 as imlib2
import gd
N = 10
def gd_scale(filename, width, height):
im = gd.image(filename)
newim = gd.image((width, height))
size = im.size()
im.copyPaletteTo(newim)
im.copyResampledTo(newim,
(0, 0), (0, 0),
(width, height), (size[0], size[1]))
newim.writeJpeg('outgd.jpg', 95)
def imlib2_scale(filename, width, height):
im = imlib2.Image(filename)
newim = im.scale((width, height))
newim.save('outimlib2.jpg')
def pil_scale(filename, width, height):
im = Image.open(filename)
newim = im.resize((width, height), Image.ANTIALIAS)
newim.save('outpil.jpg', quality=95)
def imagemagick_scale_plus_sharpen(filename, width, height):
im = PythonMagick.Image(filename)
im.scale('%dx%d' % (width, height))
im.sharpen(1)
im.quality(95)
im.write('outimsharpen.jpg')
def imagemagick_scale(filename, width, height):
im = PythonMagick.Image(filename)
im.quality(95)
im.scale('%dx%d' % (width, height))
im.write('outim.jpg')
def pgmagick_scale_plus_sharpen(filename, width, height):
im = pgmagick.Image(filename)
im.scale('%dx%d' % (width, height))
im.sharpen(1)
im.quality(95)
im.write('outpgsharpen.jpg')
def pgmagick_scale(filename, width, height):
im = pgmagick.Image(filename)
im.scale('%dx%d' % (width, height))
im.quality(95)
im.write('outpg.jpg')
def opencv_scale(filename, width, height):
im = highgui.cvLoadImage(filename)
newim = cv.cvCreateImage(cv.cvSize(width, height), 8, 3)
cv.cvResize(im, newim, cv.CV_INTER_AREA)
highgui.cvSaveImage("outcv.jpg", newim)
def exebench(width):
"""
benchorg.jpg is
'http://upload.wikimedia.org/wikipedia/commons/d/df/SAND_LUE.jpg'
"""
bm = Benchmarker(30)
height = width * 2 / 3
with bm("gd"):
for i in range(N):
gd_scale('benchorg.jpg', width, height)
with bm("imlib2"):
for i in range(N):
imlib2_scale('benchorg.jpg', width, height)
with bm("PIL"):
for i in range(N):
pil_scale('benchorg.jpg', width, height)
#with bm("PythonMagick"):
# for i in range(N):
# imagemagick_scale('benchorg.jpg', width, height)
#with bm("PythonMagick(+sharpen)"):
# for i in range(N):
# imagemagick_scale_plus_sharpen('benchorg.jpg', width, height)
with bm("pgmagick"):
for i in range(N):
pgmagick_scale('benchorg.jpg', width, height)
with bm("pgmagick(+sharpen)"):
for i in range(N):
pgmagick_scale_plus_sharpen('benchorg.jpg', width, height)
with bm("opencv"):
for i in range(N):
opencv_scale('benchorg.jpg', width, height)
bm.print_compared_matrix()
if __name__ == '__main__':
exebench(180)
print "=" * 70
exebench(600)
print "=" * 70
exebench(1200)
PythonMagickとpgmagickは同時に使用できないので、別々に実行しました。
以下にスクリプトと結果を置いているので細かい結果とかを知りたければ 見てみてください。
http://www.hexacosa.net/hgrepos/python-snipets/file/bf1b91ed1a38/imageprocessing
まとめ
小さい画像だとあまり画質に差がでませんので、 Imlib2の使用を検討してもよいのではないかと思います。 私は大きな画像になるとImageMagickまたはGraphicsMagickの sharpenフィルターを使った画像の方が好みなので、 pgmagickを使用することにします。 この辺は用途に合わせて選んだ方が良さそうです。