PIL? Извлечь все пиксели заданного значения RGB - PullRequest
1 голос
/ 28 декабря 2011

Учитывая изображение (файл .tiff или geotiff) с ровно 22 цветами (каждое с отдельным значением RGB), каковы подходы для их разделения («фильтрации») на 22 отдельных изображения, каждое из которых содержит только те пикселиконкретное значение RGB?

1 Ответ

4 голосов
/ 06 апреля 2012

Вот пиксельный способ сделать это, который может работать с любым количеством цветов в изображении (хотя это может стать медленным для многих цветов и больших изображений). Он также будет работать для палитровых изображений (он их преобразует).

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. Вызов im.getcolors() возвращает список всех цветов на изображении и количество их повторений в виде кортежа, если только число цветов не превышает максимальное значение (которое вы можете указать, и по умолчанию 256).
  2. Затем мы создаем словарь colors_dict, снабженный цветами на изображении и соответствующими значениями пустых изображений.
  3. Затем мы перебираем изображение для всех пикселей, обновляя соответствующую словарную запись для каждого пикселя. Выполнение этого означает, что нам нужно только один раз прочитать изображение. Мы используем load() для ускорения доступа к пикселям при чтении изображения.
  4. color_separator() возвращает словарь изображений, обозначаемый каждым уникальным цветом на изображении.

Чтобы сделать это быстрее, вы можете использовать load() для каждого изображения в colors_dict, но вам может потребоваться быть немного осторожнее, поскольку это может занять много памяти, если изображения имеют много цветов и имеют большой размер. Если это не проблема, добавьте (после создания colors_dict):

fast_colors = dict((key, value.load()) for key, value in colors_dict.items())

и своп:

colors_dict[pix[j,i]].putpixel((j,i), pix[j,i])

для:

fast_colors[pix[j,i]][j,i] = pix[j,i]

22 цветное изображение: enter image description here

22 цветных изолированных изображения:

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

...