The following method does exactly that, taking multiple horizontal slices and putting them in a 2D matrix
def slices_matrix_2D(img):
''' Transform a 3D MRI image into a 2D image, by obtaining 9 slices
and placing them in a 4x4 two-dimensional grid.
All 16 cuts are from a horizontal/axial view. They are selected
from the 30th to the 60th level of the original 3D image.
Parameters:
img -- np.ndarray with the 3D image
Returns:
np.ndarray -- The resulting 2D image
'''
# create the final 2D image
image_2D = np.empty(IMG_2D_SHAPE)
# set the limits and the step
TOP = 60
BOTTOM = 30
STEP = 2
N_CUTS = 16
# iterator for the cuts
cut_it = TOP
# iterator for the rows of the 2D final image
row_it = 0
# iterator for the columns of the 2D final image
col_it = 0
for cutting_time in range(N_CUTS):
# cut
cut = img[cut_it, :, :]
cut_it -= STEP
# reset the row iterator and move the
# col iterator when needed
if cutting_time in [4, 8, 12]:
row_it = 0
col_it += cut.shape[1]
# copy the cut to the 2D image
for i in range(cut.shape[0]):
for j in range(cut.shape[1]):
image_2D[i + row_it, j + col_it] = cut[i, j]
row_it += cut.shape[0]
# return the final 2D image, with 3 channels
# this is necessary for working with most pre-trained nets
return np.repeat(image_2D[None, ...], 3, axis=0).T
#return image_2D
**The following method uses the previous 2D transformation to load the 3D images from disk and transforms them. Also returns the image label. **
def load_image_2D(abs_path, labels):
''' Load an image (.nii) and its label, from its absolute path.
Transform it into a 2D image, by obtaining 16 slices and placing them
in a 4x4 two-dimensional grid.
Parameters:
abs_path -- Absolute path, filename included
labels -- Label mapper
Returns:
img -- The .nii image, converted into a numpy array
label -- The label of the image (from argument 'labels')
'''
# obtain the label from the path (it is the last directory name)
label = labels[abs_path.split('/')[-2]]
# load the image with SimpleITK
sitk_image = sitk.ReadImage(abs_path)
# transform into a numpy array
img = sitk.GetArrayFromImage(sitk_image)
# apply whitening
img = preprocessing.whitening(img)
# make the 2D image
img = slices_matrix_2D(img)
return img, label
Define the complete filename for each one of the .tfrecords.
train_tfrec2D = os.path.join(DB_TF_2D_PATH, TFREC_2D_SS_TRAIN)
test_tfrec2D = os.path.join(DB_TF_2D_PATH, TFREC_2D_SS_TEST)
val_tfrec2D = os.path.join(DB_TF_2D_PATH, TFREC_2D_SS_VAL)
Design the method for creating a .tfrecords, given the all the images filenames, the name of the file and the label mapper (always the LABELS constant). It uses the previous two methods for loading the images
def create_tf_record_2D(img_filenames, tf_rec_filename, labels):
''' Create a TFRecord file, including the information
of the specified images, after converting them into
a 2D grid.
Parameters:
img_filenames -- Array with the path to every
image that is going to be included
in the TFRecords file.
tf_rec_filename -- Name of the TFRecords file.
labels -- Label mapper
'''
# open the file
writer = tf.python_io.TFRecordWriter(tf_rec_filename)
# iterate through all .nii files
for meta_data in img_filenames:
# load the image and label
img, label = load_image_2D(meta_data, labels)
# create a feature
feature = {'label': _int64_feature(label),
'image': _float_feature(img.ravel())}
# create an example protocol buffer
example = tf.train.Example(features=tf.train.Features(feature=feature))
# serialize to string and write on the file
writer.write(example.SerializeToString())
writer.close()
Finally, create the .tfrecords.
create_tf_record_2D(training_set, train_tfrec2D, LABELS)
create_tf_record_2D(test_set, test_tfrec2D, LABELS)
create_tf_record_2D(validation_set, val_tfrec2D, LABELS)