Эффективное изменение формы массива ndarray из 2D в 3D на основе элементов из 2D - PullRequest
2 голосов
/ 25 июня 2011

Я работаю с DICOM файлами, которые содержат данные изображения.Я использую pydicom для чтения метаданных из файла .DCM.Теперь данные о пикселях, извлеченные из файла .DCM, возвращаются в виде двумерного пустого символа.
Конкретные файлы DICOM, с которыми я работаю, сохраняют одно значение интенсивности на пиксель.После того, как я выполню некоторые манипуляции с ними, я получаю одно значение с плавающей запятой (от 0,0 до 1,0) на пиксель в двумерном массиве:

[

[0,98788927, 0,98788927, 0,98788927, ..., 0,88062284, 0,89532872, 0,87629758],
[0,98788927, 0,98788927, 0,98788927, ..., 0,8884083, 0,89446367, 0,87889273], * 1013, 0,887, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,987, 0,98788, 0,987, 0,98788, 0,987, 0,987, 0,98788, 0,987, 0,98788, 0,987, 0,98788, 0,987, 0,987, 0,98788, 0,987, 0,987, 0,987, 0,98788, 0,98788, 0,98788, 0,98788, 0,98788, 0,98788, 0,98788, 0,98788, 0,98788927., 0,89532872, 0,87629758],
, ...,
[0,97491349, 0,97491349, 0,97491349, ..., 0,74480969, 0,72318339, 0,73269896],
[0,97491349, 0,97491349, 0,97, 491, 0,97,99, 0,9957, 0,74480969, 0,74740484],
[0,97491349, 0,97491349, 0,97491349, ..., 0,74913495 0,75865052, 0,75086505],

]

Я хотел бы преобразоватьэто в трехмерный ndarray с numpy, заменяя каждый элемент последовательностью элементов [R, G, B], где R = G = B = значение интенсивности.

Функция ndarray.put () сглаживаетматрица, которая исключает этот метод.

Я также попробовал:

for x in range( len(a[0]) ):
  for y in range( len(a) ):
    a[x][y] = [ a[x][y], a[x][y], a[x][y] ]

но получить

ValueError: setting an array element with a sequence.   

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

Заранее благодарен за любую помощь.

1 Ответ

2 голосов
/ 25 июня 2011

Итак, вы хотите, конечно, массив формы m x n x r , где r - размер кортежа.

Один из способов сделать это, который мне кажется наиболее простым, состоит в том, чтобы: (i) явно создать массив трехмерной сетки, идентичный исходному двумерному массиву, за исключением добавления последнего измерения, r, который был добавлен, а затем; (ii) отобразите свои кортежи rgb на эту сетку.

>>> # first, generate some fake data:
>>> m, n = 5, 4            # rows & cols, represents dimensions of original image
>>> D = NP.random.randint(0, 10, m*n).reshape(m, n)
>>> D
    array([[8, 2, 2, 1],
           [7, 5, 0, 9],
           [2, 2, 9, 3],
           [5, 7, 3, 0],
           [5, 8, 1, 7]])

Теперь создайте массив Grid:

>>> G = NP.zeros((m, n, r), dtype='uint')

Думайте о G как о m x n прямоугольной сетке - такой же, как D - но с каждой из 20 ячеек, хранящих не целое число (как D), а кортеж rgb, поэтому:

>>> # placing the color pixel (209, 127, 87) at location 3,2:
>>> G[3,2] = (209, 124, 87)

Чтобы получить эту конструкцию, вы можете увидеть кортеж rgb с / в сетке G, посмотрев на три последовательных фрагмента G:

>>> G[:,:,0]      # red
>>> array([[  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0, 209,   0,   0],
           [  0,   0,   0,   0,   0]], dtype=uint8)

>>> G[:,:,1]    # green
>>> array([[  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0, 124,   0,   0],
           [  0,   0,   0,   0,   0]], dtype=uint8)

>>> G[:,:,2]   # blue
>>> array([[ 0,  0,  0,  0,  0],
           [ 0,  0,  0,  0,  0],
           [ 0,  0,  0,  0,  0],
           [ 0,  0, 87,  0,  0],
           [ 0,  0,  0,  0,  0]], dtype=uint8)

Теперь, чтобы фактически получить желаемый результат, нам просто нужно (i) создать сетку G, массив 3D NumPy, первые два измерения которого взяты из массива, хранящегося в вашем файле .DCM, и чье третье измерение равно три от длины кортежа rgb; затем (ii) отобразить кортежи rgb на эту сетку, G.

>>> # create the Grid
>>> G = NP.zeros((m, n, r), dtype='uint')
>>> # now from the container that holds your rgb tuples, create *three* m x n arrays, 
>>> # one for each item in your rgb tuples

>>> # now just map the r values (1st itm in each rgb tuple) to the 3D grid
>>> G[:,:,0] = r_vals
>>> G[:,:,1] = g_vals
>>> G[:,:,2] = b_vals

>>> G.shape
    (5, 4, 3)
...