On Dec 11, 2008, at 4:33 PM, Joris De Ridder wrote:

> Hi,
>
> Below you can find a small cython function that implements a simple  
> max-filter. That is, given an image (a 2d numpy ndarray), each  
> pixel is replaced by the maximum value in a neighborhood [-dx:dx, - 
> dy:dy] around that pixel. For simplicity it just ignores the edges  
> of the image.
>
> I implemented the same function using C++ & ctypes, and the latter  
> function turns out to be about 100 times faster than the cython  
> one, for a 500x500 image, and dx,dy = 5,5. This surprises me,  
> because of the simplicity of the function. I checked the C file,  
> and also the translation of the maxfilter() function in C is quite  
> simple. The bulk of the time is of course spent in the loops, and  
> the only bottleneck that I can see is accessing the numpy arrays.  
> Is there anything I can do in Cython to speed that up?

Try declaring i and j to be unsigned ints, and see if that speeds  
anything up. (Currently it checks to see if the index is negative and  
does the Python-style indexing backwards in that case). You could  
also try passing in mode="c" to your ndarray type declaration.  
Another thing to attempt is to avoid looking up image[i+k,j+n] more  
than once by doing

value = image[i+k,j+n]
if maxvalue < value:
      maxvalue = value

100x difference sounds like what one would expect between Python and  
C, not between Cython and C++. Is it *exactly* the same algorithm?  
(Perhaps, since it's such a simple algorithm you could post the C++  
code as well?) It seems one could use a "sliding window" of maximum  
values to avoid re-computing the max of a 11x11 square on each  
iteration which could easily account for most of the speed difference  
you see here.

> Cheers,
> Joris
>
>
>
> import numpy as np
> cimport cython
> cimport numpy as np
>
> DTYPE = np.int                    # our image type
> ctypedef np.int_t DTYPE_t         # our compile time image type
>
> @cython.boundscheck(False)
> def maxfilter(np.ndarray[DTYPE_t, ndim=2] image, int dx, int dy):
>
>     cdef int nRow = image.shape[0]
>     cdef int nCol = image.shape[1]
>     cdef np.ndarray[DTYPE_t, ndim=2] result = np.zeros((nRow,nCol),  
> dtype=DTYPE)
>     cdef DTYPE_t maxvalue
>
>     cdef int i,j,k,n
>     for i from dx <= i < nRow-dx:
>         for j from dy <= j < nCol-dy:
>             maxvalue = image[i,j]
>             for k from -dx <= k <= dx:
>                 for n from -dy <= n <= dy:
>                     if maxvalue < image[i+k,j+n]: maxvalue = image[i 
> +k,j+n]
>             result[i,j] = maxvalue
>     return result
>
>
> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for  
> more information.
>
> _______________________________________________
> Cython-dev mailing list
> [email protected]
> http://codespeak.net/mailman/listinfo/cython-dev

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to