2015-07-07 3 views
1

У меня есть данные трехмерного изображения и вы хотите собрать стопку изображений RGB из одноканальных стеков, т. Е. Я попытаюсь объединить три массива формы (358, 1379, 1042) в один массив формы (358, 1379, 1042, 3). Вдохновленный skimage.color.gray2rgb Я попыталсяОбъединить большие массивы numpy в оперативной памяти

np.concatenate((
    stack1[..., np.newaxis], 
    stack2[..., np.newaxis], 
    stack3[..., np.newaxis]), axis=-1) 

Однако, даже если каждый из этих стеков только 1GiB это наполняет мою пустую ~ 12GiB RAM сразу ... Так что я пытался предварительно выделить массив конечной формы, а затем заполните его стеками, например

rgb_stack = np.zeros(stack1.shape + (3,)) 
rgb_stack[:,:,:,0] = stack1 

, который также исчерпал мою оперативную память, как только я выполнил вторую строку. В конце концов я попытался явно скопировать данные из stack1 в rgb_stack по

rgb_stack = np.zeros(stack1.shape + (3,)) 
rgb_stack[:,:,:,0] = stack1.copy() 

с тем же результатом. Что я делаю не так?

+1

Если вы не указали dtype, 'zeros' предположим, что вы хотите float64, а' '(358, 1379, 1042, 3)' float64 array будет занимать ~ 11.5 GiB. Какой тип данных является вашим входным массивом? –

+0

То, что 11.5GiB о том, что 'wh'' говорит мне, - но в ОЗУ это, кажется, намного меньше? В любом случае входные массивы являются 'dtype ('uint16')', и я также могу перейти на 8 бит. – qiv

+1

Некоторые операционные системы (в частности, Linux) с радостью перекомпилируют память. Когда вы создаете свой массив нулей, ядро ​​не сразу выделяет размер RAM с соответствующим размером - это происходит только тогда, когда вы на самом деле пытаетесь записать эти адреса памяти, поэтому вы видите только «MemoryError», когда пытаетесь назначить на 'rgb_stack'. –

ответ

0

Завершить, что можно узнать из комментариев к вопросу; np.zeros создает массив из float64, который почти 12GiB большой. Это само по себе не заполняет оперативную память, поскольку Linux перехватывает и только откладывает соответствующее ОЗУ, как только массив заполняется, что в этом случае после заполнения данных изображения.

Таким образом, создавая zeros как еще один dtype, решает проблему, например.

rgb_stack = np.zeros(stack1.shape + (3,), dtype=np.uint16) 
rgb_stack[:,:,:,0] = stack1.copy() 

отлично работает с uint16 штабелями.