I have several 3D images of shape (32,32,32) and I want to create 2D images from them. I want to do that by getting each slice in the z-axis and putting each of them in a square array in order, something like this:
Because I want the 2D image to be square I need to fill the missing slices with zeros (Black in the example).
This is what I did:
# I created an array of the desired dimensions
grid = np.zeros((6*32,6*32))
# Then, I assigned to each section of the grid the values of every slice of the 3d_image:
grid[0:32, 0:32] = 3d_image[:,:,0]
grid[0:32, 32:64] = 3d_image[:,:,1]
grid[0:32, 64:96] = 3d_image[:,:,2]
grid[0:32, 96:128] = 3d_image[:,:,3]
grid[0:32, 128:160] = 3d_image[:,:,4]
grid[0:32, 160:192] = 3d_image[:,:,5]
grid[32:64, 0:32] = 3d_image[:,:,6]
grid[32:64, 32:64] = 3d_image[:,:,7]
grid[32:64, 64:96] = 3d_image[:,:,8]
grid[32:64, 96:128] = 3d_image[:,:,9]
grid[32:64, 128:160] = 3d_image[:,:,10]
grid[32:64, 160:192] = 3d_image[:,:,11]
grid[64:96, 0:32] = 3d_image[:,:,12]
grid[64:96, 32:64] = 3d_image[:,:,13]
...
grid[160:192, 160:192] = 3d_image[:,:,31]
And It worked!! But I want to automate it, so I tried this:
d = [0, 32, 64, 96, 128, 160]
for j in range(6):
for i in d:
grid[0:32, i:i 32] = 3d_image[:,:,j]
But it didn't work, the slice index for 3d_image (j) is not changing, and I don't know how to change the index range for grid after every 6th slice.
Could you help me?
CodePudding user response:
Here's an automated way to do it. Let's say your array with shape (32, 32, 32)
is called n
. Note that this method relies on all 3 dimensions having the same size.
num_layers = n.shape[0]
# num_across = how many images will go in 1 row or column in the final array.
num_across = int(np.ceil(np.sqrt(num_layers)))
# new_shape = how many numbers go in a row in the final array.
new_shape = num_across * num_layers
final_im = np.zeros((new_shape**2)).reshape(new_shape, new_shape)
for i in range(num_layers):
# Get what number row and column the image goes in (e.g. in the example,
# the image labelled 28 is in the 4th (3rd with 0-indexing) column and 5th
# (4th with 0-indexing) row.
col_num = i % num_across
row_num = i // num_across
# Put the image in the appropriate part of the final image.
final_im[row_num*num_layers:row_num*num_layers num_layers, col_num*num_layers:col_num*num_layers num_layers] = n[i]
final_im
now contains what you want. Below is a representation where each image is a different color and the "black" areas are purple because matplotlib colormaps are funny like that:
Anyway, you can tell that the images go where they're supposed to and you get your empty space along the bottom.
CodePudding user response:
Assuming that that img
is an array of the shape (32,32,32), this should work:
N = 32
a = np.vstack([img, np.zeros((4, N, N), dtype=img.dtype)])
grid = a.transpose(1, 0, 2).reshape(N, -1, 6*N).transpose(1, 0, 2).reshape(6*N, -1)