使用Python OpenCV读取带有颜色索引的.tiff文件

3
我有{{link1:包含颜色索引图像的.tiff文件}},即图像本身(1024x1024)每个像素包含一个索引(在我的情况下为0,1),在tiff文件中有一个颜色映射表(256x3)将这些代码映射到颜色。
code    R   G   B
_________________
0 =     0   0   0
1 =     140 215 115
2 =     255 255 255 ... (other codes are irrelevant for me)

我想使用Python读取索引图像。我正在使用OpenCV,并按照文档尝试了以下方法(不使用-1标志将得到RGB图像):
img = cv2.imread(file, cv2.IMREAD_UNCHANGED)     # cv2.IMREAD_UNCHANGED = -1

我期望得到未改变的索引颜色图像,即一个包含值为0或1的1024x1024像素图像。然而,我得到了一个包含值为0或181的1024x1024像素图像。我不知道181是从哪里来的(不是相应颜色值的平均值; (140+215+115)/3=157),而且我也不想手动更改这些值。有没有一种方法可以使用Python OpenCV(或其他库)读取彩色索引TIFF文件,以获取索引图像和(可选的)颜色映射?
一个示例文件在这里。使用MATLAB读取此数据会按预期工作:
img = imread(file);              % returns img: (1024, 1024) with values [0, 1]
[img, cmap] = imread(file);      % returns img: (1024, 1024) with values [0, 1], cmap (256x3)
1个回答

1

更新的答案

看起来 Pillow 也可以从您的TIFF中提取调色板。我不是Python专家,但我写了这个代码,它似乎可以工作:

from PIL import Image

image = Image.open('indexed.tif')
print(image.getpalette()[:12])

输出

[0, 0, 0, 140, 215, 115, 255, 255, 255, 0, 0, 0]

原始答案

你可以在绝大多数Linux发行版上轻松地使用命令行中的ImageMagick完成你要求的操作,而且它也可用于macOS和Windows。

首先回答最后一个问题,你可以使用以下命令提取调色板:

identify -verbose indexed.tif

样例输出
Image: indexed.tif
  Format: TIFF (Tagged Image File Format)
  Mime type: image/tiff
  Class: PseudoClass
  Geometry: 1024x1024+0+0
  Resolution: 72x72
  Print size: 14.2222x14.2222
  Units: PixelsPerInch
  Colorspace: sRGB
  Type: Palette
  Endianess: LSB
  Depth: 8-bit
  Channel depth:
    Red: 8-bit
    Green: 8-bit
    Blue: 8-bit
  Channel statistics:
    Pixels: 1048576
    Red:
      min: 0  (0)
      max: 140 (0.54902)
      mean: 24.9271 (0.0977535)
      standard deviation: 53.5578 (0.210031)
      kurtosis: 0.832982
      skewness: 1.68315
      entropy: 0.675795
    Green:
      min: 0  (0)
      max: 215 (0.843137)
      mean: 38.281 (0.150121)
      standard deviation: 82.2495 (0.322547)
      kurtosis: 0.832982
      skewness: 1.68315
      entropy: 0.675795
    Blue:
      min: 0  (0)
      max: 115 (0.45098)
      mean: 20.4759 (0.0802975)
      standard deviation: 43.9939 (0.172525)
      kurtosis: 0.832982
      skewness: 1.68315
      entropy: 0.675795
  Image statistics:
    Overall:
      min: 0  (0)
      max: 215 (0.843137)
      mean: 27.8947 (0.109391)
      standard deviation: 59.9337 (0.235034)
      kurtosis: 2.61693
      skewness: 2.01681
      entropy: 0.675795
  Colors: 2
  Histogram:
    861876: (  0,  0,  0) #000000 black
    186700: (140,215,115) #8CD773 srgb(140,215,115)
  Colormap entries: 256
  Colormap:
         0: (  0,  0,  0,255) #000000FF black
         1: (140,215,115,255) #8CD773FF srgba(140,215,115,1)
         2: (255,255,255,255) #FFFFFFFF white
         3: (  0,  0,  0,255) #000000FF black
         4: (  0,  0,  0,255) #000000FF black
         5: (  0,  0,  0,255) #000000FF black
         6: (  0,  0,  0,255) #000000FF black
         7: (  0,  0,  0,255) #000000FF black
         8: (  0,  0,  0,255) #000000FF black
         ...
         ...

你可以在上面的最后8行看到你的调色板(colormap)。更方便的命令是:
identify -verbose indexed.tif | grep -A8 "Colormap:"
  Colormap:
     0: (  0,  0,  0,255) #000000FF black
     1: (140,215,115,255) #8CD773FF srgba(140,215,115,1)
     2: (255,255,255,255) #FFFFFFFF white
     3: (  0,  0,  0,255) #000000FF black
     4: (  0,  0,  0,255) #000000FF black
     5: (  0,  0,  0,255) #000000FF black
     6: (  0,  0,  0,255) #000000FF black
     7: (  0,  0,  0,255) #000000FF black

现在是关于你问题的第一部分。获取黑色零和其他颜色为一的图像最简单的方法是将填充颜色设置为一(ImageMagick 称之为 gray(1)),然后将不是黑色的所有内容都变成该颜色。最后,保存为 PGM(便携式灰度映射)文件,OpenCV 可以在没有任何库的情况下读取它,而且它不能包含调色板,因此没有机会搞乱你的东西:
convert indexed.tif -fill "gray(1)" +opaque black indices.pgm

这就是实际答案的结尾,接下来的所有内容都只是额外信息。
请注意,这将是一张非常暗淡、对比度低的图像,因为它只包含0或1,范围在0-255之间,所以如果想看到任何东西,您需要对其进行归一化或对比度拉伸处理。
convert indices.pgm -normalize result.jpg

enter image description here


请注意,如果您使用的是ImageMagick v7+,则上述命令中的identify将变为magick identify,而convert将变为magick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接