Python PIL难以处理未压缩的16位TIFF图像 [英] Python PIL struggles with uncompressed 16-bit TIFF images
问题描述
我的系统是Mac OS X v10.8.2.我有几个2560x500未压缩的16位TIFF图像(灰度,无符号16位整数).我首先尝试使用PIL(通过Homebrew,版本1.7.8安装)加载它们:
My system is Mac OS X v10.8.2. I have several 2560x500 uncompressed 16-bit TIFF images (grayscale, unsigned 16-bit integers). I first attempt to load them using PIL (installed via Homebrew, version 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,可能不是巧合.
The negative values are off by 65,536... probably not a coincidence.
如果我假装改变像素并通过PIL恢复为TIFF图像(只需将阵列放回图像中即可):
If I pretend to alter pixels and revert back to TIFF image via PIL (by just putting the array back as an image):
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文档,因此示例方式很少.
I can't find Image.fromarray()
in the PIL documentation. I've tried loading via Image.fromstring()
, but I don't understand the PIL documentation and there is little in the way of example.
如上面的代码所示,PIL似乎将数据检测"为I;16B
.从PIL文档可以看出,模式I
是:
As shown in the code above, PIL seems to "detect" the data as I;16B
. From what I can tell from the PIL docs, mode I
is:
*I* (32-bit signed integer pixels)
显然,这是不正确的.
我在SX上发现许多帖子,暗示PIL不支持16位图像.我已经找到使用pylibtiff的建议,但我相信这仅是Windows?
I find many posts on SX suggesting that PIL doesn't support 16-bit images. I've found suggestions to use pylibtiff, but I believe that is Windows only?
我正在寻找一种轻量级"的方式来在Python中使用这些TIFF图像.令我感到惊讶的是,这很困难,这使我相信问题对于其他人来说将是显而易见的.
I am looking for a "lightweight" way to work with these TIFF images in Python. I'm surprised it is this difficult and that leads me to believe the problem will be obvious to others.
推荐答案
事实证明Matplotlib在两行代码行中处理16位未压缩的TIFF图像:
It turns out that Matplotlib handles 16-bit uncompressed TIFF images in two lines of code:
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数组非常简单.我希望这可以帮助其他人快速找到解决方案,因为这对我而言并不明显.
Et voila. I suppose this doesn't meet my requirements as "lightweight" since Matplotlib is (to me) a heavy module, but it is spectacularly simple to get the image into a Numpy array. I hope this helps someone else find a solution quickly as this wasn't obvious to me.
这篇关于Python PIL难以处理未压缩的16位TIFF图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!