Python и 16-битный Tiff - PullRequest
       42

Python и 16-битный Tiff

13 голосов
/ 30 августа 2011

Как я могу преобразовать и сохранить 16-битный одноканальный TIF в Python?

Я могу без проблем загрузить 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 голосов
/ 27 января 2012

Наткнулся на этот поток, пытаясь сохранить 16-битные изображения TIFF с помощью PIL / numpy.

Версии: python 2.7.1 - numpy 1.6.1 - PIL 1.1.7

Вот быстрыйтест я написал.uint16 массив numpy -> преобразованный в строку -> преобразованный в изображение PIL типа 'I; 16' -> сохраненный как 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).

7 голосов
/ 31 августа 2011

Для преобразования без потерь из 16-битного оттенка серого TIFF в PNG используйте PythonMagick :

from PythonMagick import Image
Image('pinei_2002300_1525_modis_ch02.tif').write("foo.png")
5 голосов
/ 30 августа 2011

Похоже, вы наткнулись на ошибку PIL или угловой случай, который не был реализован.

Вот обходной путь:

i16.mode = 'I'
i16.point(lambda i:i*(1./256)).convert('L').save('foo.png')
0 голосов
/ 18 апреля 2017

Преобразование TIFF ImageJ в JPEG с PIL 4.1 +

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