Home > Net >  Slicing a 3D image to create a 2D image
Slicing a 3D image to create a 2D image

Time:04-16

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?

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

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)
  • Related