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?

有帮助吗?

解决方案

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()
  1. Calling 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).
  2. We then build a dictionary colors_dict, keyed by the colors in the image, and with corresponding values of empty images.
  3. We then iterate over the image for all pixels, updating the appropriate dictionary entry for each pixel. Doing it like this means we only need to read through the image once. We use load() to make pixel access faster as we read through the image.
  4. 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: enter image description here

22 color isolated images:

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top