HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Chromatic aberration

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
chromaticaberrationstackoverflow

Problem

surface is a pygame.surface object from the Pygame graphics library. It actually runs way faster than I thought it would for a first try. Still, have I made any obvious mistakes here? Is there any way to make it go even faster?

cdef mapped_chromatic_aberration(surface, numpy.ndarray[int,ndim=2] intensitymap):
    cdef int x,y,z,maxx,maxy,intensity
    cdef numpy.ndarray[unsigned char,ndim=3] array
    cdef numpy.ndarray[unsigned char,ndim=2] r,g,b
    r=pygame.surfarray.pixels_red(surface)
    g=pygame.surfarray.pixels_green(surface)
    b=pygame.surfarray.pixels_blue(surface)
    array=pygame.surfarray.pixels3d(surface)

    maxx,maxy=surface.get_rect().bottomright

    for x in range(maxx):
        for y in range(maxy):
            try:
                pass
                intensity=intensitymap[x,y]
                array[x,y,0]=r[x+intensity,y]
                array[x,y,1]=g[x,y+intensity]
                array[x,y,2]=b[x+intensity,y-intensity]
            except IndexError:
                pass

cdef random_chromatic_aberration(surface,int intensity=5):
    mapped_chromatic_aberration(surface,numpy.random.random_integers(-intensity,intensity,surface.get_rect().bottomright))

Solution

At first glance, the double for loop seems to be very time consuming. Since you're using the numpy arrays, there is a way to get rid of it:

x = np.arange(array.shape[0])
y = np.arange(array.shape[1])
intensity = intensitymap.astype(int)
array[:, :, 0] = red[x + intensity, y]
array[:, :, 1] = green[x, y + intensity]
array[:, :, 2] = blue[x + intensity, y - intensity]


By the way, I would recommend you to use the numba JIT compiler. This will let you write pure python code. It is under active development now, and this is optimized for numpy arrays.

Code Snippets

x = np.arange(array.shape[0])
y = np.arange(array.shape[1])
intensity = intensitymap.astype(int)
array[:, :, 0] = red[x + intensity, y]
array[:, :, 1] = green[x, y + intensity]
array[:, :, 2] = blue[x + intensity, y - intensity]

Context

StackExchange Code Review Q#98501, answer score: 3

Revisions (0)

No revisions yet.