This is my first attempt at using strides in numpy and it did improve speed compared to simple iteration over the different filters, yet it still is quite slow (and it feels like there are at least one or two things that are completely redundant or inefficient).
So my question is: are there better ways of performing this or tweaks to my code that would make it significantly faster?
The algorithm performs a local evaluation of 9 different filters for each pixel and selects the one that has the least standard deviation (my attempt to implement Nagau and Matsuyma (1980) "A Structural Analysis of Complex Areal Photographs", as described in an image analysis book). The result is a both smoothened and edge sharpened image (Quite cool if you ask me!)
import numpy as np
from scipy import ndimage
from numpy.lib import stride_tricks
def get_rotating_kernels():
kernels = list()
protokernel = np.arange(9).reshape(3, 3)
for k in xrange(9):
ax1, ax2 = np.where(protokernel==k)
kernel = np.zeros((5,5), dtype=bool)
kernel[ax1: ax1+3, ax2: ax2+3] = 1
kernels.append(kernel)
return kernels
def get_rotation_smooth(im, **kwargs):
kernels = np.array([k.ravel() for k in get_rotating_kernels()],
dtype=bool)
def rotation_matrix(section):
multi_s = stride_tricks.as_strided(section, shape=(9,25),
strides=(0, section.itemsize))
rot_filters = multi_s[kernels].reshape(9,9)
return rot_filters[rot_filters.std(1).argmin(),:].mean()
return ndimage.filters.generic_filter(im, rotation_matrix, size=5, **kwargs)
from scipy import lena
im = lena()
im2 = get_rotation_smooth(im)
(Just a comment, the get_rotating_kernel hasn't really been optimized since almost no time is spent there anyway)
On my netbook, it took 126s and Lena is after all a quite small image.
Edit:
I got the suggestion to change rot_filters.std(1) to rot_filters.var(1) to save quite a few square-roots and it shaved off something in the order of 5s.
cProfile)?rotation_matrixfunction is called 262144 times, there's the time that can be saved. And whichever part it would point to I still don't know how it would help me...but maybe it's just that I haven't learned to lovecProfile...