Source code for classes_cae

"""Classi per la data augmentation del progetto CAE"""


import keras
import numpy as np
from skimage.io import imread
from skimage.transform import resize
from sklearn.utils import shuffle


[docs]class MassesSequence(keras.utils.Sequence): """ Classe per fare data augmentation per CAE """ def __init__( # pylint: disable=R0913 self, images, masks, label_array, img_gen, batch_size=10, shape=(124, 124) ): """ :type images: np.array :param images: immagini :type masks: np.array :param masks: maschere :type label_array: np.array :param label_array: label di classificazione (benigno o maligno) :type batch_size: int :param batch_size: dimensione della batch :type img_en: ImageDatagenerator :param img_gen: istanza della classe ImageDatagenerator :type shape: tuple :type shape: dimensione delle immagini. Di default (124, 124) """ self.images, self.masks, self.label_array = images, masks, label_array self.shape = shape self.img_gen = img_gen self.batch_size = batch_size def __len__(self): """restituisce il rapporto tra la lunghezza del vettore delle immagini e la dimensione della batch """ return len(self.images) // self.batch_size
[docs] def on_epoch_end(self): """Mischia il dataset a fine epoca.""" self.images, self.masks, self.label_array = shuffle( self.images, self.masks, self.label_array )
[docs] def process(self, img, transform): """ Applica una trasformazione random all'immagine""" img = self.img_gen.apply_transform(img, transform) return img
def __getitem__(self, idx): """Organizza le immagini,maschere e classi in batch""" batch_images = self.images[idx * self.batch_size : (idx + 1) * self.batch_size] batch_masks = self.masks[idx * self.batch_size : (idx + 1) * self.batch_size] batch_label_array = self.label_array[ idx * self.batch_size : (idx + 1) * self.batch_size ] images_list = [] masks_list = [] classes_ = [] for image, mask, label in zip(batch_images, batch_masks, batch_label_array): transform = self.img_gen.get_random_transform(self.shape) images_list.append(self.process(image, transform)) masks_list.append(self.process(mask, transform) > 0.2) classes_.append(label) return np.asarray(images_list, np.float64), [ np.asarray(masks_list, np.float64), np.asarray(classes_, np.float), ]
[docs]class MassesSequenceRadiomics(keras.utils.Sequence): """ Classe per il data augmentation per CAE con feature radiomiche """ def __init__( # pylint: disable=R0913 self, images, masks, label_array, features, img_gen, batch_size=10, shape=(124, 124), ): """Inizializza la sequenza :type images: np.array :param images: immagini :type masks: np.array :param masks: maschere :type label_array: np.array :param label_array: label di classificazione (benigno o maligno) :type features: np.array :param features: feature ottenute con pyradiomics :type batch_size: int :param batch_size: dimensione della batch :type img_en: ImageDatagenerator :param img_gen: istanza della classe ImageDatagenerator :type shape: tuple :type shape: dimensione delle immagini. Di default (124, 124) """ self.images, self.masks, self.label_array, self.features = ( images, masks, label_array, features, ) self.shape = shape self.img_gen = img_gen self.batch_size = batch_size def __len__(self): """restituisce il rapporto tra la lunghezza del vettore delle immagini e la dimensione della batch """ return len(self.images) // self.batch_size
[docs] def on_epoch_end(self): """Mischia il dataset a fine epoca.""" self.images, self.masks, self.label_array, self.features = shuffle( self.images, self.masks, self.label_array, self.features )
[docs] def process(self, img, transform): """ Applica una trasformazione random all'immagine""" img = self.img_gen.apply_transform(img, transform) return img
def __getitem__(self, idx): """Organizza le immagini,maschere, classi e feature in batch""" batch_images = self.images[idx * self.batch_size : (idx + 1) * self.batch_size] batch_masks = self.masks[idx * self.batch_size : (idx + 1) * self.batch_size] batch_label_array = self.label_array[ idx * self.batch_size : (idx + 1) * self.batch_size ] batch_features = self.features[ idx * self.batch_size : (idx + 1) * self.batch_size ] images_list = [] masks_list = [] classes_ = [] features_ = [] for image, mask, label, feature in zip( batch_images, batch_masks, batch_label_array, batch_features ): transform = self.img_gen.get_random_transform(self.shape) images_list.append(self.process(image, transform)) masks_list.append(self.process(mask, transform) > 0.2) classes_.append(label) features_.append(feature) return [ np.asarray(images_list, np.float64), np.asarray(features_, np.float64), ], [ np.asarray(masks_list, np.float64), np.asarray(classes_, np.float), ]
[docs]class MassesSequenceRadiomicsBig(keras.utils.Sequence): # pylint: disable=R0902 """ Classe per data augmentation per CAE con grande dataset """ def __init__( # pylint: disable=R0913 self, images, masks, label_array, features, img_gen, batch_size=5, shape=(2048, 1536), shape_tensor=(2048, 1536, 1), ): """Inizializza la sequenza :type images: np.array :param images: path delle immagini :type masks: np.array :param masks: path delle maschere :type label_array: np.array :param label_array: label di classificazione (benigno o maligno) :type features: np.array :param features: feature ottenute con pyradiomics :type batch_size: int :param batch_size: dimensione della batch :type img_en: ImageDatagenerator :param img_gen: istanza della classe ImageDatagenerator :type shape: tuple :type shape: dimensione delle immagini. Di default (2048, 1536) :type shape_tensor: tuple :type shape_tensor: dimensione del tensore di reshape. Di default (2048,1536,1) """ self.images, self.masks, self.label_array, self.features = ( images, masks, label_array, features, ) self.shape = shape self.shape_tensor = shape_tensor self.img_gen = img_gen self.batch_size = batch_size def __len__(self): """restituisce il rapporto tra la lunghezza del vettore delle immagini e la dimensione della batch """ return len(self.images) // self.batch_size
[docs] def on_epoch_end(self): """Mischia il dataset a fine epoca.""" self.images, self.masks, self.label_array, self.features = shuffle( self.images, self.masks, self.label_array, self.features )
[docs] def process(self, img, transform): """ Applica una trasformazione random all'immagine""" img = self.img_gen.apply_transform(img, transform) return img
def __getitem__(self, idx): # pylint: disable=R0914 """Organizza le immagini,maschere, classi e feature in batch""" batch_images = self.images[idx * self.batch_size : (idx + 1) * self.batch_size] batch_masks = self.masks[idx * self.batch_size : (idx + 1) * self.batch_size] batch_label_array = self.label_array[ idx * self.batch_size : (idx + 1) * self.batch_size ] batch_features = self.features[ idx * self.batch_size : (idx + 1) * self.batch_size ] images_list = [] masks_list = [] classes_ = [] features_ = [] for image, mask, label, feature in zip( batch_images, batch_masks, batch_label_array, batch_features ): transform = self.img_gen.get_random_transform(self.shape) images_el = resize(imread(str(image)), self.shape_tensor) masks_el = resize(imread(str(mask)), self.shape_tensor) images_list.append(self.process(images_el, transform)) del images_el masks_list.append(self.process(masks_el, transform)) del masks_el classes_.append(label) features_.append(feature) return [np.array(images_list) / 255, np.asarray(features_, np.float64)], [ np.array(masks_list) / 255, np.asarray(classes_, np.float), ]
[docs]class ValidatorGenerator(keras.utils.Sequence): """Classe per generare i dati di validazione in batch per il dataset grande""" def __init__( # pylint: disable=R0913 self, images, masks, label_array, features, batch_size=5, shape=(1024, 768), shape_tensor=(1024, 768, 1), ): """Inizializza la sequenza :type images: np.array :param images: path delle immagini :type masks: np.array :param masks: path delle maschere :type label_array: np.array :param label_array: label di classificazione (benigno o maligno) :type features: np.array :param features: feature ottenute con pyradiomics :type batch_size: int :param batch_size: dimensione della batch :type shape: tuple :type shape: dimensione delle immagini. Di default (2048, 1536) :type shape_tensor: tuple :type shape_tensor: dimensione del tensore di reshape. Di default (2048,1536,1) """ self.images, self.masks, self.label_array, self.features = ( images, masks, label_array, features, ) self.shape = shape self.batch_size = batch_size self.shape_tensor = shape_tensor def __len__(self): """restituisce il rapporto tra la lunghezza del vettore delle immagini e la dimensione della batch """ return len(self.images) // self.batch_size def __getitem__(self, idx): # pylint: disable=R0914 """Organizza le immagini,maschere, classi e feature di validazione in batch""" batch_images = self.images[idx * self.batch_size : (idx + 1) * self.batch_size] batch_masks = self.masks[idx * self.batch_size : (idx + 1) * self.batch_size] batch_label_array = self.label_array[ idx * self.batch_size : (idx + 1) * self.batch_size ] batch_features = self.features[ idx * self.batch_size : (idx + 1) * self.batch_size ] images_list = [] masks_list = [] classes_ = [] features_ = [] for image, mask, label, feature in zip( batch_images, batch_masks, batch_label_array, batch_features ): images_el = resize(imread(str(image)), self.shape_tensor) masks_el = resize(imread(str(mask)), self.shape_tensor) images_list.append(images_el) del images_el masks_list.append(masks_el) del masks_el classes_.append(label) features_.append(feature) return [np.array(images_list) / 255, np.asarray(features_, np.float64)], [ np.array(masks_list) / 255, np.asarray(classes_, np.float), ]