ph0*_*t0n 9 python tiff python-imaging-library
我的系统是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)
Run Code Online (Sandbox Code Playgroud)
负值下降65,536 ......可能不是巧合.
如果我假装改变像素并通过PIL恢复到TIFF图像(只需将数组作为图像放回):
newimg = Image.fromarray(imgarray)
Run Code Online (Sandbox Code Playgroud)
我收到错误:
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
Run Code Online (Sandbox Code Playgroud)
我Image.fromarray()在PIL文档中找不到.我试过加载过Image.fromstring(),但我不理解PIL文档,并且没有什么例子.
如上面的代码所示,PIL似乎"检测"了数据I;16B.从我从PIL文档中可以看出,模式I是:
*I* (32-bit signed integer pixels)
Run Code Online (Sandbox Code Playgroud)
显然,这是不正确的.
我在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)
Run Code Online (Sandbox Code Playgroud)
瞧瞧.我认为这不符合我的"轻量级"要求,因为Matplotlib(对我来说)是一个沉重的模块,但是将图像变成Numpy数组非常简单.我希望这有助于其他人快速找到解决方案,因为这对我来说并不明显.
小智 5
试试Pillow,"友好"的PIL叉子.他们最近在16位和32位图像中添加了更好的支持,包括在numpy阵列界面中.此代码适用于最新的枕头:
from PIL import Image
import numpy as np
img = Image.open('data.tif')
data = np.array(img)
Run Code Online (Sandbox Code Playgroud)