Как узнать, какие цвета имеет в виду PIL при получении всех уникальных цветов в геоТИФЕ?

#python #colors #python-imaging-library #rgb #color-palette

Вопрос:

У меня есть куча изображений геоТИФА, которые я пытаюсь проанализировать. Например, вот один из них ниже:

esiber_2000jul28a_3c

Я хотел бы подсчитать, сколько пикселей на этом изображении синие, а сколько белых. Я использую следующий код для получения этой информации:

 from PIL import Image from collections import defaultdict  # open the image (fp is the filepath of the image) im = Image.open(fp) # the image is in 'P' mode  # convert to RGB?  # im.convert('RGB')   by_color = defaultdict(int) for pixel in im.getdata():  by_color[pixel]  = 1  im_col = Image.Image.getcolors(im) print(im_col) print(by_color)  

Эти изображения находятся в режиме «P», или в режиме палитрирования. Независимо от того, конвертирую ли я эти изображения в режим «RGB», раскомментировав эту строку кода выше, я получу следующий вывод в этом формате (этот конкретный вывод для примера изображения выше).:

 [(777, 0), (196, 1), (378, 2), (1149, 3)] defaultdict(lt;class 'int'gt;, {2: 378, 3: 1149, 1: 196, 0: 777})  

Итак, насколько я понимаю, 0, 1, 2 и 3 представляют уникальные цвета пикселей, а соответствующие 777, 196, 378 и 1149 представляют количество раз, когда эти пиксели находятся на изображении (и если я сложу 777 196 378 1149 = 2500, это имеет смысл, так как это изображение размером 50 х 50 пикселей).

Мои две основные проблемы заключаются в следующем:

  1. Почему существует четыре значения? Согласно изображению, должно быть только три значения: черный фон, синий океан и белый лед — есть ли где-то скрытый цвет?
  2. Как я могу узнать, какие цвета представляют 0, 1, 2 и 3 в паллетированном формате? Я поискал какой-то цветовой код на каком-то веб-сайте и обнаружил, что 0 означает 2, но 1 означает зеленый, что, как я знаю, неправильно, поэтому я определенно что-то неправильно понимаю. Есть ли способ получить этот «цветовой код» из изображения с помощью PIL?

Заранее спасибо.

Комментарии:

1. Пожалуйста, поделитесь своим реальным полноразмерным изображением с помощью Dropbox, Google Диска или чего-то подобного. Спасибо.

Ответ №1:

Ваше изображение немного странное, в нем две пары одинаковых элементов палитры:

  • индекс 1 == индекс 3, и
  • индекс 2 == индекс 4

Вы можете увидеть это с помощью ImageMagick, если выполните эту команду в терминале:

 magick identify -verbose 1QgAe.png  

Сокращенный вывод

 ... ...  Histogram:  12431: (0,0,0) #000000 black  6205: (0,0,254) #0000FE srgb(0,0,254)  21364: (254,254,223) #FEFEDF srgb(254,254,223)  Colormap entries: 256  Colormap:  0: (0,0,0,1) #000000FF black  1: (254,254,223,1) #FEFEDFFF srgba(254,254,223,1)  2: (0,0,254,1) #0000FEFF srgba(0,0,254,1)  3: (254,254,223,1) #FEFEDFFF srgba(254,254,223,1)  4: (0,0,254,1) #0000FEFF srgba(0,0,254,1) ... ...  

21 364 пикселя, которые являются srgb(254 254 223), представляют собой всего лишь совокупные значения 3126 и 18 238.


Вы также можете увидеть это pngcheck вот так:

 pngcheck -p 1QgAe.png  File: 1QgAe.png (6135 bytes) PLTE chunk: 256 palette entries  0: ( 0, 0, 0) = (0x00,0x00,0x00)  1: (254,254,223) = (0xfe,0xfe,0xdf)  2: ( 0, 0,254) = (0x00,0x00,0xfe)  3: (254,254,223) = (0xfe,0xfe,0xdf)  4: ( 0, 0,254) = (0x00,0x00,0xfe)  5: ( 0, 0, 0) = (0x00,0x00,0x00)  ...  ...  

Если вы хотите увидеть это в Python с PIL, вы можете использовать этот код, и вы увидите, что он такой же:

 #!/usr/bin/env python3  from PIL import Image  # Load image im = Image.open('1QgAe.png')  if im.mode=='P':  colours = im.getcolors()  print(f'Colours: {colours}')   palette = im.getpalette()  for i in range(256):  r = palette[3*i]  g = palette[3*i 1]  b = palette[3*i 2]  print(f'palette[{i}] = rgb({r},{g},{b})')  

Пример вывода

 Colours: [(12431, 0), (3126, 1), (6205, 2), (18238, 3)]  palette[0] = rgb(0,0,0) palette[1] = rgb(254,254,223) palette[2] = rgb(0,0,254) palette[3] = rgb(254,254,223) palette[4] = rgb(0,0,254) palette[5] = rgb(0,0,0) palette[6] = rgb(0,0,0)  

Если вам удобно с Numpy, вы можете использовать:

 from PIL import Image import numpy as np  # Load image im = Image.open('1QgAe.png') palette = np.array(im.getpalette()).reshape(256,3) print(palette)