# [SciPy-user] Efficient "windowing"

Neil Martinsen-Burrell n.martinsen-burrell@wartburg....
Wed Dec 5 13:58:57 CST 2007

> Date: Wed, 05 Dec 2007 17:18:09 +0100
> From: "Jose Luis Gomez Dans" <josegomez@gmx.net>
> Subject: [SciPy-user] Efficient "windowing"

> I am trying to apply a simple algorithm to a 2D matrix (an image). What I want
> to do is, for each pixel, choose the highest (... lowest) value in its 8- or
> 4-connected neighbours. I have done this using weave.inline, and using a
> couple of loops, but I was curious if there's some way of doing this using
> numpy slice syntax? My (allegedly, unelegant) attempts have been versions of
> the following:
>
> b[1:-1,1:-1] = scipy.array([a[0:-2,1:-1] , a[2:,1:-1] , a[1:-1,0:-2] ,\
>       a[1:-1,2:],a[0:-2,0:-2], a[0:-2,2:], a[2:,0:-2], a[2:,2:]],'f').max()
>
> They don't work, because the max() call at the end refers to the whole array,
> so you are given a constant value array, equal to the max. value of a. Using
> for loops is very slow when dealing with large arrays.

I use something like this:

import numpy
def _neighbors(i,j):
return [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]

x=numpy.random.random((5,5))
print x[zip(*_neighbors(2,3))].max()

Where the zip (* ) is the inverse of zip and converts the list of tuples
from _neighbors into a tuple of lists.  This uses numpy's fancy indexing to
special case when the indices are themselves lists.

-Neil

--