有没有人有一种方法可以在Python中导入每通道16位,3通道TIFF图像?
我还没有找到一种方法,在处理TIFF格式时会保留每个通道的16位深度。我希望一些有用的灵魂能有解决方案。
以下列出了我迄今为止尝试过但未取得成功的结果:
import numpy as np
import PIL.Image as Image
import libtiff
import cv2
im = Image.open('a.tif')
# IOError: cannot identify image file
tif = libtiff.TIFF.open('a.tif')
im = tif.read_image()
# im only contains one of the three channels. im.dtype is uint16 as desired.
im = []
for i in tif.iter_images():
# still only returns one channel
im = np.array(cv2.imread('a.tif'))
# im.dtype is uint8 and not uint16 as desired.
# specifying dtype as uint16 does not correct this
到目前为止,我找到的唯一解决方案是使用ImageMagick将图像转换为PNG。然后,沼泽标准matplotlib.pyplot.imread
读取PNG文件没有任何问题。
我遇到的另一个问题是将任何numpy数组保存为16位PNG文件,到目前为止还不是直截了当。
答案 0 :(得分:29)
功能有限,特别是在写回磁盘非RGB图像时,Christoph Gohlke's tifffile
module读取3通道16位TIFF并没有问题,我只是测试了它:
>>> import tifffile as tiff
>>> a = tiff.imread('Untitled-1.tif')
>>> a.shape
(100L, 100L, 3L)
>>> a.dtype
dtype('uint16')
而且Photoshop在没有抱怨我从做什么的情况下阅读:
>>> tiff.imsave('new.tiff', a)
答案 1 :(得分:22)
@Jaime的答案有效。
与此同时,我设法在OpenCV中使用cv2.imread
来解决问题。
默认情况下,cv2.imread
会将a.tif
中的16位三通道图像转换为8位,如问题所示。
cv2.imread
接受文件名(cv2.imread(filename[, flags])
)后面的标志,该标志指定加载图像的颜色类型cf. documentation:
因此,以下内容将在不转换的情况下读取图像:
>>> im = cv2.imread('a.tif', -1)
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
请注意,OpenCV以相反的顺序返回R,G和B通道,因此im[:,:,0]
是B通道,im[:,:,1]
是G通道,im[:,:,2]
是R通道。
我还发现cv2.imwrite
可以写16位,三通道TIFF文件。
>>> cv2.imwrite('out.tif', im)
使用ImageMagick检查位深度:
$ identify -verbose out.tif
Format: TIFF (Tagged Image File Format)
Class: DirectClass
Geometry: 384x288+0+0
Resolution: 72x72
Print size: 5.33333x4
Units: PixelsPerInch
Type: TrueColor
Base type: TrueColor
Endianess: MSB
Colorspace: sRGB
Depth: 16-bit
Channel depth:
red: 16-bit
green: 16-bit
blue: 16-bit
....
答案 2 :(得分:10)
我找到了上述两种方法的另一种选择。
scikit-image包还可以使用tifffile.py
和FreeImage读取16位三通道TIFF文件,并将它们指定为要使用的插件。
虽然使用tifffile.py
进行阅读可能更简单地按照@Jaime所示的方式进行,但我想我会展示它是如何与scikit-image一起使用的,以防有人想要这样做方式。
对于使用Ubuntu的任何人,使用libfreeimage3
的{{1}}可以使用FreeImage。
如果使用apt
插件选项,则必须将tifffile.py复制到skimage / io / _plugins目录(在Ubuntu上为f.ex.,我的案例中的完整路径为tifffile.py
)。
/usr/local/lib/python2.7/dist-packages/skimage/io/_plugins/
编写TIFF文件:
>>> import skimage.io
>>> im = skimage.io.imread('a.tif', plugin='tifffile')
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
>>> im = skimage.io.imread('a.tif', plugin='freeimage')
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
使用ImageMagick检查>>> skimage.io.imsave('b.tif', im, plugin='tifffile')
>>> skimage.io.imsave('c.tif', im, plugin='freeimage')
和b.tif
的bitdepth显示两个图像中的每个通道都是16位。
答案 3 :(得分:4)
对我来说,之前的替代方案不起作用。我已成功使用gdal来读取1 GB的16位图像。
您可以使用以下内容打开图片:
from osgeo import gdal
import numpy as np
ds = gdal.Open("name.tif")
channel = np.array(ds.GetRasterBand(1).ReadAsArray())
您可以使用supported diver列表来编写数据。
答案 4 :(得分:0)
我建议使用与OpenImageIO的python绑定,这是处理vfx域(通常为16/32位)中各种图像格式的标准。
import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")
答案 5 :(得分:0)
试图使用Scikits-Image(skimage.io)读取具有JPEG压缩的多图像TIFF只是相当费力。我正在使用Windows 10发行版的Anaconda Python3; tifffile是通过Anaconda Navigator或“ conda install”安装的。
最后,用“ conda remove tifffile”卸载了“ tifffile”。接下来用“ pip install tifffile”重新安装“ tifffile”。这安装了最新的“ tifffile”插件-版本2020.5.5。接下来使用“ pip install imagecodecs”安装的图像编解码器。现在,以下代码可以工作了:
import skimage.io
img = skimage.io.imread('picture.tiff', plugin='tifffile')
请注意,只有在按照上述顺序完成“ tifffile”和“ imagecodes”的安装(并且首先删除了Anaconda“ tifffile”)后,此方法才有效。