Skip to content
Advertisement

Slicing a 3D image to create a 2D image

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:

enter image description here

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?

Advertisement

Answer

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: Picture

Anyway, you can tell that the images go where they’re supposed to and you get your empty space along the bottom.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement