Python PIL 难以处理未压缩的 16 位 TIFF 图像

标签 python python-imaging-library tiff

我的系统是 Mac OS X v10.8.2。我有几个 2560x500 未压缩的 16 位 TIFF 图像(灰度,无符号 16 位整数)。我首先尝试使用 PIL(通过 Homebrew 安装,版本 1.7.8)加载它们:

from PIL import Image
import numpy as np

filename = 'Rocks_2ptCal_750KHz_20ms_1ma_120KV_2013-03-06_20-02-12.tif'
img = Image.open(filename)

# >>> img
# <PIL.TiffImagePlugin.TiffImageFile image mode=I;16B size=2560x500 at 0x10A383C68>

img.show() 

# almost all pixels displayed as white.  Not correct.  
# MatLab, EZ-draw, even Mac Preview show correct images in grayscale.

imgdata = list(img.getdata()) 

# most values negative:
# >>> imgdata[0:10]
# [-26588, -24079, -27822, -26045, -27245, -25368, -26139, -28454, -30675, -28455]

imgarray = np.asarray(imgdata, dtype=np.uint16) 

# values now correct
# >>> imgarray
# array([38948, 41457, 37714, ..., 61922, 59565, 60035], dtype=uint16)

负值相差 65,536...可能不是巧合。

如果我假装更改像素并通过 PIL 恢复为 TIFF 图像(只需将数组放回图像):

newimg = Image.fromarray(imgarray)

我收到错误:

File "/usr/local/lib/python2.7/site-packages/PIL/Image.py", line 1884, in fromarray
    raise TypeError("Cannot handle this data type")
TypeError: Cannot handle this data type

我在 PIL 文档中找不到 Image.fromarray()。我试过通过 Image.fromstring() 加载,但我不理解 PIL 文档,也没有什么示例。

如上面的代码所示,PIL 似乎将数据“检测”为I;16B。从 PIL 文档中我可以看出,模式 I 是:

*I* (32-bit signed integer pixels)

显然,这是不正确的。

我在 SX 上发现很多帖子暗示 PIL 不支持 16 位图像。我找到了使用 pylibtiff 的建议,但我认为这仅适用于 Windows?

我正在寻找一种在 Python 中处理这些 TIFF 图像的“轻量级”方法。我很惊讶竟然如此困难,这让我相信这个问题对其他人来说是显而易见的。

最佳答案

事实证明,Matplotlib 在行代码中处理 16 位未压缩的 TIFF 图像:

import matplotlib.pyplot as plt
img = plt.imread(filename)

# >>> img
# array([[38948, 41457, 37714, ..., 61511, 61785, 61824],
#       [39704, 38083, 36690, ..., 61419, 60086, 61910],
#       [41449, 39169, 38178, ..., 60192, 60969, 63538],
#       ...,
#       [37963, 39531, 40339, ..., 62351, 62646, 61793],
#       [37462, 37409, 38370, ..., 61125, 62497, 59770],
#       [39753, 36905, 38778, ..., 61922, 59565, 60035]], dtype=uint16)

等等。我想这不符合我作为“轻量级”的要求,因为 Matplotlib(对我来说)是一个沉重的模块,但是将图像放入 Numpy 数组非常简单。我希望这可以帮助其他人快速找到解决方案,因为这对我来说并不明显。

关于Python PIL 难以处理未压缩的 16 位 TIFF 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15284601/

相关文章:

python - 代码块中的 Sphinx 变量替换

pdf - Linux PDF 转 TIFF 质量问题

c# - 如何在 Silverlight 上显示 tiff 文件?

python - “is”运算符对非缓存整数的行为异常

python - 标准化具有多个零的像素输入数据

python - 将图像中的对象排成一行

python - 将图像中的每个像素乘以一个因子

python - 是否可以在所有平台上确定性地从 jpeg 文件中读取像素?

java - 使用 Java ImageIO 进行 Tiff 压缩

python - 如何在 PyQt 中获取命名颜色?