6

我正在将一些基于 PIL 的代码转换为 NumPy,但我发现该skimage.transform.rotate函数PIL 的Image.rotate.

作为粗略的比较,使用skimage' 旋转在 ~1000x1000 像素的图像上需要 ~2.2 秒,而Image.rotate需要 ~0.1 秒:

import time
from PIL import Image
import numpy as np
from skimage.transform import rotate

im = Image.open("some_big_image.png").convert("L")
print "Image size: %s" %(im.size, )

s = time.time()
im.rotate(10, Image.BICUBIC, expand=True)
print "Image.rotate: %0.04f" %(time.time() - s, )

ima = np.array(im) / 255.0
s = time.time()
rotate(ima, 10, order=3) # order=3 --> bi-cubic filtering
print "skimage.transform.rotate: %0.04f" %(time.time() - s, )

和输出:

$ py rotate.py
Image size: (1275, 1650)
Image.rotate: 0.1154
skimage.transform.rotate: 2.2310

(这些数字在多次运行中或多或少是一致的;我不认为这是没有运行足够测试的产物)

所以!那是怎么回事?有什么方法可以加快 skimage 的速度rotate吗?

版本信息:

  • 皮尔:1.1.7
  • skimage:0.14.1
  • 麻木:1.7.1
  • 蟒蛇:2.7.2

可能还值得注意:

  • 如果BICUBIC不使用过滤,则该im.rotate操作只需 ~0.01 秒,而设置order=0为使用最近邻过滤,skimage.rotate则需要 ~0.6 秒。
4

2 回答 2

7

从https://github.com/scikit-image/scikit-image安装最新版本。就在几天前,我修复了一个与此减速相关的错误(参见https://github.com/scikit-image/scikit-image/commit/d5776656a8217e58cb28d5760439a54e96d15316 )。

我的数字与当前的开发版本如下:

from PIL import Image
import numpy as np
from skimage.transform import rotate

a = np.zeros((1000, 1000), dtype=np.uint8)

im = Image.fromarray(a)

%timeit im.rotate(10, Image.BICUBIC, expand=True)

ima = a / 255.0
%timeit rotate(ima, 10, order=1)
%timeit rotate(ima, 10, order=3)


## -- Output --
10 loops, best of 3: 41.3 ms per loop
10 loops, best of 3: 43.6 ms per loop
10 loops, best of 3: 101 ms per loop
于 2013-11-11T21:57:54.553 回答
1

只阅读了 Python 代码而不是 Cython 代码warp(),猜测是因为 skimage 使用的是通用扭曲代码,它的代码路径效率低于专门为平面内旋转而编写的代码,仅此而已。

于 2013-11-06T20:58:02.903 回答