ПИЛ? Извлечь все пиксели заданного значения RGB

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


person Calvin Cheng    schedule 28.12.2011    source источник


Ответы (1)


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

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-цветное изображение: введите здесь описание изображения

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

введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображения введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображения введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображения введите описание изображения здесь введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображениявведите здесь описание изображения введите описание изображения здесь введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображения

person fraxel    schedule 06.04.2012
comment
Итак, как бы вы объединили несколько из 22 изображений, скажем, желтое и красное? Или, по крайней мере, не иметь черного цвета на изображениях, чтобы можно было вставить несколько из 22 изображений в новое изображение? - person klocey; 20.04.2013