tags:

views:

63

answers:

4

I have a simple black and white only gif image (400x400px let's say).

I need to get all pixels from that image and find whether they are black or white. I need to create a dictionary with the information about the pixels and their colors then.

I'm pretty new to python so I am kinda struggling with this. But here goes my script so far:

#!/usr/bin/env python

import os
import Image

os.chdir("D:/python-projects")
aImage = Image.open("input.gif")

aPixelsBlackOrWhiteDictionary = {}
# now I need to fill the dictionary with values such as
# "X,Y": 0
# "X,Y": 1
# where X,Y are coordinates and 0/1 i the pixel color (b/w)

Basically I want the final dictionary to be something like this:

"0,0" : 0 # pixel with X=0,Y=0 coordinates is black
"1,0" : 1 # pixel with X=1,Y=0 coordinates is White

EDIT:

When I try:

print aImage[0, 0]

I get an error:

Traceback (most recent call last):
  File "D:\python-projects\backprop.py", line 15, in <module>
    print aImage[0, 0]
  File "C:\Python26\lib\site-packages\pil-1.1.7-py2.6-win32.egg\Image.py", line
512, in __getattr__
    raise AttributeError(name)
AttributeError: __getitem__
+1  A: 

Try:

pix = aImage.load()
print pix[x, y]

Also note that you can use tuples as dictionary keys, you can use mydict[(x, y)] instead of mydict["x,y"].

This pixel information is already stored in the image, why store it in a dict?

Paulo Scardine
I get an error. See my updated answer.
Richard Knop
Doesn't seem to have worked very well...
SamB
@Richard: Are you using an old version of PIL? http://www.pythonware.com/library/pil/handbook/image.htm says this will work in PIL 1.1.6+
Brian
@Richard: fixed. Access with this method is a lot faster than getpixel and putpixel.
Paulo Scardine
@Brian: there was an error in the sample code before edition.
Paulo Scardine
+1  A: 

Are you sure you want to do that? It would be horrendously inefficient to use a dictionary to store this data.

I would think a numpy array would be much more appropriate...

SamB
more a comment than an answer...
Paulo Scardine
This is just a small image (400x400 pixels) so I don't think it matters. But I might refactor the code once I get everything I need working so it is more efficient.
Richard Knop
+1  A: 

You should be using getpixel rather than using indexing operators. Note that this may be very slow. You would be better off using getdata, which returns all of pixels as a sequence.

See http://www.pythonware.com/library/pil/handbook/image.htm .

Brian
I dont think this information is correct. Access via the object returned by Image.open() is a lot faster than getpixel and putpixel.
Paulo Scardine
@Paulo: My point was that he should use `getpixel` because indexing would not compile with his code, not that he should use `getpixel` in general. As my post says, `getpixel` is slow. However, I think `getdata` and indexing are probably equally appropriate from an efficiency perspective.
Brian
@Brian: sorry, I misread your answer.
Paulo Scardine
+1  A: 

If you wanted to see if a thumb was mono you could try this:-

def is_mono(image, variance=5):
    img_dta = list(im.getdata())   
    colour_test = lambda r,g,b : abs(r-g) > variance or abs(g-b) > variance
    if any([colour_test(r,g,b) for (r,g,b) in img_dta]):  return False
    return True

url1 = 'http://farm5.static.flickr.com/4145/5090947066_0d9d45edf4_s.jpg' # Mono
url2 = 'http://farm5.static.flickr.com/4087/5090362043_03c2da75d4_s.jpg' # Colour
for url in (url1, url2):
    dta = urllib.urlopen(url).read()
    im = Image.open(StringIO(dta))
    print is_mono(im)

>

True
False
Dantalion