在 geoTIFF 中获取所有唯一颜色时,如何知道 PIL 指的是啥颜色?
Posted
技术标签:
【中文标题】在 geoTIFF 中获取所有唯一颜色时,如何知道 PIL 指的是啥颜色?【英文标题】:How to know what colors PIL is referring to when getting all unique colors in a geoTIFF?在 geoTIFF 中获取所有唯一颜色时,如何知道 PIL 指的是什么颜色? 【发布时间】:2021-12-06 16:08:52 【问题描述】:我有一堆要分析的 geoTIFF 图像。例如,下面是一个:
我想计算这张图片中有多少像素是蓝色的,有多少是白色的。我正在使用以下代码来获取此信息:
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(<class 'int'>, 2: 378, 3: 1149, 1: 196, 0: 777)
所以,据我了解,0、1、2 和 3 代表唯一的像素颜色,而 777、196、378 和 1149 分别代表这些像素在图像中的次数(如果我加起来 777 + 196 + 378 + 1149 = 2500,这是有道理的,因为这是一张 50 像素 x 50 像素的图像)。
我的两个主要担忧是:
-
为什么有四个值?根据图像,应该只有三个值:黑色背景、蓝色海洋和白色冰 - 是否有隐藏的颜色?
我如何知道 0、1、2 和 3 在托盘格式中代表什么颜色?我在某个网站上查找了一些颜色代码,我发现 0 表示 2,但 1 表示绿色,我知道这是不对的,所以我肯定在这里误解了一些东西。有没有办法使用 PIL 从图像中获取这个“颜色代码”?
提前致谢。
【问题讨论】:
请使用 Dropbox 或 Google Drive 等分享您的实际全尺寸图像。谢谢。 【参考方案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)
...
...
srgb(254,254,223) 的 21,364 像素只是 3,126 和 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)
...
...
如果你想用 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)')
样本输出
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)
【讨论】:
以上是关于在 geoTIFF 中获取所有唯一颜色时,如何知道 PIL 指的是啥颜色?的主要内容,如果未能解决你的问题,请参考以下文章