Fastest Way To Loop Through Every Pixel

Ron Adam rrr at ronadam.com
Sat Jul 29 16:31:42 EDT 2006


Chaos wrote:
> As my first attempt to loop through every pixel of an image, I used
> 
>         for thisY in range(0, thisHeight):
>             for thisX in range(0, thisWidth):
>                   #Actions here for Pixel thisX, thisY
> 
> But it takes 450-1000 milliseconds
> 
> I want speeds less than 10 milliseconds
> 
> I have tried using SWIG, and pypy but they all are unsuccessfull in
> compiling my files.

This probably won't work for you, but it's worth suggesting as it may 
give you other ideas to solve your problem.

If it is a list of lists of pixel objects you can iterate though the 
pixels directly and not use range or xrange at all.  For this to work 
the pixel object needs to be mutable or have an attribute to store it's 
value.  It can't be just an int, in that case you will need to use indexes.



     pixel = [rgb_value]

or

     pixel = [r,g,b]

or

     class Pixel(object):
        def __self__(self, rgb_value):
            self.value = rgb_value
     pixel = Pixel(rgb_value)

Or some other variation that is mutable.


These may not be suitable and may cause additional overhead elsewhere as 
the image may need to be converted to some other form in order to 
display or save it.



What Actions are you performing on the pixels?

You may be able to increase the speed by creating lookup tables in 
dictionaries and then use the pixel value for the key.


Just a rough example...

    action1 = dict()
    # fill dict with precomputed pixel key value pairs.
    # ...

    image = getimage()
    for row in image:
       for pixel in row:
          # one of the following or something similar
          pixel[0] = action1[pixel]
          pixel.value = action1[pixel.value]
          pixel[:] = action[pixel]


The pixels need to be objects so they are mutable.  If they aren't, then 
you will need to use index's as you did above.

Precomputing the pixel value tables may use up too much memory or take a 
very long time if your image has a large amount of possible colors.  If 
precomputing the pixels take too long but you are not concerned by the 
memory usage, you may be able to store (pickle) the precomputed tables 
then unpickle it before it is used.

This work best if the number of colors (the depth) is limited.

If these suggestions aren't applicable, then you most likely need to 
look at an image library that uses compiled C (or assembly) code to do 
the brute force work.  It may also be possible to access your platforms 
directX or opengl library routines directly to do it.

Cheers,
    Ron















More information about the Python-list mailing list