Reputation: 36506
Given an image (.tiff or geotiff file) with exactly 22 colors (each with a distinct RGB value), what are the approaches to separate ("filter") them out into 22 separate images, each containing only those pixels with a specific RGB value?
Upvotes: 1
Views: 3622
Reputation: 35269
Here is a pixelwise way of doing it, which can work for any number of colors in the image (although it can get slow for many colours and large images). It also will work for paletted images (it converts them).
import Image
def color_separator(im):
if im.getpalette():
im = im.convert('RGB')
colors = im.getcolors()
width, height = im.size
colors_dict = dict((val[1],Image.new('RGB', (width, height), (0,0,0)))
for val in colors)
pix = im.load()
for i in xrange(width):
for j in xrange(height):
colors_dict[pix[i,j]].putpixel((i,j), pix[i,j])
return colors_dict
im = Image.open("colorwheel.tiff")
colors_dict = color_separator(im)
#show the images:
colors_dict.popitem()[1].show()
colors_dict.popitem()[1].show()
im.getcolors()
returns a list of all the colors in the image and the number of times they occur, as a tuple, unless the number of colors exceeds a max value (which you can specify, and defaults to 256).colors_dict
, keyed by the colors in the image, and with corresponding values of empty images.load()
to make pixel access faster as we read through the image.color_separator()
returns a dictionary of images, keyed by every unique colour in the image.To make it faster you could use load()
for every image in colors_dict
, but you may need to be a little careful as it could consume a lot of memory if the images have many colours and are large. If this isn't an issue then add (after the creation of colors_dict
):
fast_colors = dict((key, value.load()) for key, value in colors_dict.items())
and swap:
colors_dict[pix[j,i]].putpixel((j,i), pix[j,i])
for:
fast_colors[pix[j,i]][j,i] = pix[j,i]
22 color image:
22 color isolated images:
Upvotes: 5