首页 文章

Python和16位Tiff

提问于
浏览
13

如何在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

4 回答

  • 8

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

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

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

    版本:python 2.7.1 - numpy 1.6.1 - PIL 1.1.7

    这是我写的快速测试 . uint16 numpy array - >转换为字符串 - >转换为类型为'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')
    

    edit: 从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条存储的图像) .

  • 0

    您似乎偶然发现了PIL错误或未实现的角落案例 .

    这是一个解决方法:

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

    使用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')
    

相关问题