Python:读写 TIFF 16 位、三通道、彩色图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18446804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python: Read and write TIFF 16 bit , three channel , colour images
提问by Lars Chr
Does anyone have a method for importing a 16 bit per channel, 3 channel TIFF image in Python?
有没有人有在 Python 中导入每通道 16 位、3 通道 TIFF 图像的方法?
I have yet to find a method which will preserve the 16 bit depth per channel when dealing with the TIFF format. I am hoping that some helpful soul will have a solution.
我还没有找到一种方法,可以在处理 TIFF 格式时保留每个通道的 16 位深度。我希望一些有用的灵魂会有一个解决方案。
Here is a list of what I have tried so far without success and the results:
以下是我迄今为止尝试过但没有成功的列表和结果:
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
So far the only solution I have found is to convert the image to PNG with ImageMagick. Then the bog standard matplotlib.pyplot.imread
reads the PNG file without any problems.
到目前为止,我找到的唯一解决方案是使用 ImageMagick 将图像转换为 PNG。然后沼泽标准matplotlib.pyplot.imread
读取 PNG 文件没有任何问题。
Another problem I have is saving any numpy arrays as 16 bit PNG files which so far has not been straightforward either.
我遇到的另一个问题是将任何 numpy 数组保存为 16 位 PNG 文件,到目前为止,这也不是很简单。
采纳答案by Jaime
It has limited functionality, especially when it comes to writing back to disk non RGB images, but Christoph Gohlke's tifffile
modulereads in 3 channel 16-bit TIFFs with no problems, I just tested it:
它的功能有限,尤其是在将非 RGB 图像写回磁盘时,但Christoph Gohlke 的tifffile
模块读取 3 通道 16 位 TIFF 没有问题,我只是对其进行了测试:
>>> import tifffile as tiff
>>> a = tiff.imread('Untitled-1.tif')
>>> a.shape
(100L, 100L, 3L)
>>> a.dtype
dtype('uint16')
And Photoshop reads without complaining what I get from doing:
Photoshop 阅读时不会抱怨我所做的事情:
>>> tiff.imsave('new.tiff', a)
回答by Lars Chr
The answer by @Jaimeworks.
@Jaime的回答有效。
In the mean time I managed to also solve the problem using cv2.imread
in OpenCV.
与此同时,我还设法解决了cv2.imread
在 OpenCV 中使用的问题。
By default cv2.imread
will convert a 16 bit, three channel image in a.tif
to 8 bit as shown in the question.
默认情况下cv2.imread
会将 16 位、三通道图像转换a.tif
为 8 位,如问题所示。
cv2.imread
accepts a flag after the filename ( cv2.imread(filename[, flags])
) which specifies the colour type of the loaded image cf. the documentation:
cv2.imread
在文件名 ( cv2.imread(filename[, flags])
)之后接受一个标志,它指定加载的图像 cf 的颜色类型。该文档:
- >0returns a 3 channel colour image. This results in conversion to 8 bit as shown above.
- 0returns a greyscale image. Also results in conversion to 8 bit.
- <0returns the image as is. Thiswill return a 16 bit image.
- >0返回 3 通道彩色图像。这会导致转换为 8 位,如上所示。
- 0返回灰度图像。也会导致转换为 8 位。
- <0按原样返回图像。这将返回一个 16 位图像。
So the following will read the image without conversion:
因此,以下将读取图像而无需转换:
>>> im = cv2.imread('a.tif', -1)
>>> im.dtype
dtype('uint16')
>>> im.shape
(288, 384, 3)
Note that OpenCV returns the R, G and B channels in reverse order so im[:,:,0]
is the B channel, im[:,:,1]
the G channel and im[:,:,2]
is the R channel.
请注意,OpenCV 以相反的顺序返回 R、G 和 B 通道,因此im[:,:,0]
B 通道、im[:,:,1]
G 通道和im[:,:,2]
R 通道也是如此。
I have also found that cv2.imwrite
can write 16 bit, three channel TIFF files.
我还发现cv2.imwrite
可以写入 16 位、三通道 TIFF 文件。
>>> cv2.imwrite('out.tif', im)
Checking the bit depth with ImageMagick:
使用 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
....
回答by Lars Chr
I found an additional alternative to the two methods above.
我找到了上述两种方法的另一种替代方法。
The scikit-imagepackage can also read 16 bit, three channel TIFF files using both tifffile.py
and FreeImage and specifying them as the plugin to be used.
所述scikit图像包也可读取16位,同时使用三个通道TIFF文件tifffile.py
中使用和FreeImage的并指定它们作为插件。
While reading using tifffile.py
is probably done more simply in the manner shown by @Jaime, I thought I would show how it is used along with scikit-image in case anyone wants to do it in this manner.
虽然阅读 usingtifffile.py
可能以@Jaime所示的方式更简单地完成,但我想我会展示它是如何与 scikit-image 一起使用的,以防有人想以这种方式进行。
For anyone using Ubuntu, FreeImage is available as libfreeimage3
using apt
.
对于任何使用 Ubuntu 的人来说,FreeImage 可以作为libfreeimage3
使用apt
.
If the tifffile.py
plugin option is used the tifffile.py must be copied to the skimage/io/_plugins directory (f.ex. on Ubuntu the full path in my case was /usr/local/lib/python2.7/dist-packages/skimage/io/_plugins/
).
如果使用tifffile.py
插件选项,则必须将 tifffile.py 复制到 skimage/io/_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)
Writing TIFF files:
写入 TIFF 文件:
>>> skimage.io.imsave('b.tif', im, plugin='tifffile')
>>> skimage.io.imsave('c.tif', im, plugin='freeimage')
Checking the bitdepth of both b.tif
and c.tif
using ImageMagick shows that each channel in both images are 16 bit.
检查两者的位深度b.tif
并c.tif
使用 ImageMagick 显示两个图像中的每个通道都是 16 位。
回答by G M
For me the previous alternatives did not work. I have used gdalsuccessfully for reading a 16bit images of 1 GB.
对我来说,以前的替代方法不起作用。我已成功使用gdal读取 1 GB 的 16 位图像。
You can open an image with something like this:
您可以使用以下内容打开图像:
from osgeo import gdal
import numpy as np
ds = gdal.Open("name.tif")
channel = np.array(ds.GetRasterBand(1).ReadAsArray())
There is a list of supported diverthat you can use to write the data.
有一个可用于写入数据的受支持 diver的列表。
回答by zeno
I recommend using the python bindings to OpenImageIO, it's the standard for dealing with various image formats in the vfx domain (which usually are 16/32bit).
我建议使用 python 绑定到 OpenImageIO,它是处理 vfx 域中各种图像格式(通常是 16/32 位)的标准。
import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")
回答by barnwaldo
Just struggled considerably trying to read a multi-image TIFF with JPEG compression using Scikits-Image (skimage.io). Am using a Windows 10 distribution of Anaconda Python3; tifffile was installed through Anaconda Navigator or 'conda install'.
只是在尝试使用 Scikits-Image (skimage.io) 读取带有 JPEG 压缩的多图像 TIFF 时非常挣扎。正在使用 Anaconda Python3 的 Windows 10 发行版;tifffile 是通过 Anaconda Navigator 或“conda install”安装的。
Finally, uninstalled 'tifffile' with 'conda remove tifffile'. Next re-installed 'tifffile' with 'pip install tifffile'. This installed the latest 'tifffile' plugin - version 2020.5.5. Next installed image codecs with 'pip install imagecodecs'. And now the following code works:
最后,使用“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')
Note this only works if the install of 'tifffile' and 'imagecodes' was done in the order outlined above (and the Anaconda 'tifffile' is first removed).
请注意,这仅在按上述顺序安装“tifffile”和“imagecodes”时才有效(并且首先删除了 Anaconda 的“tifffile”)。