Python 和 16 位 Tiff

发布于 2024-12-02 04:20:44 字数 791 浏览 1 评论 0原文

如何在 Python 中转换并保存 16 位单通道 TIF?

我可以毫无问题地加载 16 位和 32 位图像,并看到 32 位图像是模式 F,16 位图像是模式 I;16S

import Image
i32 = Image.open('32.tif')
i16 = Image.open('16.tif')
i32
# <TiffImagePlugin.TiffImageFile image mode=F size=2000x1600 at 0x1098E5518>
i16
# <TiffImagePlugin.TiffImageFile image mode=I;16S size=2000x1600 at 0x1098B6DD0>

但是我我在处理 16 位图像时遇到问题。如果我想保存为 PNG,我不能直接这样做:

i32.save('foo.png')
# IOError: cannot write mode F as PNG
i16.save('foo.png')
# ValueError: unrecognized mode

如果我转换 32 位图像,我可以保存它:

i32.convert('L').save('foo.png')

但相同的命令不适用于 16 位图像:

i16.convert('L').save('foo.png')
# ValueError: unrecognized mode

How can I convert and save a 16 bit single-channel TIF in Python?

I can load a 16 and 32 bit image without an issue, and see that the 32 bit image is mode F and the 16 bit image is mode I;16S:

import Image
i32 = Image.open('32.tif')
i16 = Image.open('16.tif')
i32
# <TiffImagePlugin.TiffImageFile image mode=F size=2000x1600 at 0x1098E5518>
i16
# <TiffImagePlugin.TiffImageFile image mode=I;16S size=2000x1600 at 0x1098B6DD0>

But I am having trouble working with the 16 bit image. If I want to save either as PNG, I cannot do so directly:

i32.save('foo.png')
# IOError: cannot write mode F as PNG
i16.save('foo.png')
# ValueError: unrecognized mode

If I convert the 32 bit image, I can save it:

i32.convert('L').save('foo.png')

But the same command will not work with the 16 bit image:

i16.convert('L').save('foo.png')
# ValueError: unrecognized mode

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

时光倒影 2024-12-09 04:20:44

对于从 16 位灰度 TIFF 到 PNG 的无损转换,请使用 PythonMagick

from PythonMagick import Image
Image('pinei_2002300_1525_modis_ch02.tif').write("foo.png")

For lossless conversion from 16 bit grayscale TIFF to PNG use PythonMagick:

from PythonMagick import Image
Image('pinei_2002300_1525_modis_ch02.tif').write("foo.png")
蔚蓝源自深海 2024-12-09 04:20:44

您似乎无意中遇到了 PIL 错误或未实现的极端情况。

这是一个解决方法:

i16.mode = 'I'
i16.point(lambda i:i*(1./256)).convert('L').save('foo.png')

You appear to have stumbled into a PIL bug, or a corner case that was unimplemented.

Here's a workaround:

i16.mode = 'I'
i16.point(lambda i:i*(1./256)).convert('L').save('foo.png')
战皆罪 2024-12-09 04:20:44

偶然发现这个线程试图用 PIL / numpy 保存 16 位 TIFF 图像。

版本:python 2.7.1 - numpy 1.6.1 - PIL 1.1.7

这是我编写的快速测试。 uint16 numpy 数组 ->转换为字符串 ->转换为“I;16”类型的 PIL 图像 ->保存为 16 位 TIFF。

在 ImageJ 中打开图像显示正确的水平渐变图案,图像类型为“每像素位数:16(无符号)”

import Image
import numpy

data = numpy.zeros((1024,1024),numpy.uint16)

h,w = data.shape

for i in range(h):
    data[i,:] = numpy.arange(w)

im = Image.fromstring('I;16',(w,h),data.tostring())
im.save('test_16bit.tif')

编辑:从 1.1.7 开始,PIL 不支持写入压缩文件,但pylibtiff 可以(lzw 压缩)。测试代码因此变为(使用 pylibtiff 0.3 测试):

import Image
import numpy
from libtiff import TIFFimage

data = numpy.zeros((1024,1024),numpy.uint16)

h,w = data.shape

for i in range(w):
    data[:,i] = numpy.arange(h)

tiff = TIFFimage(data, description='')
tiff.write_file('test_16bit.tif', compression='lzw')
#flush the file to disk:
del tiff

请注意:测试代码更改为生成垂直渐变,否则无法实现压缩(请参阅警告:pylibtiff 目前支持读取和写入使用 TIFF 条带存储的图像)。

Stumbled on this thread trying to save 16 bit TIFF images with PIL / numpy.

Versions: python 2.7.1 - numpy 1.6.1 - PIL 1.1.7

Here's a quick test I wrote. uint16 numpy array -> converted to string -> converted to a PIL image of type 'I;16' -> saved as a 16 bit TIFF.

Opening the image in ImageJ shows the right horizontal gradient pattern and the image type is 'Bits per pixel: 16 (unsigned)'

import Image
import numpy

data = numpy.zeros((1024,1024),numpy.uint16)

h,w = data.shape

for i in range(h):
    data[i,:] = numpy.arange(w)

im = Image.fromstring('I;16',(w,h),data.tostring())
im.save('test_16bit.tif')

edit: As of 1.1.7, PIL does not support writing compressed files, but pylibtiff does (lzw compression). The test code thus becomes (tested with pylibtiff 0.3):

import Image
import numpy
from libtiff import TIFFimage

data = numpy.zeros((1024,1024),numpy.uint16)

h,w = data.shape

for i in range(w):
    data[:,i] = numpy.arange(h)

tiff = TIFFimage(data, description='')
tiff.write_file('test_16bit.tif', compression='lzw')
#flush the file to disk:
del tiff

Please note: test code changed to generate a vertical gradient otherwise, no compression achieved (refer to warning: pylibtiff currently supports reading and writing images that are stored using TIFF strips).

鹤仙姿 2024-12-09 04:20:44

使用 PIL 4.1+ 将 ImageJ TIFF 转换为 JPEG

im = numpy.array(Image.open('my.tiff'))
image = Image.fromarray(im / numpy.amax(im) * 255)
image.save('my.jpg')

Convert an ImageJ TIFF to a JPEG with PIL 4.1+

im = numpy.array(Image.open('my.tiff'))
image = Image.fromarray(im / numpy.amax(im) * 255)
image.save('my.jpg')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文