Fastest Way To Loop Through Every Pixel

nikie n.estner at gmx.de
Mon Jul 31 10:50:50 EDT 2006


Paul McGuire wrote:

> "Chaos" <psnim2000 at gmail.com> wrote in message
> news:1154280523.162997.298400 at i42g2000cwa.googlegroups.com...
> >
> > Paul McGuire wrote:
> > > "Paul McGuire" <ptmcg at austin.rr._bogus_.com> wrote in message
> > > news:Grhyg.21879$Cn6.17684 at tornado.texas.rr.com...
> > > > "Chaos" <psnim2000 at gmail.com> wrote in message
> > > > news:1154055002.495073.171650 at i3g2000cwc.googlegroups.com...
> > > > >
> > > > >
> > > > > myCol = (0.3 * image.GetRed(thisX, thisY)) + (0.59 *
> > > > > image.GetGreen(thisX, thisY)) + (0.11 * image.GetBlue(thisX, thisY))
> > > > > if myCol < darkestCol:
> > > > >    darkestCol = myCol
> > > > >    possX = thisX
> > > > >    possY = thisY
> > > > >
> > > >
> > > > Psyco may be of some help to you, especially if you extract out your
> myCol
> > > > expression into its own function, something like:
> > > >
> > > > def darkness(img,x,y):
> > > >     return  (0.3 * img.GetRed(x,y)) + (0.59 * img.GetGreen(x,y)) +
> (0.11 *
> > > > img.GetBlue(x,y))
> > > >
> > > <snip>
> > >
> > > Even better than my other suggestions might be to write this function,
> and
> > > then wrap it in a memoizing decorator
> > >
> (http://wiki.python.org/moin/PythonDecoratorLibrary#head-11870a08b0fa59a8622
> > > 201abfac735ea47ffade5) - surely there must be some repeated colors in
> your
> > > image.
> > >
> > > -- Paul
> >
> > Its not only finding the darkest color, but also finding the X position
> > and Y Position of the darkest color.
> >
>
> Sorry, you are correct.  To take advantage of memoizing, the darkness method
> would have to work with the r, g, and b values, not the x's and y's.
>
> -- Paul
>
>
> import psyco
> psyco.full()
>
> IMAGE_WIDTH = 200
> IMAGE_HEIGHT = 200
> imgColRange = range(IMAGE_WIDTH)
> imgRowRange = range(IMAGE_HEIGHT)
>
> @memoize    # copy memoize from
> http://wiki.python.org/moin/PythonDecoratorLibrary, or similar
> def darkness(r,g,b):
>     return 0.3*r + 0.59*g + 0.11*b
>
> def getDarkestPixel(image):
>     getR = image.GetRed
>     getG = image.GetGreen
>     getB = image.GetBlue
>
>     darkest = darkness( getR(0,0), getG(0,0), getB(0,0) )
>     # or with PIL, could do
>     # darkest = darkness( *getpixel(0,0) )
>     dkX = 0
>     dkY = 0
>     for r in imgRowRange:
>         for c in imgColRange:
>             dk = darkness( getRed(r,c), getGrn(r,c), getBlu(r,c) )
>             if dk < darkest:
>                 darkest = dk
>                 dkX = c
>                 dkY = r
>     return dkX, dkY

>From my experiences with Psyco/PIL, it's probably faster to move the
image data into lists first (using list(Image.getdata) or
list(image.getband)) and access the raw data in your loop(s). Don't use
Image.getpixel in a tight loop, they result in Python-to-C-Calls which
can't be optimized by Psyco. Even when you're not using Psyco, getpixel
is probably slower (at least the PIL docs say so: "Note that this
method is rather slow; if you need to process larger parts of an image
from Python, use the getdata method.")




More information about the Python-list mailing list