Преобразование float32 в бит-эквивалентный int32 - PullRequest
0 голосов
/ 27 ноября 2018

Модуль Pillow в Python настаивает на открытии 32-битного / пиксельного файла TIFF, который у меня есть, как если бы пиксели были типа float32, тогда как я считаю, что правильная интерпретация - это unsigned int32.Если я иду вперед и загружаю данные в массив 640x512 типа float32, как я могу перепечатать его как uint32, сохраняя при этом базовое двоичное представление?

В Fortran и C легко иметь указатели или структуры данныхдругой тип, указывающий на один и тот же блок физической памяти, так что необработанное содержимое памяти может быть легко интерпретировано в соответствии с любым типом, который я хочу.Существует ли в Python эквивалентная процедура?

Пример следует (обратите внимание, что у меня нет информации о сжатии и т. Д .; рассматриваемый файл был извлечен коммерческой программой из проприетарного формата файла):

from PIL import Image

infile = "20181016_071207_367_R.tif"        
im = Image.open(infile)

data = np.array(im.getdata())
print(data)

[-9,99117374 -10,36103535 -9,80686869 ... -18,41988373 -18,35027885 -18,69905663]

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Ответ, в этом случае, заключается в том, что Подушка загружает изображение с правильным типом (с плавающей точкой 32), как указано в изображении, экспортированном из тепловой камеры.Нет необходимости приводить изображение к целому числу, и это приведет к неверному результату.

0 голосов
/ 27 ноября 2018

Если у вас im.mode, изначально равный F, вы можете заставить Pillow перезагружать одни и те же данные в другом режиме (действительно, очень необычное желание) таким хакерским способом:

imnew = im.convert(mode='I')
imnew.frombytes(im.tobytes())

В более общем смысле (вне контекста PIL), всякий раз, когда вы сталкиваетесь с необходимостью иметь дело с необработанным представлением памяти в Python, вы обычно должны полагаться на numpy или встроенный в Python класс memoryview с struct module.

Вот пример повторной интерпретации массива numpy float32 как int32:

a = np.array([1.0, 2.0, 3.0], dtype='float32')
a_as_int32 = a.view('int32')

Вот пример того же действия с использованием memoryview:

# Create a memory buffer
b = bytearray(4*3)

# Write three floats
struct.pack_into('fff', b, 0, *[1.0, 2.0, 3.0])

# View the same memory as three ints
mem_as_ints = memoryview(b).cast('I')
...