一个"I;16"图像文件的numpy.array

6
我想使用TIFF图像有效地保存大量的测量数据数组。通过将它们设置为mode="I;16"(对应于我的16位数据范围),它们产生2MB的文件(~1000x1000“像素”)。这很好。
但是,当涉及到分析时,我遇到了重新转换它们为数组的麻烦。对于32位数据(->“I”),numpy.array命令可以正常工作。在“I;16”的情况下,结果是一个0D numpy数组,其中TIFF作为[0,0]条目。
有没有办法让它工作?我真的很想避免使用32位图像,因为我不需要范围,而且它会使所需的HDD空间加倍(计划进行很多这样的测量...)

1
你能展示一下你加载图片的代码吗?你是使用PIL的Image类吗? - Ferdinand Beyer
我使用Image类,为了加载图像,我只需使用Image.open("im.tif")。 - Jakob
1
PIL错误:https://dev59.com/gWw05IYBdhLWcg3wahRN - mankoff
感谢mankoff的提示,但我还是不太明白。所以我必须将其转换为32位->模式'I'对吗?当我这样做并将结果加载到numpy数组中时,我得到了错误的数据(完整的uint16比例,从0到65000多)。我不想处理图像,我需要将TIFF灰度转换为实际值!答案在那里吗? - Jakob
也许我应该解释一下我在这里做什么:我将数据存储在一个numpy数组中,稍微重新调整一下比例,以更好地使用16位数据空间(log10、线性扩展),然后四舍五入并将其设置为numpy.int16。我的数组范围大约是-20000 < x < +20000。使用PIL.fromarray(自动模式“ I;16”)生成我的图像并保存它。这些就是我稍后要打开和重新转换的图像/数据映射。 - Jakob
3个回答

6
这应该可以解决问题(使用pillow/PIL方法,对于16位图像速度较慢,请参见下文)。
from PIL import Image
import numpy as np

data = np.random.randint(0,2**16-1,(1000,1000))
im = Image.fromarray(data)
im.save('test.tif')

im2 = Image.open('test.tif')
data2 = np.array(im2.getdata()).reshape(im2.size[::-1])

使用 C. Gohlke 的 tifffile 来解决问题(非常快速)的另一种方法:

import tifffile

fp = r'path\to\image\image.tif'

with tifffile.TIFFfile(fp) as tif:
    data = tif.asarray()

2
在我发帖之前,不知何故没有注意到你的回答。我同意,这是最好的解决方法,但我认为您需要重新调整reshape的大小...应该是...reshape(im2.size[::-1]) - Joe Kington
没错!im.size => (width, height),但我们希望我们的numpy数组是以(高度,宽度)的形式存在的。感谢您的纠正。 - otterb
使用相对较新的PIL版本(2.6.1),似乎无法正常工作。fromarray()方法会抛出异常“无法处理此数据类型”。感谢提供tifffile参考,我会尝试一下。 - gatoatigrado
哦,太棒了,tifffile真的很快!谢谢! - gatoatigrado

3
您可以使用GDAL + Numpy/Scipy来读取具有16位通道数据的栅格图像:
import gdal
tif = gdal.Open('path.tif')
arr = tif.ReadAsArray()

0

将(ImageJ)TIFF转换为8位numpy数组

im = numpy.array(Image.open('my.tiff'))
n = (im / numpy.amax(im) * 255).astype(numpy.uint8)

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