简体   繁体   English

在 geoTIFF 中获取所有独特颜色时,如何知道 PIL 指的是什么颜色?

[英]How to know what colors PIL is referring to when getting all unique colors in a geoTIFF?

I have a bunch of geoTIFF images I am trying to analyze.我有一堆想要分析的 geoTIFF 图像。 For example, here is one below:例如,下面是一个:

esiber_2000jul28a_3c

I would like to obtain a count of how many pixels in this image are blue, and how many are white.我想计算此图像中有多少像素是蓝色的,有多少是白色的。 I am using the following code to obtain this information:我正在使用以下代码来获取此信息:

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)

These images are in 'P', or palettized mode.这些图像处于“P”或调色模式。 Whether or not I convert these images to 'RGB' mode by uncommenting that line of code above, I get the following output in this format (this specific output is for the example image above):无论我是否通过取消注释上面那行代码将这些图像转换为“RGB”模式,我都会以这种格式获得以下输出(此特定输出适用于上面的示例图像):

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

So, from my understanding, the 0, 1, 2, and 3 represent the unique pixel colors, and the respective 777, 196, 378, and 1149 represent the amount of times these pixels are in the image (and if I add up 777 + 196 + 378 + 1149 = 2500, this makes sense, since this is a 50 pixel x 50 pixel image).所以,根据我的理解,0、1、2 和 3 代表独特的像素颜色,而各自的 777、196、378 和 1149 代表这些像素在图像中的次数(如果我加起来 777 + 196 + 378 + 1149 = 2500,这是有道理的,因为这是一个 50 像素 x 50 像素的图像)。

My two main concerns are:我的两个主要问题是:

  1. Why are there four values?为什么有四个值? According to the image, there should only be three values: black background, blue ocean, and white ice - is there a hidden color somewhere?根据图像,应该只有三个值:黑色背景,蓝色海洋和白色冰 - 某处是否有隐藏颜色?
  2. How can I know what colors the 0, 1, 2, and 3 represent in palletized format?我如何知道 0、1、2 和 3 以托盘化格式表示什么颜色? I looked for some color code on some website, and I found that 0 meant 2, but the 1 meant green, which I know isn't right, so I'm definitely misunderstanding something here.我在某个网站上查找了一些颜色代码,我发现 0 表示 2,但 1 表示绿色,我知道这是不对的,所以我肯定在这里误解了一些东西。 Is there a way to get this 'color code' from the image using PIL?有没有办法使用 PIL 从图像中获取这个“颜色代码”?

Thanks in advance.提前致谢。

Your image is a little bit weird, it has two pairs of identical palette entries:你的图像有点奇怪,它有两对相同的调色板条目:

  • index 1 == index 3, and索引 1 == 索引 3,和
  • index 2 == index 4索引 2 == 索引 4

You can see that with ImageMagick if you run this command in Terminal:如果您在终端中运行此命令,您可以使用ImageMagick看到:

magick identify -verbose 1QgAe.png

Abbreviated output缩写输出

...
...
  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)
...
...

The 21,364 pixels that are srgb(254,254,223) are just the combined totals of 3,126 and 18,238. srgb(254,254,223) 的 21,364 个像素只是 3,126 和 18,238 的总和。


You can equally see it with pngcheck like this:你也可以像这样用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)
  ...
  ...

If you want to see that in Python with PIL, you can use this code and you will see it is the same:如果您想在带有 PIL 的 Python 中看到它,您可以使用此代码,您将看到它是相同的:

#!/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})')

Sample output样本输出

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)

If you are comfortable with Numpy, you can use:如果您对 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM