Image.open出现错误,无法识别图像文件。

3

我正在尝试使用PIL的Image函数打开一个geotiff文件,但是它会引发错误:

OSError: cannot identify image file 'Whatever\\image\\I\\use.tiff'

我看到这里有一个关于图片在Python中无法识别的问题,例如这个。解决方案是使用:
Import Image 

代替
From PIL import Image

我认为这是一种过时的解决方案;我无法导入图片。另一种解决方法是将pillow更新到2.9,但5年后我们已经更新到5.0.0。我也尝试了4.0.0,但收到了相同的错误消息。 是否有最新的解决方案?

这是我的代码,这里是一个文件链接:

image_path = 'each\\image\\I\\use.tiff'

from PIL import Image
Image.open(image_path)

不,import Image 不是问题所在;在很久以前,PIL存在打包问题,无法安装正确的包(因此 PIL.Image 被安装为 Image)。 - Martijn Pieters
1
如果PIL / Pillow无法打开文件,则可能是不支持的格式或已损坏。请尝试使用https://pypi.python.org/pypi/GDAL/。 - Martijn Pieters
另一个可能性是该文件使用压缩,这需要您安装libtiff,请参见https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#tiff。无论如何,如果没有实际的文件进行测试,我们无法提供帮助。 - Martijn Pieters
我添加了一个文件。我可以使用gdal和qgis打开该文件,但PIL会引发错误。虽然这只是一个例子,但对我使用的每个TIFF都是如此。 - ArnJac
我会建议坚持使用GDAL或者转换为低位深度(最高16位)的格式。 - Martijn Pieters
如果您感兴趣,这是调试输出:https://gist.github.com/mjpieters/522f47fa0466d8520ee835bf4006aac4 - Martijn Pieters
3个回答

15

你有一个多通道的32位TIFF图像,但Pillow目前还不支持该格式。请参见问题 #1888

Pillow(和PIL)目前能够打开每个通道8位的多通道图像(例如RGB),但如果它们是单通道图像(例如灰度),则能够打开更高位深度的图像(例如I16、I32或Float32图像)。

[...]

