2010-01-21 2 views
12

Я пытаюсь создать очень большое изображение (25000x25000), вставив вместе много меньших изображений. При вызове Image.new() с такими большими размерами, python исчерпывает память, и я получаю MemoryError.Создание очень больших изображений с использованием библиотеки изображений Python

Есть ли способ выписать изображение, подобное этому, без того, чтобы все оставалось в ОЗУ?

EDIT: Использование команды ImageMagick montage, возможно создание изображений с произвольным размером. Похоже, что он не пытается загрузить окончательное изображение в ОЗУ (он использует очень мало памяти во время процесса), а скорее передает его на диск, что идеально.

+0

Должны ли изображения быть в режиме RGB? –

+0

Да, это цветные изображения. Также 25000x25000 на самом деле всего лишь небольшая часть полного изображения, которое, вероятно, будет 175 000x325 000. Даже если изображения были в оттенках серого, я угадываю изображение, размер которого все равно не поместится в ОЗУ. – meatvest

+0

Обычно это помогает в ответе на такие вопросы, чтобы узнать, как будет использоваться выход. Какая программа/система будет потреблять эти данные (и/или для каких целей)? Ответ на это может указать путь. –

ответ

0

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

2

Не слишком удивляет, что у вас заканчивается память; это изображение займет более 2 гигабайт в памяти, и в зависимости от системы, в которой вы используете ОС, возможно, не сможет выделить достаточную виртуальную память для запуска python, независимо от вашей фактической ОЗУ.

Вам обязательно нужно будет записать его поэтапно. Если вы используете необработанный формат, вы, вероятно, можете сделать это для каждой строки изображений, если они имеют одинаковые размеры. Затем вы можете объединить файлы, иначе вам нужно быть более осторожными с тем, как вы кодируете данные.

0

mayby ​​Вы можете опробовать привязки python OIIO, которые были созданы одним из студентов GSoC? OpenImageIO сами может читать большие изображения, используя небольшую память - но я не использовал его самого

OIIO: http://openimageio.org Как использовать питон привязки: http://openimageio.org/wiki/index.php?title=Python_bindings

Существует также небольшой сценарий под названием «isticher», то есть делая то, что вы хотите (по крайней мере, я так думаю)

-1

Используйте numpy.memmap и модуль png.

3

Вы можете попробовать использовать библиотеку GDAL. Он предоставляет привязки к Python. Здесь объединены tutorial, представляющие способы чтения и записи изображений с использованием API C++, C и Python. В зависимости от используемых GDAL операций и функций GDAL может обрабатывать очень большие изображения и обрабатывать изображения, которые слишком велики для хранения в ОЗУ.

2

Это всего лишь вопрос понимания формата двоичного файла. Сжатые форматы будут сложнее.

Предполагая, что вы хотите растровый/DIB, этот код:

#incremental_write_bmp.py 
import binascii 

data=''' 
0h -2 -42 4D -"BM" -Magic Number (unsigned integer 66, 77) 
2h -4 -46 00 00 00 -70 Bytes -Size of the BMP file 
6h -2 -00 00 -Unused -Application Specific 
8h -2 -00 00 -Unused -Application Specific 
Ah -4 -36 00 00 00 -54 bytes -The offset where the bitmap data (pixels) can be found. 
Eh -4 -28 00 00 00 -40 bytes -The number of bytes in the header (from this point). 
12h -4 -02 00 00 00 -2 pixels -The width of the bitmap in pixels 
16h -4 -02 00 00 00 -2 pixels -The height of the bitmap in pixels 
1Ah -2 -01 00 -1 plane -Number of color planes being used. 
1Ch -2 -18 00 -24 bits -The number of bits/pixel. 
1Eh -4 -00 00 00 00 -0 -BI_RGB, No compression used 
22h -4 -10 00 00 00 -16 bytes -The size of the raw BMP data (after this header) 
26h -4 -13 0B 00 00 -2,835 pixels/meter -The horizontal resolution of the image 
2Ah -4 -13 0B 00 00 -2,835 pixels/meter -The vertical resolution of the image 
2Eh -4 -00 00 00 00 -0 colors -Number of colors in the palette 
32h -4 -00 00 00 00 -0 important colors -Means all colors are important 
36h -3 -00 00 FF -0 0 255 -Red, Pixel (1,0) 
39h -3 -FF FF FF -255 255 255 -White, Pixel (1,1) 
3Ch -2 -00 00 -0 0 -Padding for 4 byte alignment (Could be a value other than zero) 
3Eh -3 -FF 00 00 -255 0 0 -Blue, Pixel (0,0) 
41h -3 -00 FF 00 -0 255 0 -Green, Pixel (0,1) 
44h -2 -00 00 -0 0 -Padding for 4 byte alignment (Could be a value other than zero) 
'''.strip().split('\n') 

open('test.bmp','wb') 
for l in data: 
    b = l.split('-')[2].strip() 
    d = ''.join(b.split()) 
    x = binascii.a2b_hex(d) 
    # this re-opens the file and appends each iteration 
    open('test.bmp','ab').write(x) 

... будет пошагово написать пример 2х2 растровый найден here. Теперь речь идет только о настройке заголовков на размер, который вы хотите, и чтение (а иногда и повторное чтение) ваших фрагментов в правильном порядке. Я попробовал его с очень большим файлом и не видел всплеск памяти python. Я предполагаю, что ОС может присоединяться к файлу, не читая всего этого.

Смежные вопросы