Python:读写TIFF 16位、三通道、彩色图像

2024-05-16 04:20:21 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有一种方法可以在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。然后bog标准matplotlib.pyplot.imread读取PNG文件,没有任何问题。

我遇到的另一个问题是将任何numpy数组保存为16位PNG文件,到目前为止这也不是一个简单的问题。


Tags: 方法图像imageimportnumpypngasnp
3条回答

它的功能有限,特别是在写回磁盘的非RGB图像时,但是Christoph Gohlke's ^{} 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)

答案由@Jaime起作用。

同时,我还设法在OpenCV中使用^{}解决了这个问题。

默认情况下cv2.imreada.tif中的16位三通道图像转换为8位,如问题所示。

cv2.imread接受文件名(cv2.imread(filename[, flags]))后面的标志,该标志指定加载的图像cf的颜色类型。documentation

  1. >;0返回3通道彩色图像。这将导致转换为8位,如上图所示。
  2. 0返回灰度图像。也会导致转换为8位。
  3. <;0按原样返回图像。这将返回16位图像。

因此,下面将读取图像而不进行转换:

>>> 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
  ....

我找到了另外两种方法的替代品。

scikit-image包还可以使用tifffile.py和FreeImage读取16位、三通道的TIFF文件,并将它们指定为要使用的插件。

当阅读使用tifffile.py可能更简单地以@Jaime所示的方式进行时,我想我将展示如何与scikit图像一起使用,以防有人想以这种方式进行阅读。

对于任何使用Ubuntu的人,FreeImage都可以通过libfreeimage3使用apt获得。

如果使用tifffile.pyplugin选项,则必须将tifffile.py复制到skipage/io/\u plugins目录(在Ubuntu上,在我的例子中,完整路径是/usr/local/lib/python2.7/dist-packages/skimage/io/_plugins/)。

>>> 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)

正在写入TIFF文件:

>>> skimage.io.imsave('b.tif', im, plugin='tifffile')
>>> skimage.io.imsave('c.tif', im, plugin='freeimage')

使用ImageMagick检查b.tifc.tif的位深度表明两个图像中的每个通道都是16位的。

相关问题 更多 >