要求

  • 我们应该能够支持常见的GIS格式以及高位深度的RGB(A)图像。
  • 至少4个通道,但可能会更多(参见#1839)
  • 不同的像素格式,包括I16、I32和Float。

我使用TIFF插件图像阅读器直接进行了测试,启用了调试模式,发现了这一点:

from PIL import TiffImagePlugin
TiffImagePlugin.DEBUG = True
with open(image_path, 'rb') as f:
    TiffImagePlugin.TiffImageFile(f)

其中包括输出:

tag: BitsPerSample (258) - type: short (3) Tag Location: 46 - Data Location: 218 - value: (32, 32, 32)

(下面是完整的调试输出)

您可以使用Python GDAL绑定来读取此格式。您也可以使用gdal_translate命令行实用程序将文件转换为Pillow 可以处理的格式; 对于多波段,您需要降到8位或转换为灰度。

例如,要将输入文件转换为PNG,可以使用以下命令:

gdal_translate -of PNG rgb_CGI.tiff rgb_CGI.png

之后Pillow可以打开PNG文件。


Pillow的TIFF插件的完整调试输出:

>>> from PIL import TiffImagePlugin
>>> TiffImagePlugin.DEBUG = True
>>> with open(image_path, 'rb') as f:
...     TiffImagePlugin.TiffImageFile(f)
...
*** TiffImageFile._open ***
- __first: 8
- ifh:  b'II*\x00\x08\x00\x00\x00'
Seeking to frame 0, on frame -1, __next 8, location: 8
Loading tags, location: 8
tag: ImageWidth (256) - type: short (3) - value: 2924
tag: ImageLength (257) - type: short (3) - value: 2088
tag: BitsPerSample (258) - type: short (3) Tag Location: 46 - Data Location: 218 - value: (32, 32, 32)
tag: Compression (259) - type: short (3) - value: 1
tag: PhotometricInterpretation (262) - type: short (3) - value: 1
tag: StripOffsets (273) - type: long (4) Tag Location: 82 - Data Location: 8576 - value: <table: 8352 bytes>
tag: SamplesPerPixel (277) - type: short (3) - value: 3
tag: RowsPerStrip (278) - type: short (3) - value: 1
tag: StripByteCounts (279) - type: long (4) Tag Location: 118 - Data Location: 224 - value: <table: 8352 bytes>
tag: PlanarConfiguration (284) - type: short (3) - value: 1
tag: ExtraSamples (338) - type: short (3) - value: (0, 0)
tag: SampleFormat (339) - type: short (3) Tag Location: 154 - Data Location: 16928 - value: (2, 2, 2)
tag: ModelPixelScaleTag (33550) - type: double (12) Tag Location: 166 - Data Location: 16934 - value: (0.25, 0.25, 0.0)
tag: ModelTiepointTag (33922) - type: double (12) Tag Location: 178 - Data Location: 16958 - value: <table: 48 bytes>
tag: GeoKeyDirectoryTag (34735) - type: short (3) Tag Location: 190 - Data Location: 17006 - value: <table: 72 bytes>
tag: GeoDoubleParamsTag (34736) - type: double (12) Tag Location: 202 - Data Location: 17078 - value: <table: 56 bytes>
tag: GeoAsciiParamsTag (34737) - type: string (2) Tag Location: 214 - Data Location: 17134 - value: Amersfoort / RD New|Amersfoort|
tag: ImageWidth (256) - type: short (3) - value: 2924
tag: ImageLength (257) - type: short (3) - value: 2088
tag: BitsPerSample (258) - type: short (3) Tag Location: 46 - Data Location: 218 - value: (32, 32, 32)
tag: Compression (259) - type: short (3) - value: 1
tag: PhotometricInterpretation (262) - type: short (3) - value: 1
tag: StripOffsets (273) - type: long (4) Tag Location: 82 - Data Location: 8576 - value: <table: 8352 bytes>
tag: SamplesPerPixel (277) - type: short (3) - value: 3
tag: RowsPerStrip (278) - type: short (3) - value: 1
tag: StripByteCounts (279) - type: long (4) Tag Location: 118 - Data Location: 224 - value: <table: 8352 bytes>
tag: PlanarConfiguration (284) - type: short (3) - value: 1
tag: ExtraSamples (338) - type: short (3) - value: (0, 0)
tag: SampleFormat (339) - type: short (3) Tag Location: 154 - Data Location: 16928 - value: (2, 2, 2)
tag: ModelPixelScaleTag (33550) - type: double (12) Tag Location: 166 - Data Location: 16934 - value: (0.25, 0.25, 0.0)
tag: ModelTiepointTag (33922) - type: double (12) Tag Location: 178 - Data Location: 16958 - value: <table: 48 bytes>
tag: GeoKeyDirectoryTag (34735) - type: short (3) Tag Location: 190 - Data Location: 17006 - value: <table: 72 bytes>
tag: GeoDoubleParamsTag (34736) - type: double (12) Tag Location: 202 - Data Location: 17078 - value: <table: 56 bytes>
tag: GeoAsciiParamsTag (34737) - type: string (2) Tag Location: 214 - Data Location: 17134 - value: Amersfoort / RD New|Amersfoort|
*** Summary ***
- compression: raw
- photometric_interpretation: 1
- planar_configuration: 1
- fill_order: 1
- size: (2924, 2088)
format key: (b'II', 1, (2, 2, 2), 1, (32, 32, 32), (0, 0))
- unsupported format
Traceback (most recent call last):
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 1196, in _setup
    self.mode, rawmode = OPEN_INFO[key]
KeyError: (b'II', 1, (2, 2, 2), 1, (32, 32, 32), (0, 0))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/ImageFile.py", line 102, in __init__
    self._open()
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 950, in _open
    self._seek(0)
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 1017, in _seek
    self._setup()
  File "/Users/mjpieters/Development/venvs/stackoverflow-3.6/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 1200, in _setup
    raise SyntaxError("unknown pixel mode")
SyntaxError: unknown pixel mode

我遇到了类似的问题。我进行了一些实验,发现在尝试打开CMYK/16位图像时出现问题。它不会在CMYK/8、RGB/8或RGB/16时报错。您能详细说明如何安装和使用GDAL吗?这似乎比Pillow更复杂。 - akinuri
我发布了一个关于GDAL安装的问题,因为它看起来很混乱。如果您能看一下这个链接,我将不胜感激:https://stackoverflow.com/q/50721107/2202732 - akinuri

1
我将tiff图像文件从64位格式转换为32位格式,这样就可以使用了。
你可以使用ImageMagick 7完成此操作:
magick oldimage.tiff -depth 8 newimage.tif

或者使用ImageMagick 6或更早版本:
convert out_0.tiff -depth 8 newimage.tiff

1

pyvips可以直接处理这样的TIFF文件。它将您的文件加载为具有两个Alpha通道的单色int32图像。

$ python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyvips
>>> x = pyvips.Image.new_from_file("rgb_CGI.tiff")
>>> x.width, x.height, x.bands, x.format, x.interpretation
(2924, 2088, 3, 'int', 'b-w')
>>> # getpoint reads out a pixel
>>> x.getpoint(10, 10)
[156.0, 141.0, 133.0]
>>> # avg finds the image average
>>> x.avg()
125.31475912560515
>>> 

它忽略了额外的GDAL标签,但您可以进行所有常规的2D图像处理,并且比PIL要快得多


FYI,pyvips不是标准模块。您需要下载Windows二进制文件并将bin文件夹添加到路径中。但它可以正常工作(其中PIL和tifffile无法加载和保存我的TIF文件)。 - BlaX

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