# Why is skimage.transform.rotate significantly slower than PIL’s Image.rotate?

I’m in the process of converting some PIL-based code over to NumPy, but I’ve found that the `skimage.transform.rotate` function is significantly slower than PIL’s `Image.rotate`.

As a rough comparison, using `skimage`‘s rotate on a ~1000×1000 pixel image takes ~2.2 seconds, while `Image.rotate` takes ~0.1 seconds:

``````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, )
``````

And the output:

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

(these numbers are more or less consistent across multiple runs; I don’t believe that this is an artifact of not running enough tests)

So! What’s up with that? Is there any way to speed up skimage’s `rotate`?

Version info:

• PIL: 1.1.7
• skimage: 0.14.1
• numpy: 1.7.1
• Python: 2.7.2

It may also be worth noting:

• If `BICUBIC` filtering isn’t used, the `im.rotate` operation only takes ~0.01 seconds, while setting `order=0` to use nearest-neighbour filtering, `skimage.rotate` takes ~0.6 seconds.

Install the latest version from https://github.com/scikit-image/scikit-image. Just a few days ago I fixed a bug (see https://github.com/scikit-image/scikit-image/commit/d5776656a8217e58cb28d5760439a54e96d15316) related to this slow down.

My numbers are as follows with the current dev version:

``````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``````