Чтение данных из 16-битного беззнакового файла необработанного изображения с прямым порядком байтов в Python

У меня есть несколько изображений, которые я хочу проанализировать с помощью скрипта Python. Они хранятся в виде файлов с исходными двоичными данными. Они имеют следующий формат. 16-битное беззнаковое, с прямым порядком байтов, 592x600 пикселей с 520-байтовым заголовком.

Когда я смотрю на файл .dat в своей ОС (OS X yosemite), я вижу, что размер файла составляет 710 920 байт.

Это имеет смысл как (592 x 600 пикселей) * (2 байта на пиксель) = 710 400 байтов. Таким образом, остаток составляет 520-байтовый заголовок.

Я хочу написать быстрый скрипт на Python для генерации массива значений пикселей. то есть я хочу убрать заголовок файла и сохранить остальные данные в виде массива, чтобы я мог использовать что-то вроде PIL, чтобы затем быстро преобразовать в изображение и вывести jpg или png.

Просто делаю что-то очень быстрое:

myfile = open('test.dat', 'rb') 

data = myfile.read()

len(data)

trimdata = data[520:]

len(trimdata)

Это дает мне необработанные данные без заголовка.

Отсюда я не уверен, как проще всего разобрать данные в массив 592x600, который затем можно использовать с PIL для быстрого экспорта изображения в градациях серого.

вот ссылка на файл, который помогает: test.dat

Изменить: спасибо за помощь - похоже, данные были Little Endian, а не Big Endian. Ваше здоровье.


person Maxwell Grady    schedule 24.10.2014    source источник
comment
Вы можете использовать struct docs.python.org/3.4/library/ struct.html # struct-format-strings   -  person Michele d'Amico    schedule 24.10.2014
comment
Вам просто интересно, как преобразовать изображения или как это сделать на Python?   -  person Michele d'Amico    schedule 24.10.2014
comment
Мне особенно интересно узнать, как это сделать на Python. Я много занимаюсь анализом изображений и вычислениями с помощью Python с похожими данными, но это первый раз, когда я собрал набор данных в необработанном формате. Замечательно иметь возможность быстро обрабатывать их с помощью imagemagick, чтобы выплевывать png или jpgs, но в конце я хотел бы получить данные в python в виде массива значений пикселей, чтобы затем я мог выполнить некоторые вычисления с данными . Спасибо за советы по использованию struct - я займусь этим сегодня вечером!   -  person Maxwell Grady    schedule 24.10.2014
comment
Исходная ссылка на тестовые данные не работает. Образец того, как выглядели эти данные, помог бы повысить ценность этого вопроса.   -  person showdev    schedule 25.01.2020


Ответы (2)


PIL должен иметь возможность читать эти данные напрямую, но черт возьми, смогу ли я понять, как это сделать. Однако для косвенного выполнения этого не требуется слишком много шагов.

fmt = '>' + str(592*600) + 'H'
pix = struct.unpack(fmt, trimdata)
scaled_pix = ''.join(chr(p/256) for p in pix)
im = Image.fromstring('L', (592,600), scaled_pix, 'raw')

Изменить. Похоже, в вашем образце изображения обратный порядок байтов, а не прямой порядок байтов. Вот исправленный код. Я также добавил автоматическое масштабирование яркости и гамма-коррекцию, поскольку полная 16-битная шкала не использовалась.

fmt = '<' + str(592*600) + 'H'
pix = struct.unpack(fmt, trimdata)
lightest = max(pix)
scaled = ''.join(chr(int((float(p) / lightest)**(1/2.2) * 255)) for p in pix)
im = Image.fromstring('L', (592,600), scaled, 'raw')

введите описание изображения здесь

person Mark Ransom    schedule 24.10.2014
comment
Спасибо за советы! Я займусь этим сегодня вечером, когда буду работать над анализом данных. Выглядит довольно просто - person Maxwell Grady; 24.10.2014
comment
Спасибо! Я просто предположил, что данные были с прямым порядком байтов, основываясь на машине, которая их сгенерировала, а также на том факте, что imageJ, похоже, получил изображение почти правильным, сказав попробовать импортировать как необработанный прямой порядок байтов ... Я должен проверить оба варианта. Спасибо за помощь! - person Maxwell Grady; 25.10.2014

Вы можете преобразовать их в быстрые файлы JPEG, вообще не написав Python, используя ImageMagick convert из командной строки.

Просто сообщите ImageMagick размер, битовую глубину и смещение данных, и он может создать для вас JPEG в оттенках серого или 16-битный TIFF.

Что-то вроде этого, но у меня нет Mac для тестирования:

convert -size 592x600+520 -depth 16 GRAY:image.dat output.jpg

Вам также может понадобиться -endian MSB (или LSB) перед первым именем файла.

Я вернулся к своему Mac, и команда для создания этого изображения:

convert -size 592x600+520 -depth 16 -endian MSB GRAY:image.dat -auto-level output.jpg

введите описание изображения здесь

person Mark Setchell    schedule 24.10.2014
comment
У меня была та же проблема с ImageJ, поскольку imagemagick, похоже, имеет место, где данные, похоже, имеют некоторые странные пятна (верхний правый corer на приведенном выше изображении). Я действительно смог получить исходное программное обеспечение для вывода необработанных данных вместе с png, поэтому я знаю, что данные не повреждены, так как теперь у меня есть набор png, которые выглядят правильно. Но после сегодняшнего дня у меня больше нет доступа к исходному программному обеспечению, поэтому я хотел найти способ получить необработанные данные для правильного отображения с помощью другого программного пакета. - person Maxwell Grady; 24.10.2014
comment
Это похоже на самое яркое пятно изображения - возможно, это MSB, который рассматривается как знаковый бит ... - person Mark Setchell; 24.10.2014
comment
@MaxwellGrady моя техника показывает идентичное изображение. Я мог бы попробовать пару экспериментов. - person Mark Ransom; 24.10.2014