Chapter 9
In some cases, we don't have a simple Boolean matching function. Instead, we're
forced to search for a minimum or maximum of some distance between items.
Assume that we have a table of Color objects as follows:
[Color(rgb=(239, 222, 205), name='Almond'),
Color(rgb=(255, 255, 153), name='Canary'),
Color(rgb=(28, 172, 120), name='Green'),...
Color(rgb=(255, 174, 66), name='Yellow Orange')]
For more information, see Chapter 6, Recursions and Reductions, where we showed you
how to parse a file of colors to create namedtuple objects. In this case, we've left the
RGB as a triple, instead of decomposing each individual field.
An image will have a collection of pixels:
pixels= [(([(r, g, b), (r, g, b), (r, g, b), ...)
As a practical matter, the Python Imaging Library (PIL) package presents the pixels
in a number of forms. One of these is the mapping from (x, y) coordinate to RGB
triple. For more information, visit https://pypi.python.org/pypi/Pillow for the
Pillow project documentation.
Given a PIL.Image object, we can iterate over the collection of pixels with something
like the following commands:
def pixel_iter(image):
w, h = img.size
return ((c, img.getpixel(c)) for c in product(range(w),
range(h)))
We've determined the range of each coordinate based on the image size. The
calculation of the product(range(w), range(h)) method creates all the possible
combinations of coordinates. It is, effectively, two nested for loops.
This has the advantage of providing each pixel with its coordinates. We can then
process the pixels in no particular order and still reconstruct an image. This is
particularly handy when using multiprocessing or multithreading to spread the
workload among several cores or processors. The concurrent.futures module
provides an easy way to distribute work among cores or processors.