I'm working with DICOM files that contain image data. I am using pydicom to read the metadata from the .DCM file. Now, the pixel data that is extracted from the .DCM file is returned as a 2 dimensional numpy ndarray.
The particular DICOM files I am working with save a single intensity value per pixel. After I perform some manipulation on them I end up with a single floating point value (between 0.0 and 1.0) per pixel in a 2 dimensional ndarray:[
[ 0.98788927, 0.98788927 0.98788927, ..., 0.88062284 0.89532872 0.87629758],
[ 0.98788927, 0.98788927, 0.98788927, ..., 0.8884083, 0.89446367, 0.87889273], [ 0.98788927, 0.98788927, 0.98788927, ..., 0.89100346, 0.89532872, 0.87629758], ,..., [ 0.97491349, 0.97491349, 0.97491349, ..., 0.7448开发者_如何学Go0969, 0.72318339, 0.73269896], [ 0.97491349, 0.97491349, 0.97491349, ..., 0.74913495, 0.74480969, 0.74740484], [ 0.97491349, 0.97491349, 0.97491349, ..., 0.74913495 0.75865052, 0.75086505],]
I would like to transform this into a 3-D ndarray with numpy by replacing each element with a sequence of elements [R, G, B] where R=G=B=intensity value.
The ndarray.put() function flattens out the matrix which rules out that method.
I also tried:
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] ]
but get a
ValueError: setting an array element with a sequence.
Suggestions? I'm trying to keep data manipulation as light as possible because some of these images are huge, so I want to avoid a hack/manually copying all the data to a separate variable.
Thanks in advance for any help.
So what you want, of course, is an array of shape m x n x r, where r is the tuple size.
One way to do this, which seems to me the most straightforward, is to: (i) explicitly create a 3D grid array, identical to your original 2D arrayexcept for addition of the last dimension, r, which has been added, and then; (ii) map your rgb tuples onto this Grid.
>>> # 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]])
Now create the Grid array:
>>> G = NP.zeros((m, n, r), dtype='uint')
Think of G as an m x n rectangular grid--same as D--but with each of the 20 cells storing not an integer (like D) but an rgb tuple, so:
>>> # placing the color pixel (209, 127, 87) at location 3,2:
>>> G[3,2] = (209, 124, 87)
To grok this construction, you can see the rgb tuple w/in the Grid, G, by looking at three consecutive slices of 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)
Now to actually get the result you want, we just need to (i) create a grid, G, a 3D NumPy array, whose first two dimensions are taken from the array stored in your .DCM file, and whose third dimension is three, from the length of an rgb tuple; then (ii) map the rgb tuples onto that grid, 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)
精彩评论