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