1

I am trying to do a deep learning model using Keras and VGG16 algorithm on DICOM images. I used thhe following data generator to process my images:

``
 # tested on tf 2.1 
 from keras_preprocessing.image.dataframe_iterator import DataFrameIterator

 class DCMDataFrameIterator(DataFrameIterator):
     def __init__(self, *arg, **kwargs):
        self.white_list_formats = ('dcm')
        super(DCMDataFrameIterator, self).__init__(*arg, **kwargs)
        self.dataframe = kwargs['dataframe']
        self.x = self.dataframe[kwargs['x_col']]
        self.y = self.dataframe[kwargs['y_col']]
        self.color_mode = kwargs['color_mode']
        self.target_size = kwargs['target_size']

def _get_batches_of_transformed_samples(self, indices_array):
    # get batch of images
    batch_x = np.array([self.read_dcm_as_array(dcm_path, self.target_size, color_mode=self.color_mode)
                        for dcm_path in self.x.iloc[indices_array]])
    
    batch_y = np.array(self.y.iloc[indices_array].astype(np.uint8))  # astype because y was passed as str

    # transform images
    if self.image_data_generator is not None:
        for i, (x, y) in enumerate(zip(batch_x, batch_y)):
            transform_params = self.image_data_generator.get_random_transform(x.shape)
            batch_x[i] = self.image_data_generator.apply_transform(x, transform_params)
            # you can change y here as well, eg: in semantic segmentation you want to transform masks as well 
            # using the same image_data_generator transformations.

    return batch_x, batch_y

@staticmethod

def read_dcm_as_array(dcm_path, target_size=(256, 256), color_mode='rgb'):
    img = tf.io.read_file(dcm_path)
    img = tfio.image.decode_dicom_image(img, dtype=tf.uint16)  
    img = tf.image.resize(img, target_size)
    img = tf.image.grayscale_to_rgb(img, name=None) # convert image grayscale to rgb for model VG16
    #img = np.expand_dims(img, -1)
    return img
``

and: `` # you can use preprocessing_function instead of rescale in all generators # if you are using a pretrained network train_augmentation_parameters = dict( rescale=1.0/255.0, rotation_range=10, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest', brightness_range = [0.8, 1.2], validation_split = 0.2 )

 valid_augmentation_parameters = dict(
rescale=1.0/255.0,
validation_split = 0.2

)

test_augmentation_parameters = dict(
rescale=1.0/255.0

)

# training parameters
BATCH_SIZE = 32
CLASS_MODE = 'sparse'
COLOR_MODE = 'grayscale'
TARGET_SIZE = (300, 300)
EPOCHS = 10
SEED = 1337

train_consts = {
'seed': SEED,
'batch_size': BATCH_SIZE,
'class_mode': CLASS_MODE,
'color_mode': COLOR_MODE,
'target_size': TARGET_SIZE,  
'subset': 'training'

}

 valid_consts = {
'seed': SEED,
'batch_size': BATCH_SIZE,
'class_mode': CLASS_MODE,
'color_mode': COLOR_MODE,
'target_size': TARGET_SIZE, 
'subset': 'validation'

}

test_consts = {
'batch_size': 1,  # should be 1 in testing
'class_mode': CLASS_MODE,
'color_mode': COLOR_MODE,
'target_size': TARGET_SIZE,  # resize input images
'shuffle': False

} ``

and:

``
# Using the training phase generators 
 train_augmenter = ImageDataGenerator(**train_augmentation_parameters)
 valid_augmenter = ImageDataGenerator(**valid_augmentation_parameters)


 train_generator = DCMDataFrameIterator(dataframe=df_merged,
                         x_col='files',
                         y_col='class',
                         image_data_generator=train_augmenter,
                         **train_consts)

 valid_generator = DCMDataFrameIterator(dataframe=df_merged,
                         x_col='files',
                         y_col='class',
                         image_data_generator=valid_augmenter,
                         **valid_consts)
``

Result of last command:

``
 Found 7828 validated image filenames belonging to 4 classes.
 Found 1956 validated image filenames belonging to 4 classes.
``

After:

 ``
base_model = VGG16(weights='imagenet', include_top=False) 

n_class = 4 # 

# Freezer les couches du VGG16
for layer in base_model.layers: 
    layer.trainable = False

model = Sequential()
model.add(base_model) # Ajout du modèle VGG16
model.add(GlobalAveragePooling2D()) 
model.add(Dense(1024,activation='relu'))
model.add(Dropout(rate=0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(rate=0.2))
model.add(Dense(n_class, activation='softmax'))
``

I compile but but when I do .fit I have the following message:

ValueError: Input arrays must be multi-channel 2D images.

Could you help me ? Thank you in advance, Thibaut

I had a look on stackoverflow to try to find a solution !

jthibaut
  • 21
  • 2

0 Answers0