4
votes

So i have preprocessed some dicom images to feed a neural network, and in image augmentation step, the image data generator expects a 4d input while my data is 3d (200, 420, 420)

i tried reshaping the array and expanding dimensions, but in both cases i cannot plot the individual images in the array (expects image with shape 420, 420 and instead my new images have shape 420, 420, 1)

and here are my codes;

I have three functions to convert DICOM images into images with good contrast;

This one takes housefield units

def transform_to_hu(medical_image, image):
    intercept = medical_image.RescaleIntercept
    slope = medical_image.RescaleSlope
    hu_image = image * slope + intercept

    return hu_image

This one sets window image values;

def window_image(image, window_center, window_width):
    img_min = window_center - window_width // 2
    img_max = window_center + window_width // 2
    window_image = image.copy()
    window_image[window_image < img_min] = img_min
    window_image[window_image > img_max] = img_max

    return window_image

And this function loads the image:

def load_image(file_path):
    medical_image = dicom.read_file(file_path)
    image = medical_image.pixel_array

    hu_image = transform_to_hu(medical_image, image)
    brain_image = window_image(hu_image, 40, 80)
    return brain_image

Then i load my images:

files = sorted(glob.glob('F:\CT_Data_Classifier\*.dcm'))
images = np.array([load_image(path) for path in files])

images.shape returns (200, 512, 512) and everything is fine about the data, for example i can plot 100th image by plt.imshow(images[100]) and it plots an image

i then feed the data into image data generator

train_image_data = ImageDataGenerator(
    rescale=1./255,
    shear_range=0.,
    zoom_range=0.05,
    rotation_range=180,
    width_shift_range=0.05,
    height_shift_range=0.05,
    horizontal_flip=True,
    vertical_flip=True,
    fill_mode='constant',
    cval=0

but then, when i try to plot, with this code:

plt.figure(figsize=(12, 12))
for X_batch, y_batch in train_image_data.flow(trainX, trainY, batch_size=9):
    for i in range(0, 9):
        plt.subplot(330 + 1 + i)
        plt.imshow(X_batch[i])
    plt.show()
    break 

it returns

(ValueError: ('Input data in "NumpyArrayIterator" should have rank 4. You passed an array with shape', (162, 420, 420)))

i tried expand_dims and reshape to add an extra dimension at the end of the array to represent channels but then it returns

TypeError: Invalid shape (420, 420, 1) for image data

in the plt.imshow stage

im a doctor and not an experienced programmer, so i would really appreciate your help. cheers.

1
Please see my answer. One question: are you training on slices of the dicom? or do you want to train on volumetric data? the image data generator is meant for images, not volumes.jakub
Hello jakub, yes i am training on DICOM slices not on volumetric data. Do you know a good resource where i can learn how to train the model on volumetric data?Şiyar Bahadır
I made a framework on top of tensorflow/keras for training on volumetric data. github.com/neuronets/nobrainer But in general, i referred to blog posts and journal articles on doing this. Please try out the framework i linked to, as it is meant to help people who are not necessarily experienced programmers. And please feel free to submit an issue on the github repository if you run into problems or have questions.jakub
Wow you are great!!! thanks a lotŞiyar Bahadır

1 Answers

2
votes

You are correct in adding an extra dimension to represent channels. That part seems fine. The problem is with plotting. For that, you can use:

plt.matshow(x[..., 0]).

where x is the 3D array. The syntax x[..., 0] means take index 0 of the last dimension of array x. The ellipsis (...) is shorthand to fill in the dimensions. For a 3D array, the equivalent call would be x[:, :, 0].