Development

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • Fastest Way To Loop Through Every Pixel

    27 answers - 376 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    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.
  • No.1 | | 1165 bytes | |

    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

    T: you don't need the 0 in the range call. Taking it out doesn't make
    it run faster, though.

    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.

    Unsuccessful because what?
    [I wasn't aware that swig was intended to compile Python scripts]

    Sticking with Python:
    With the "for thisX" try
    (1) using xrange instead of range.
    (2) widthRange = range(thisWidth)
    for thisY in range(thisHeight):
    for thisX in widthrange:
    and in general, hoist loop-invariants outside the loop.

    Have you considered Pyrex?

    It all depends on what "#Actions here for Pixel thisX, thisY" is doing.
    Perhaps there is a library (PIL, pygame, ) that does what you are
    trying to do.
    Perhaps if you show us what you are doing, we can give you better
    advice.

    HTH,
    John
  • No.2 | | 1609 bytes | |

    John Machin wrote:
    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

    T: you don't need the 0 in the range call. Taking it out doesn't make
    it run faster, though.
    --
    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.

    Unsuccessful because what?
    [I wasn't aware that swig was intended to compile Python scripts]

    Sticking with Python:
    With the "for thisX" try
    (1) using xrange instead of range.
    (2) widthRange = range(thisWidth)
    for thisY in range(thisHeight):
    for thisX in widthrange:
    and in general, hoist loop-invariants outside the loop.

    Have you considered Pyrex?

    It all depends on what "#Actions here for Pixel thisX, thisY" is doing.
    Perhaps there is a library (PIL, pygame, ) that does what you are
    trying to do.
    Perhaps if you show us what you are doing, we can give you better
    advice.

    HTH,
    John

    Nope still same speed. I also tried pyrex but I couldnt understand how
    to build pyx files. I didnt see how to set up the files using C. I
    wasnt sure if you were supposed use the example or build your own.

    With pypy I got a strange error trying to open py files. It said the
    first character of evey py file was unknown.

    I may try SWIG again becuase I fail to rememeber why I stopped using it.
  • No.3 | | 1288 bytes | |

    Hello Chaos,

    Whatever you do in "#Actions here " might be expressed nicely as a
    ufunction for numeric. Then you might be able to convert the expression
    to a numeric expression. Check out numpy/scipy.

    In general, if thisHeight, thisWidth are large use xrange not range.
    range() generates a list of numbers first then iterates through them.
    So try that first.

    Then of course if you do the whole thing many times you could just
    pre-generate the indices as in:
    all_indices=[]
    for i in xrange(thisHeight):
    for j in xrange(thisWidth):
    all_indices.append( (i,j) )

    Then each time you need to run '#Actions here' you can just use
    for (i,j) in all_indices:
    #Actions here blah blah

    In general, if there would be a way to significantly optimize generic
    for loops, they would probably be already optimized

    Nick V.

    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.
  • No.4 | | 2238 bytes | |

    Chaos wrote:
    John Machin wrote:
    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

    T: you don't need the 0 in the range call. Taking it out doesn't make
    it run faster, though.
    --
    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.

    Unsuccessful because what?
    [I wasn't aware that swig was intended to compile Python scripts]

    Sticking with Python:
    With the "for thisX" try
    (1) using xrange instead of range.
    (2) widthRange = range(thisWidth)
    for thisY in range(thisHeight):
    for thisX in widthrange:
    and in general, hoist loop-invariants outside the loop.

    Have you considered Pyrex?

    It all depends on what "#Actions here for Pixel thisX, thisY" is doing.
    Perhaps there is a library (PIL, pygame, ) that does what you are
    trying to do.
    Perhaps if you show us what you are doing, we can give you better
    advice.

    HTH,
    John

    Nope still same speed. I also tried pyrex but I couldnt understand how
    to build pyx files. I didnt see how to set up the files using C. I
    wasnt sure if you were supposed use the example or build your own.

    With pypy I got a strange error trying to open py files. It said the
    first character of evey py file was unknown.

    I may try SWIG again becuase I fail to rememeber why I stopped using it.

    With SWIG when I tried to execute ld -shared example.o example_wrap.o
    -o _example.so line in CMD I got example_wrap.o:example.o
    :<.text+0x: undifned refrence to object

    Thank you but it didnt work, but I think I am getting somewhere because
    I used your method and got 400 ms, I think that is something because I
    used 2 loops

    He is the code #Actions here

    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
  • No.5 | | 861 bytes | |

    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.

    You could try the PIL package.

    >From the docs at


    Image.eval(function, image) =image

    Applies the function (which should take one argument) to each pixel in
    the given image. If the image has more than one band, the same function
    is applied to each band. Note that the function is evaluated once for
    each possible pixel value, so you cannot use random components or other
    generators.

    HTH,
    ~Simon
  • No.6 | | 569 bytes | |

    Have you tried PIL? (Python Imaging Library)

    "Chaos" <psnim2000 (AT) gmail (DOT) comwrote:

    >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.
  • No.7 | | 1189 bytes | |

    Simon Forman wrote:
    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.

    You could try the PIL package.
    >
    >From the docs at


    Image.eval(function, image) =image

    Applies the function (which should take one argument) to each pixel in
    the given image. If the image has more than one band, the same function
    is applied to each band. Note that the function is evaluated once for
    each possible pixel value, so you cannot use random components or other
    generators.

    HTH,
    ~Simon

    I have tried PIL. Not only that, but the Image.eval function had no
    success either. I did some tests and I found out that Image.eval only
    called the function a certain number of times either 250, or 255.
    Unless I can find a working example for this function, its impossible
    to use.
  • No.8 | | 1555 bytes | |

    "Chaos" <psnim2000 (AT) gmail (DOT) comwrote in message
    news:1154055002.495073.171650 (AT) i3g2000cwc (DOT) 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))

    You may also be paying a penalty for the floating-point multiplications.
    Since you are only concerned with the relative values, what if you scale up
    all of your weighting coefficients, so that you only do integer multiplies?

    def darkness(img,x,y):
    return (30 * img.GetRed(x,y)) + (59 * img.GetGreen(x,y)) + (11 *
    img.GetBlue(x,y))

    You can also cut down on resolution of your GetXXX functions by saving them
    to locals.

    RedVal = Image.GetRed
    GrnVal = Image.GetGreen
    BluVal = Image.GetBlue
    def darkness(img,x,y):
    return (30 * RedVal(img,x,y)) + (59 * GreenVal(img,x,y)) + (11 *
    BlueVal(img,x,y))

    Even downer-and-dirtier, you could approximate 30 with 32, 59 with 64, and
    11 with 8, and do bit-shifting instead of multiplying:

    def darkness(img,x,y):
    return (RedVal(img,x,y) << 5) + (GreenVal(img,x,y) << 6) +
    (BlueVal(img,x,y) << 3)

    -- Paul
  • No.9 | | 494 bytes | |

    "Nick Vatamaniuc" <vatamane (AT) gmail (DOT) comwrote in message
    news:1154053874.100840.122250@
    Hello Chaos,

    Then of course if you do the whole thing many times you could just
    pre-generate the indices as in:
    all_indices=[]
    for i in xrange(thisHeight):
    for j in xrange(thisWidth):
    all_indices.append( (i,j) )

    just:

    all_indices = [ (i,j) for i in xrange(thisHeight) for j in
    xrange(thisWidth) ]

    Embrace those list comprehensions!
    -- Paul
  • No.10 | | 1717 bytes | |

    Chaos wrote:
    Simon Forman wrote:
    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.

    You could try the PIL package.
    >
    >From the docs at


    Image.eval(function, image) =image

    Applies the function (which should take one argument) to each pixel in
    the given image. If the image has more than one band, the same function
    is applied to each band. Note that the function is evaluated once for
    each possible pixel value, so you cannot use random components or other
    generators.

    HTH,
    ~Simon

    I have tried PIL. Not only that, but the Image.eval function had no
    success either. I did some tests and I found out that Image.eval only
    called the function a certain number of times either 250, or 255.

    It says "the function is evaluated once for each possible pixel value",
    so if it's only calling the function 250 or 255 times it's because your
    image only has 250 or 255 colors.

    Image.eval() caches the results of your function for each
    color/pixel-value and reuses them rather than recomputing them.

    I take it that whatever you're doing to those pixels involves more
    information than just the pixel values? What are you doing to the
    pixels? That's probably wher you should look to improve the speed of
    the loop.

    Peace,
    ~Simon
  • No.11 | | 518 bytes | |

    "Paul McGuire" <ptmcg (AT) austin (DOT) rr._bogus_.comwrote:

    | Even downer-and-dirtier, you could approximate 30 with 32, 59 with 64, and
    | 11 with 8, and do bit-shifting instead of multiplying:
    |
    | def darkness(img,x,y):
    | return (RedVal(img,x,y) << 5) + (GreenVal(img,x,y) << 6) +
    | (BlueVal(img,x,y) << 3)
    |
    |
    | -- Paul

    *grin* - a man after my own heart! - how do you multiply by ten? - shift, save a
    copy, shift twice more and add the copy
    - Hendrik
  • No.12 | | 2482 bytes | |

    Simon Forman wrote:
    Chaos wrote:
    Simon Forman wrote:
    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.

    You could try the PIL package.
    >
    >From the docs at


    Image.eval(function, image) =image

    Applies the function (which should take one argument) to each pixel in
    the given image. If the image has more than one band, the same function
    is applied to each band. Note that the function is evaluated once for
    each possible pixel value, so you cannot use random components or other
    generators.

    HTH,
    ~Simon

    I have tried PIL. Not only that, but the Image.eval function had no
    success either. I did some tests and I found out that Image.eval only
    called the function a certain number of times either 250, or 255.

    It says "the function is evaluated once for each possible pixel value",
    so if it's only calling the function 250 or 255 times it's because your
    image only has 250 or 255 colors.

    Image.eval() caches the results of your function for each
    color/pixel-value and reuses them rather than recomputing them.

    I take it that whatever you're doing to those pixels involves more
    information than just the pixel values? What are you doing to the
    pixels? That's probably wher you should look to improve the speed of
    the loop.

    Peace,
    ~Simon

    , sorry. I didn't see where you had already posted the actions
    you're taking on the pixels

    He is the code #Actions here

    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

    Hmm, if you're just trying to find the darkest color and one of it's
    pixel coordinates after applying your weighting calculation, and you
    don't mind if the coordinates are of the first encountered pixel of
    that color, then I think you might be able to use Image.eval() after
    all.

    What format are the images in?

    Peace,
    ~Simon
  • No.13 | | 836 bytes | |

    "H J van Rooyen" <mail (AT) microcorp (DOT) co.zawrote in message
    @python.org
    "Paul McGuire" <ptmcg (AT) austin (DOT) rr._bogus_.comwrote:

    | Even downer-and-dirtier, you could approximate 30 with 32, 59 with 64,
    and
    | 11 with 8, and do bit-shifting instead of multiplying:
    |
    | def darkness(img,x,y):
    | return (RedVal(img,x,y) << 5) + (GreenVal(img,x,y) << 6) +
    | (BlueVal(img,x,y) << 3)
    |
    |
    | -- Paul

    *grin* - a man after my own heart! - how do you multiply by ten? - shift,
    save a
    copy, shift twice more and add the copy

    - Hendrik

    Sadly, my timeit results show this saves only a little time, and
    is even slower then just doing the original
    floating point multiply. The biggest win is in prelookup of Image.GetXXX
    functions.
    -- Paul
  • No.14 | | 489 bytes | |

    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

    The main question is: why do you want to do this? I ask because with
    performance requirements like that, you almost certainly need another
    approach, one which I may be able to suggest.
  • No.15 | | 1123 bytes | |

    Chaos (psnim2000 (AT) gmail (DOT) com) wrote:

    : He is the code #Actions here

    : 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

    You really don't want to do this in interpreted Python code. Way to slow.
    I don't know PIL but probably you can do it their.

    Another aproach is to use one of the array/maths libraries e.g. Numeric or
    NumPy.

    You'll need to move the image data between PIL and the array package with
    the data being a (y,x,3) array for input array and (y,x) for the output
    array. .tostirng() methods and fromstring() can be usefull here.

    Then

    1. Colour map it
    newImage = 0.3 * image[:,:,0] + 0.59 * image[:,:,1] + 0.11 * image[:,:,2]

    2. Mask of pixels less than your threshold

    newImage = clip(newImage, myCol, MAX_CLUR)

    3. Find the coordinates of the last minimum colour - possX, possY (do you
    really need/mean to do this?)

    hth
    cds
  • No.16 | | 1181 bytes | |

    "Paul McGuire" <ptmcg (AT) austin (DOT) rr._bogus_.comwrote:

    | "H J van Rooyen" <mail (AT) microcorp (DOT) co.zawrote in message
    | @python.org
    | "Paul McGuire" <ptmcg (AT) austin (DOT) rr._bogus_.comwrote:
    | >
    | | Even downer-and-dirtier, you could approximate 30 with 32, 59 with 64,
    | and
    | | 11 with 8, and do bit-shifting instead of multiplying:
    | |
    | | def darkness(img,x,y):
    | | return (RedVal(img,x,y) << 5) + (GreenVal(img,x,y) << 6) +
    | | (BlueVal(img,x,y) << 3)
    | |
    | |
    | | -- Paul
    | >
    | *grin* - a man after my own heart! - how do you multiply by ten? - shift,
    | save a
    | copy, shift twice more and add the copy
    | >
    | - Hendrik
    | >
    | Sadly, my timeit results show this saves only a little time, and
    | is even slower then just doing the original
    | floating point multiply. The biggest win is in prelookup of Image.GetXXX
    | functions.
    |
    | -- Paul

    I was not seriously suggesting this for use in python on a pc - its the sort of
    rubbish you do on a small embedded machine that has a reduced instruction set
    and no multiplier
    - Hendrik
  • No.17 | | 504 bytes | |

    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.

    I think you are using PIL but I don't know what version.

    Check out this page.

    HTH
    jay
  • No.18 | | 541 bytes | |

    "Chaos" <psnim2000 (AT) gmail (DOT) comwrote in message
    news:1154053723.899787.72980 (AT) i3g2000cwc (DOT) googlegroups.com
    >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


    Besides other suggestions, you might also take a look at Pygame which both
    wraps a C graphics library and has an interface to numeric.
  • No.19 | | 659 bytes | |

    Terry Reedy wrote:
    "Chaos" <psnim2000 (AT) gmail (DOT) comwrote in message
    news:1154053723.899787.72980 (AT) i3g2000cwc (DOT) googlegroups.com
    >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
    >

    Besides other suggestions, you might also take a look at Pygame which both
    wraps a C graphics library and has an interface to numeric.

    :-)
    Could your check_earlier_responses() gizmoid be made case-insensitive?
    (-:
  • No.20 | | 1111 bytes | |

    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

    Milliseconds don't mean much unless we knew how big your images are and
    what hardware you're using.

    Have you considered using NumPy? Assuming you can get the image into a
    numpy array efficiently, the actual algorithm boils down to something
    like this:

    grey = r*0.3 + g*0.59 + b*0.11
    index = grey.argmin()
    x,y = index%step, index/step
    v = grey[x,y]

    where r,g,b and grey are numpy.ndarray objects; The arithmetic
    operators and the argmin-function are implemented in C, so you can
    expect decent performance. (the 4 lines above take about 80 ms for a
    1000x1000 image on my PC)

    If that's not enough, you might want to use some specially optimized C
    library for this purpose. (I'd suggest Intel's IPP, but there are
    others).
  • No.21 | | 1196 bytes | |

    nikie wrote:
    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

    Milliseconds don't mean much unless we knew how big your images are and
    what hardware you're using.

    Have you considered using NumPy? Assuming you can get the image into a
    numpy array efficiently, the actual algorithm boils down to something
    like this:

    grey = r*0.3 + g*0.59 + b*0.11
    index = grey.argmin()
    x,y = index%step, index/step
    v = grey[x,y]

    where r,g,b and grey are numpy.ndarray objects; The arithmetic
    operators and the argmin-function are implemented in C, so you can
    expect decent performance. (the 4 lines above take about 80 ms for a
    1000x1000 image on my PC)

    If that's not enough, you might want to use some specially optimized C
    library for this purpose. (I'd suggest Intel's IPP, but there are
    others).

    Can you give me an example of geting an image into a numpy array?
  • No.22 | | 1252 bytes | |

    nikie wrote:
    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

    Milliseconds don't mean much unless we knew how big your images are and
    what hardware you're using.

    Have you considered using NumPy? Assuming you can get the image into a
    numpy array efficiently, the actual algorithm boils down to something
    like this:

    grey = r*0.3 +

    g*0.59 + b*0.11
    index = grey.argmin()
    x,y = index%step, index/step
    v = grey[x,y]

    where r,g,b and grey are numpy.ndarray objects; The arithmetic
    operators and the argmin-function are implemented in C, so you can
    expect decent performance. (the 4 lines above take about 80 ms for a
    1000x1000 image on my PC)

    If that's not enough, you might want to use some specially optimized C
    library for this purpose. (I'd suggest Intel's IPP, but there are
    others).

    I really do not understand the code. Where did you get the varibales r,
    g, b and step and what does v produce?
  • No.23 | | 2621 bytes | |

    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)

    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
  • No.24 | | 1021 bytes | |

    "Paul McGuire" <ptmcg (AT) austin (DOT) rr._bogus_.comwrote in message
    news:Grhyg.21879$Cn6.17684 (AT) tornado (DOT) texas.rr.com
    "Chaos" <psnim2000 (AT) gmail (DOT) comwrote in message
    news:1154055002.495073.171650 (AT) i3g2000cwc (DOT) 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
    (#head-11870a08b0fa59a8622
    201abfac735ea47ffade5) - surely there must be some repeated colors in your
    image.
    -- Paul
  • No.25 | | 1167 bytes | |

    Paul McGuire wrote:
    "Paul McGuire" <ptmcg (AT) austin (DOT) rr._bogus_.comwrote in message
    news:Grhyg.21879$Cn6.17684 (AT) tornado (DOT) texas.rr.com
    "Chaos" <psnim2000 (AT) gmail (DOT) comwrote in message
    news:1154055002.495073.171650 (AT) i3g2000cwc (DOT) 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
    (#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.
  • No.26 | | 3721 bytes | |

    Chaos wrote:

    nikie wrote:
    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

    Milliseconds don't mean much unless we knew how big your images are and
    what hardware you're using.

    Have you considered using NumPy? Assuming you can get the image into a
    numpy array efficiently, the actual algorithm boils down to something
    like this:

    grey = r*0.3 +

    g*0.59 + b*0.11
    index = grey.argmin()
    x,y = index%step, index/step
    v = grey[x,y]

    where r,g,b and grey are numpy.ndarray objects; The arithmetic
    operators and the argmin-function are implemented in C, so you can
    expect decent performance. (the 4 lines above take about 80 ms for a
    1000x1000 image on my PC)

    If that's not enough, you might want to use some specially optimized C
    library for this purpose. (I'd suggest Intel's IPP, but there are
    others).

    I really do not understand the code. Where did you get the varibales r,
    g, b and step and what does v produce?

    Sorry, I should have commented it better. The idea is that r,g,b are
    numpy-arrays containig the r, g, b-pixel-values in the image:

    import numpy, Image
    img = Image.open("Image1.jpg")
    r = numpy.array(img.getdata(0))
    g = numpy.array(img.getdata(1))
    b = numpy.array(img.getdata(2))
    w,h = img.size

    The "step" is the length of one line of pixels, that is, the offset to
    a pixel (x,y) is x+y*step. (This is usually called "step" or "stride"
    in literature)

    step = w

    Now, I can use numpy's overridden arithmetic operators to do the
    per-pixel calculations (Note that numpy also overrides sin, cos, max,
    , but you'll have to use from numpy import * to get these overrides
    in your namespace):

    grey = r*0.3 + g*0.59 + b*0.11

    The multiplication-operator is overridden, so that "r*0.3" multiplies
    each value in the array "r" with "0.3" and returns the multiplied
    array, same for "g*0.59", "b*0.11". Adding the arrays adds them up
    value by value, and returns the sum array. This generally works quite
    well and intuitively if you perform only per-pixel operations. If you
    need a neighborhood, use slicing.
    The function "argmin" searches for the index of the minimum value in
    the array:

    index = grey.argmin()

    But since we want coordinates instead of indices, we'll have to
    transform these back using the step value:

    x,y = index % step, index / step

    Result:

    print x,y,r[index],g[index],b[index]

    Works for my image.

    Notes:
    - I'm _not_ sure if this is the fastest way to get an image into a
    numpy array. It's convenient, but if you need speed, digging into the
    numpy docs/newsgroup archive, and doing a few benchmarks for yourself
    would be a good idea
    - numpy does have 2d-Arrays, but I'm not that much of a numpy expert to
    tell you how to use that to get rid of the index/step-calculations.
    Again, numpy-docs/newsgroup might help
    - a general advice: using integer multiplications instead for
    floating-point may help with performance, too.
    - you said something about 10 ms, so I'm guessing your image doesn't
    come from a harddrive at all (because reading it alone will usually
    take longer than 10 ms). Numpy arrays have a C-Interface you might want
    to use to get data from a framegrabber/digital camera into a numpy
    array.
  • No.27 | | 953 bytes | |

    Fredrik Lundh wrote:
    Chaos wrote:

    I have tried PIL. Not only that, but the Image.eval function had no
    success either. I did some tests and I found out that Image.eval only
    called the function a certain number of times either 250, or 255.
    Unless I can find a working example for this function, its impossible
    to use.

    you might have better success by asking questions about the problem
    you're trying to solve, rather than about some artifact of your first
    attempt to solve it

    the following PIL snippet locates the darkest pixel in an image in about
    0.5 milliseconds for a 200x200 RGB image, on my machine:

    im = im.convert("L") # convert to grayscale
    lo, hi = im.getextrema() # find darkest pixel value
    lo = im.point(lambda x: x == lo) # highlight darkest pixel value
    x, y, _, _ = lo.getbbox() # locate uppermost/leftmost dark pixel

    </F>

    thank you that worked perfectly.

Re: Fastest Way To Loop Through Every Pixel


max 4000 letters.
Your nickname that display:
In order to stop the spam: 9 + 8 =
QUESTION ON "Development"

EMSDN.COM