Question

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 ~1000x1000 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.
Was it helpful?

Solution

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

OTHER TIPS

Having only read the Python code and not the Cython code for warp(), guess would be that since skimage is using generic warping code, its code paths are less efficient than something written specifically to do in-plane rotation and nothing else.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top