[SciPy-user] Efficient "windowing"

Robert Kern robert.kern at gmail.com
Wed Dec 5 15:11:44 EST 2007


Jose Luis Gomez Dans wrote:
> Hi,
> 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.

.max() takes an `axis` argument. It also takes an `out` argument that will help
you save you from making some large temporaries.

In [1]: from numpy import *

In [2]: n = 256

In [5]: a = random.random((n,n)).astype(float32)

In [7]: b = zeros([n,n], dtype=float32)

In [8]: neighbors = 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:]])

In [9]: neighbors.shape
Out[9]: (8, 254, 254)

In [10]: neighbors.max(axis=0, out=b[1:-1,1:-1])
Out[10]:
array([[ 0.94350582,  0.94350582,  0.94350582, ...,  0.98800218,
         0.97231197,  0.61088812],
       [ 0.94350582,  0.82977545,  0.94350582, ...,  0.61088812,
         0.97231197,  0.97231197],
       [ 0.94350582,  0.94350582,  0.94350582, ...,  0.95455241,
         0.95455241,  0.95455241],
       ...,
       [ 0.92812324,  0.92812324,  0.95367759, ...,  0.92305821,
         0.92305821,  0.92305821],
       [ 0.95591497,  0.95591497,  0.95367759, ...,  0.96583498,
         0.85454881,  0.92305821],
       [ 0.92812324,  0.95591497,  0.92812324, ...,  0.96583498,
         0.92305821,  0.92305821]], dtype=float32)

In [11]: b
Out[11]:
array([[ 0.        ,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.        ],
       [ 0.        ,  0.94350582,  0.94350582, ...,  0.97231197,
         0.61088812,  0.        ],
       [ 0.        ,  0.94350582,  0.82977545, ...,  0.97231197,
         0.97231197,  0.        ],
       ...,
       [ 0.        ,  0.95591497,  0.95591497, ...,  0.85454881,
         0.92305821,  0.        ],
       [ 0.        ,  0.92812324,  0.95591497, ...,  0.92305821,
         0.92305821,  0.        ],
       [ 0.        ,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.        ]], dtype=float32)


-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth."
  -- Umberto Eco



More information about the SciPy-User mailing list