Exemplo n.º 1
0
    def setUp(self):
        """Set up test fixtures, if any."""
        self.dir = Path(tempfile.gettempdir()) / '.torchio_tests'
        self.dir.mkdir(exist_ok=True)
        random.seed(42)
        np.random.seed(42)

        subject_a = Subject(
            Image('t1', self.get_image_path('t1_a'), INTENSITY), )
        subject_b = Subject(
            Image('t1', self.get_image_path('t1_b'), INTENSITY),
            Image('label', self.get_image_path('label_b', binary=True), LABEL),
        )
        subject_c = Subject(
            Image('label', self.get_image_path('label_c', binary=True),
                  LABEL), )
        subject_d = Subject(
            Image('t1', self.get_image_path('t1_d'), INTENSITY),
            Image('t2', self.get_image_path('t2_d'), INTENSITY),
            Image('label', self.get_image_path('label_d', binary=True), LABEL),
        )
        self.subjects_list = [
            subject_a,
            subject_b,
            subject_c,
            subject_d,
        ]
        self.dataset = ImagesDataset(self.subjects_list)
        self.sample = self.dataset[-1]
Exemplo n.º 2
0
    def setUp(self):
        """Set up test fixtures, if any."""
        self.dir = Path(tempfile.gettempdir()) / '.torchio_tests'
        self.dir.mkdir(exist_ok=True)
        random.seed(42)
        np.random.seed(42)

        registration_matrix = np.array([[1, 0, 0, 10], [0, 1, 0, 0],
                                        [0, 0, 1.2, 0], [0, 0, 0, 1]])

        subject_a = Subject(t1=Image(self.get_image_path('t1_a'), INTENSITY), )
        subject_b = Subject(
            t1=Image(self.get_image_path('t1_b'), INTENSITY),
            label=Image(self.get_image_path('label_b', binary=True), LABEL),
        )
        subject_c = Subject(label=Image(
            self.get_image_path('label_c', binary=True), LABEL), )
        subject_d = Subject(
            t1=Image(
                self.get_image_path('t1_d'),
                INTENSITY,
                pre_affine=registration_matrix,
            ),
            t2=Image(self.get_image_path('t2_d'), INTENSITY),
            label=Image(self.get_image_path('label_d', binary=True), LABEL),
        )
        self.subjects_list = [
            subject_a,
            subject_b,
            subject_c,
            subject_d,
        ]
        self.dataset = ImagesDataset(self.subjects_list)
        self.sample = self.dataset[-1]
Exemplo n.º 3
0
def main():
    # Define training and patches sampling parameters
    num_epochs = 20
    patch_size = 128
    queue_length = 100
    samples_per_volume = 5
    batch_size = 2

    # Populate a list with images
    one_subject = Subject(
        T1=Image('../BRATS2018_crop_renamed/LGG75_T1.nii.gz',
                 torchio.INTENSITY),
        T2=Image('../BRATS2018_crop_renamed/LGG75_T2.nii.gz',
                 torchio.INTENSITY),
        label=Image('../BRATS2018_crop_renamed/LGG75_Label.nii.gz',
                    torchio.LABEL),
    )

    # This subject doesn't have a T2 MRI!
    another_subject = Subject(
        T1=Image('../BRATS2018_crop_renamed/LGG74_T1.nii.gz',
                 torchio.INTENSITY),
        label=Image('../BRATS2018_crop_renamed/LGG74_Label.nii.gz',
                    torchio.LABEL),
    )

    subjects = [
        one_subject,
        another_subject,
    ]

    subjects_dataset = ImagesDataset(subjects)
    queue_dataset = Queue(
        subjects_dataset,
        queue_length,
        samples_per_volume,
        patch_size,
        ImageSampler,
    )

    # This collate_fn is needed in the case of missing modalities
    # In this case, the batch will be composed by a *list* of samples instead of
    # the typical Python dictionary that is collated by default in Pytorch
    batch_loader = DataLoader(
        queue_dataset,
        batch_size=batch_size,
        collate_fn=lambda x: x,
    )

    # Mock PyTorch model
    model = nn.Identity()

    for epoch_index in range(num_epochs):
        for batch in batch_loader:  # batch is a *list* here, not a dictionary
            logits = model(batch)
            print([batch[idx].keys() for idx in range(batch_size)])
    print()
Exemplo n.º 4
0
 def _get_subjects_list(root, modalities):
     one_modality = modalities[0]
     paths = sglob(root / one_modality, '*.nii.gz')
     subjects = []
     for filepath in paths:
         subject_id = get_subject_id(filepath)
         images_dict = dict(subject_id=subject_id)
         images_dict[one_modality] = Image(filepath, INTENSITY)
         for modality in modalities[1:]:
             globbed = sglob(root / modality,
                             f'{subject_id}-{modality}.nii.gz')
             if globbed:
                 assert len(globbed) == 1
                 images_dict[modality] = Image(globbed[0], INTENSITY)
             else:
                 skip_subject = True
                 break
         else:
             skip_subject = False
         if '-HH-' not in images_dict['subject_id']:
             skip_subject = True
         if skip_subject:
             continue
         subjects.append(Subject(**images_dict))
     return subjects
Exemplo n.º 5
0
    def get_volume_torchio_without_motion(self, idx, return_orig=False):
        subject_row = self.get_row(idx)
        dict_suj = dict()
        if not pd.isna(subject_row["image_filename"]):
            path_imgs = self.read_path(subject_row["image_filename"])
            if path_imgs:
                imgs = ScalarImage(path_imgs)
                dict_suj["t1"] = imgs

        if "label_filename" in subject_row.keys() and not pd.isna(
                subject_row["label_filename"]):
            path_imgs = self.read_path(subject_row["label_filename"])
            imgs = LabelMap(path_imgs)
            dict_suj["label"] = imgs
        sub = Subject(dict_suj)
        if "history" not in self.df_data.columns:
            return sub
        else:
            trsfms = self.get_transformations(idx)
            trsfms_short = []
            for tr in trsfms.transforms:  #.transforms:
                print(tr.name)
                if isinstance(tr, torchio.transforms.LabelsToImage):
                    tr.label_key = "label"
                if isinstance(tr, torchio.transforms.MotionFromTimeCourse):
                    tmot = tr
                    break
                trsfms_short.append(tr)
            trsfms_short = torchio.Compose(trsfms_short)
            res = trsfms_short(sub)
            return res, tmot
Exemplo n.º 6
0
 def test_inconsistent_spatial_shape(self):
     subject = Subject(
         a=ScalarImage(tensor=torch.rand(1, 3, 3, 4)),
         b=ScalarImage(tensor=torch.rand(2, 2, 3, 4)),
     )
     with self.assertRaises(RuntimeError):
         subject.spatial_shape
Exemplo n.º 7
0
 def _resize(self, image: ScalarImage, label_map: LabelMap):
     res_subject = Resize(self.cfg["desired_size"]).apply_transform(
         Subject(
             image=ScalarImage(tensor=image.data),
             seg=LabelMap(tensor=label_map.data),
         )
     )
     return res_subject["image"], res_subject["seg"]
Exemplo n.º 8
0
 def test_duplicate_image_name(self):
     with self.assertRaises(KeyError):
         with tempfile.NamedTemporaryFile() as f:
             Subject(
                 Image('t1', f.name, INTENSITY),
                 Image('t1', f.name, INTENSITY),
             )
         self.iterate_dataset([images])
Exemplo n.º 9
0
 def get_subject_with_partial_volume_label_map(self, components=1):
     """Return a subject with a partial-volume label map."""
     return Subject(
         t1=ScalarImage(self.get_image_path('t1_d'), ),
         label=LabelMap(
             self.get_image_path('label_d2',
                                 binary=False,
                                 components=components)),
     )
Exemplo n.º 10
0
 def setUp(self):
     super().setUp()
     self.subjects = [
         Subject(
             image=ScalarImage(self.get_image_path(f'hs_image_{i}')),
             label=LabelMap(self.get_image_path(f'hs_label_{i}')),
         )
         for i in range(5)
     ]
     self.dataset = SubjectsDataset(self.subjects)
Exemplo n.º 11
0
 def get_inconsistent_sample(self):
     """Return a sample containing images of different shape."""
     subject = Subject(
         Image('t1', self.get_image_path('t1_d'), INTENSITY),
         Image('t2', self.get_image_path('t2_d', shape=(10, 20, 31)),
               INTENSITY),
         Image('label', self.get_image_path('label_d', binary=True), LABEL),
     )
     subjects_list = [subject]
     dataset = ImagesDataset([subject])
     return dataset[0]
Exemplo n.º 12
0
    def test_all_random_transforms(self):
        sample = Subject(t1=ScalarImage(tensor=torch.rand(1, 20, 20, 20)),
                         seg=LabelMap(tensor=torch.rand(1, 20, 20, 20) > 1))

        transforms_names = [
            name for name in dir(torchio) if name.startswith('Random')
        ]

        # Downsample at the end so that image shape is not modified
        transforms_names.remove('RandomDownsample')
        transforms_names.append('RandomDownsample')

        transforms = []
        for transform_name in transforms_names:
            # Only transform needing an argument for __init__
            if transform_name == 'RandomLabelsToImage':
                transform = getattr(torchio, transform_name)(label_key='seg')
            else:
                transform = getattr(torchio, transform_name)()
            transforms.append(transform)
        composed_transform = torchio.Compose(transforms)
        with warnings.catch_warnings():  # ignore elastic deformation warning
            warnings.simplefilter('ignore', RuntimeWarning)
            transformed = composed_transform(sample)

        new_transforms, seeds = compose_from_history(transformed.history)
        new_transformed = self.apply_transforms(subject=sample,
                                                trsfm_list=new_transforms,
                                                seeds_list=seeds)
        """
        new_transforms = []
        seeds = []

        for transform_name, params_dict in transformed.history:
            # The Resample transform in the history comes from the DownSampling
            if transform_name in ['Resample', 'Compose']:
                continue
            transform_class = getattr(torchio, transform_name)

            if transform_name == 'RandomLabelsToImage':
                transform = transform_class(label_key='seg')
            else:
                transform = transform_class()
            new_transforms.append(transform)
            seeds.append(params_dict['seed'])

        composed_transform = torchio.Compose(new_transforms)
        with warnings.catch_warnings():  # ignore elastic deformation warning
            warnings.simplefilter('ignore', RuntimeWarning)
            new_transformed = composed_transform(sample, seeds=seeds)
        """

        self.assertTensorEqual(transformed.t1.data, new_transformed.t1.data)
        self.assertTensorEqual(transformed.seg.data, new_transformed.seg.data)
Exemplo n.º 13
0
def get_subject_list_from_file_list(fin, mask_regex=None, mask_key='brain'):
    subjects_list = []
    for ff in fin:
        one_suj = {'image': Image(ff, INTENSITY)}
        if mask_regex is not None:
            dir_file = get_parent_path(ff)[0]
            fmask = gfile(dir_file, mask_regex, {"items": 1})
            one_suj[mask_key] = Image(fmask[0], LABEL)

        subjects_list.append(Subject(one_suj))

    return subjects_list
Exemplo n.º 14
0
    def get_volume_torchio(self, idx, return_orig=False):
        subject_row = self.get_row(idx)
        dict_suj = dict()
        if not pd.isna(subject_row["image_filename"]):
            path_imgs = self.read_path(subject_row["image_filename"])
            if path_imgs:
                imgs = ScalarImage(path_imgs)
                dict_suj["t1"] = imgs

        if "label_filename" in subject_row.keys() and not pd.isna(
                subject_row["label_filename"]):
            path_imgs = self.read_path(subject_row["label_filename"])
            imgs = LabelMap(path_imgs)
            dict_suj["label"] = imgs
        sub = Subject(dict_suj)
        if "history" not in self.df_data.columns:
            return sub
        else:
            trsfms = self.get_transformations(idx)
            res = sub
            for tr in trsfms.transforms:  #.transforms:
                print(tr.name)
                if isinstance(tr, torchio.transforms.LabelsToImage):
                    tr.label_key = "label"
                if isinstance(tr, torchio.transforms.MotionFromTimeCourse):
                    output_path = opj(self.out_tmp, "{}.png".format(idx))
                    fitpars = tr.fitpars["t1"]
                    plt.figure()
                    plt.plot(fitpars.T)
                    plt.legend([
                        "trans_x", "trans_y", "trans_z", "rot_x", "rot_y",
                        "rot_z"
                    ])
                    plt.xlabel("Timesteps")
                    plt.ylabel("Magnitude")
                    plt.title("Motion parameters")
                    plt.savefig(output_path)
                    plt.close()
                    self.written_files.append(output_path)
                #Bad bug fix, du to frequency_encogin_dim save without a dict ...
                if isinstance(
                        tr, torchio.transforms.augmentation.intensity.
                        random_motion_from_time_course.MotionFromTimeCourse):
                    if isinstance(tr.tr, dict):
                        if not isinstance(tr.frequency_encoding_dim, dict):
                            value = tr.frequency_encoding_dim
                            aaa = dict()
                            for k in tr.tr.keys():
                                aaa[k] = value
                            tr.frequency_encoding_dim = aaa
            res = trsfms(sub)
            return res
Exemplo n.º 15
0
 def setUp(self):
     super().setUp()
     subjects = []
     for i in range(5):
         image = ScalarImage(self.get_image_path(f'hs_image_{i}'))
         label_path = self.get_image_path(f'hs_label_{i}',
                                          binary=True,
                                          force_binary_foreground=True)
         label = LabelMap(label_path)
         subject = Subject(image=image, label=label)
         subjects.append(subject)
     self.subjects = subjects
     self.dataset = SubjectsDataset(self.subjects)
Exemplo n.º 16
0
    def get_volume_torchio(self, idx, return_orig=False):
        subject_row = self.get_row(idx)
        dict_suj = dict()
        if not pd.isna(subject_row["image_filename"]):
            path_imgs = self.read_path(subject_row["image_filename"])
            if path_imgs:
                if isinstance(path_imgs, list):
                    imgs = ScalarImage(tensor=np.asarray(
                        [nb.load(p).get_fdata() for p in path_imgs]))
                else:
                    imgs = ScalarImage(path_imgs)
                dict_suj["t1"] = imgs

        if "label_filename" in subject_row.keys() and not pd.isna(
                subject_row["label_filename"]):
            path_imgs = self.read_path(subject_row["label_filename"])
            if isinstance(path_imgs, list):
                imgs = LabelMap(tensor=np.asarray(
                    [nb.load(p).get_fdata() for p in path_imgs]))
            else:
                imgs = LabelMap(path_imgs)
            dict_suj["label"] = imgs
        sub = Subject(dict_suj)
        if "history" not in self.df_data.columns:
            return sub
        else:
            trsfms = self.get_transformations(idx)
            res = sub
            for tr in trsfms.transforms:  #.transforms:
                print(tr.name)
                if isinstance(tr, torchio.transforms.LabelsToImage):
                    tr.label_key = "label"
                if isinstance(tr, torchio.transforms.MotionFromTimeCourse):
                    output_path = opj(self.out_tmp, "{}.png".format(idx))
                    fitpars = tr.fitpars["t1"]
                    plt.figure()
                    plt.plot(fitpars.T)
                    plt.legend([
                        "trans_x", "trans_y", "trans_z", "rot_x", "rot_y",
                        "rot_z"
                    ])
                    plt.xlabel("Timesteps")
                    plt.ylabel("Magnitude")
                    plt.title("Motion parameters")
                    plt.savefig(output_path)
                    plt.close()
                    self.written_files.append(output_path)
                res = tr(res)
            res = trsfms(sub)
            return res
 def setUp(self):
     super().setUp()
     self.subjects = [
         Subject(
             image=ScalarImage(self.get_image_path(f'hs_image_{i}')),
             label=LabelMap(
                 self.get_image_path(
                     f'hs_label_{i}',
                     binary=True,
                     force_binary_foreground=True,
                 ), ),
         ) for i in range(5)
     ]
     self.dataset = SubjectsDataset(self.subjects)
Exemplo n.º 18
0
    def _get_subjects_list(self) -> List[Subject]:
        if not os.path.exists(self.cfg["cache_path"]):
            self._generate_cache()
            multitasking.wait_for_tasks()

        subjects = []
        for pt_name in os.listdir(self.cfg["cache_path"]):
            pt_data = torch.load(os.path.join(self.cfg["cache_path"], pt_name))

            subjects.append(
                Subject(
                    subject_id=pt_data["subject_id"],
                    image=ScalarImage(tensor=pt_data["image"]),
                    seg=LabelMap(tensor=pt_data["seg"]),
                )
            )
        return subjects
Exemplo n.º 19
0
 def get_inconsistent_sample(self):
     """Return a sample containing images of different shape."""
     subject = Subject(
         t1=Image(self.get_image_path('t1_d'), INTENSITY),
         t2=Image(self.get_image_path('t2_d', shape=(10, 20, 31)),
                  INTENSITY),
         label=Image(
             self.get_image_path(
                 'label_d',
                 shape=(8, 17, 25),
                 binary=True,
             ),
             LABEL,
         ),
     )
     subjects_list = [subject]
     dataset = ImagesDataset(subjects_list)
     return dataset[0]
Exemplo n.º 20
0
 def get_inconsistent_shape_subject(self):
     """Return a subject containing images of different shape."""
     subject = Subject(
         t1=ScalarImage(self.get_image_path('t1_inc')),
         t2=ScalarImage(self.get_image_path('t2_inc', shape=(10, 20, 31))),
         label=LabelMap(
             self.get_image_path(
                 'label_inc',
                 shape=(8, 17, 25),
                 binary=True,
             ), ),
         label2=LabelMap(
             self.get_image_path(
                 'label2_inc',
                 shape=(18, 17, 25),
                 binary=True,
             ), ),
     )
     return subject
Exemplo n.º 21
0
 def test_no_sample(self):
     with tempfile.NamedTemporaryFile() as f:
         input_dict = {'image': ScalarImage(f.name)}
         subject = Subject(input_dict)
         with self.assertRaises(RuntimeError):
             RandomFlip()(subject)
Exemplo n.º 22
0
 def test_input_dict(self):
     with tempfile.NamedTemporaryFile() as f:
         input_dict = {'image': ScalarImage(f.name)}
         Subject(input_dict)
         Subject(**input_dict)
Exemplo n.º 23
0
"""
Another way of getting this result is by running the command-line tool:

$ torchio-transform ~/Dropbox/MRI/t1.nii.gz RandomMotion /tmp/t1_motion.nii.gz --seed 42 --kwargs "degrees=10 translation=10 num_transforms=3 proportion_to_augment=1"

"""

from pprint import pprint
from torchio import Image, ImagesDataset, transforms, INTENSITY, LABEL, Subject

subject = Subject(
    Image('label', '~/Dropbox/MRI/t1_brain_seg.nii.gz', LABEL),
    Image('t1', '~/Dropbox/MRI/t1.nii.gz', INTENSITY),
)
subjects_list = [subject]

dataset = ImagesDataset(subjects_list)
sample = dataset[0]
transform = transforms.RandomMotion(
    seed=42,
    degrees=10,
    translation=10,
    num_transforms=3,
)
transformed = transform(sample)

pprint(transformed['t1']['random_motion_times'])
pprint(transformed['t1']['random_motion_degrees'])
pprint(transformed['t1']['random_motion_translation'])

dataset.save_sample(transformed, dict(t1='/tmp/t1_motion.nii.gz'))
Exemplo n.º 24
0
from torchio import Subject, Image, ImagesDataset
from torchio.transforms import RandomMotionFromTimeCourse
from torchio.metrics import SSIM3D, MetricWrapper, MapMetricWrapper
from torchio.metrics.ssim import functional_ssim
from torch.nn import MSELoss, L1Loss
import torch
from nibabel.viewers import OrthoSlicer3D as ov

t1_path = "/data/romain/HCPdata/suj_100307/T1w_acpc_dc_restore.nii"
mask_path = "/data/romain/HCPdata/suj_100307/cat12/fill_mask_head.nii.gz"
dataset = ImagesDataset([
    Subject({
        "T1": Image(t1_path),
        "mask": Image(mask_path, type="mask"),
        "mask2": Image(mask_path, type="mask")
    })
])

metrics = {
    "L1":
    MetricWrapper("L1", L1Loss()),
    "L1_map":
    MapMetricWrapper("L1_map",
                     lambda x, y: torch.abs(x - y),
                     average_method="mean",
                     mask_keys=['mask2']),
    "L2":
    MetricWrapper("L2", MSELoss()),
    #"SSIM": SSIM3D(average_method="mean"),
    "SSIM_mask":
    SSIM3D(average_method="mean", mask_keys=["mask", "mask2"]),
Exemplo n.º 25
0
 def test_positional_args(self):
     with self.assertRaises(ValueError):
         with tempfile.NamedTemporaryFile() as f:
             Subject(Image(f.name, INTENSITY))
Exemplo n.º 26
0
$ torchio-transform ~/Dropbox/MRI/t1.nii.gz RandomMotion /tmp/t1_motion.nii.gz --seed 42 --kwargs "degrees=10 translation=10 num_transforms=3"

"""

from pprint import pprint
from torchio import Image, ImagesDataset, transforms, INTENSITY, LABEL, Subject


#subject = Subject(
#    Image('label', '~/Dropbox/MRI/t1_brain_seg.nii.gz', LABEL),
#    Image('t1', '~/Dropbox/MRI/t1.nii.gz', INTENSITY),
#)
dic_suj = {'t1': Image('/data/romain/HCPdata/suj_100307/T1w_1mm.nii.gz', INTENSITY),
           'label': Image('/data/romain/HCPdata/suj_100307/T1w_1mm.nii.gz', LABEL)}
subject = Subject(dic_suj)

subject = Subject(
    t1 = Image('/data/romain/HCPdata/suj_100307/T1w_1mm.nii.gz', INTENSITY),
    label = Image('/data/romain/HCPdata/suj_100307/T1w_1mm.nii.gz', LABEL),
    )

subjects_list = [subject]

dataset = ImagesDataset(subjects_list)

sample = dataset[0]
transform = transforms.RandomMotion(
    seed=2,
    degrees=0,
    translation=100,
Exemplo n.º 27
0
 def test_input_dict(self):
     with tempfile.NamedTemporaryFile() as f:
         input_dict = {'image': Image(f.name, INTENSITY)}
         Subject(input_dict)
         Subject(**input_dict)
Exemplo n.º 28
0
def ImagesFromDataFrame(dataframe,
                        psize,
                        headers,
                        q_max_length=10,
                        q_samples_per_volume=1,
                        q_num_workers=2,
                        q_verbose=False,
                        sampler='label',
                        train=True,
                        augmentations=None,
                        preprocessing=None,
                        in_memory=False):
    # Finding the dimension of the dataframe for computational purposes later
    num_row, num_col = dataframe.shape
    # num_channels = num_col - 1 # for non-segmentation tasks, this might be different
    # changing the column indices to make it easier
    dataframe.columns = range(0, num_col)
    dataframe.index = range(0, num_row)
    # This list will later contain the list of subjects
    subjects_list = []

    channelHeaders = headers['channelHeaders']
    labelHeader = headers['labelHeader']
    predictionHeaders = headers['predictionHeaders']
    subjectIDHeader = headers['subjectIDHeader']

    sampler = sampler.lower()  # for easier parsing

    # define the control points and swap axes for augmentation
    augmentation_patchAxesPoints = copy.deepcopy(psize)
    for i in range(len(augmentation_patchAxesPoints)):
        augmentation_patchAxesPoints[i] = max(
            round(augmentation_patchAxesPoints[i] / 10),
            1)  # always at least have 1

    # iterating through the dataframe
    resizeCheck = False
    for patient in range(num_row):
        # We need this dict for storing the meta data for each subject
        # such as different image modalities, labels, any other data
        subject_dict = {}
        subject_dict['subject_id'] = dataframe[subjectIDHeader][patient]
        # iterating through the channels/modalities/timepoints of the subject
        for channel in channelHeaders:
            # assigning the dict key to the channel
            if not in_memory:
                subject_dict[str(channel)] = Image(str(
                    dataframe[channel][patient]),
                                                   type=torchio.INTENSITY)
            else:
                img = sitk.ReadImage(str(dataframe[channel][patient]))
                array = np.expand_dims(sitk.GetArrayFromImage(img), axis=0)
                subject_dict[str(channel)] = Image(
                    tensor=array,
                    type=torchio.INTENSITY,
                    path=dataframe[channel][patient])

            # if resize has been defined but resample is not (or is none)
            if not resizeCheck:
                if not (preprocessing is None) and ('resize' in preprocessing):
                    if (preprocessing['resize'] is not None):
                        resizeCheck = True
                        if not ('resample' in preprocessing):
                            preprocessing['resample'] = {}
                            if not ('resolution' in preprocessing['resample']):
                                preprocessing['resample'][
                                    'resolution'] = resize_image_resolution(
                                        subject_dict[str(channel)].as_sitk(),
                                        preprocessing['resize'])
                        else:
                            print(
                                'WARNING: \'resize\' is ignored as \'resample\' is defined under \'data_processing\', this will be skipped',
                                file=sys.stderr)
                else:
                    resizeCheck = True

        # # for regression
        # if predictionHeaders:
        #     # get the mask
        #     if (subject_dict['label'] is None) and (class_list is not None):
        #         sys.exit('The \'class_list\' parameter has been defined but a label file is not present for patient: ', patient)

        if labelHeader is not None:
            if not in_memory:
                subject_dict['label'] = Image(str(
                    dataframe[labelHeader][patient]),
                                              type=torchio.LABEL)
            else:
                img = sitk.ReadImage(str(dataframe[labelHeader][patient]))
                array = np.expand_dims(sitk.GetArrayFromImage(img), axis=0)
                subject_dict['label'] = Image(
                    tensor=array,
                    type=torchio.LABEL,
                    path=dataframe[labelHeader][patient])

            subject_dict['path_to_metadata'] = str(
                dataframe[labelHeader][patient])
        else:
            subject_dict['label'] = "NA"
            subject_dict['path_to_metadata'] = str(dataframe[channel][patient])

        # iterating through the values to predict of the subject
        valueCounter = 0
        for values in predictionHeaders:
            # assigning the dict key to the channel
            subject_dict['value_' + str(valueCounter)] = np.array(
                dataframe[values][patient])
            valueCounter = valueCounter + 1

        # Initializing the subject object using the dict
        subject = Subject(subject_dict)

        # padding image, but only for label sampler, because we don't want to pad for uniform
        if 'label' in sampler or 'weight' in sampler:
            psize_pad = list(
                np.asarray(np.round(np.divide(psize, 2)), dtype=int))
            padder = Pad(
                psize_pad, padding_mode='symmetric'
            )  # for modes: https://numpy.org/doc/stable/reference/generated/numpy.pad.html
            subject = padder(subject)

        # Appending this subject to the list of subjects
        subjects_list.append(subject)

    augmentation_list = []

    # first, we want to do thresholding, followed by clipping, if it is present - required for inference as well
    if not (preprocessing is None):
        if train:  # we want the crop to only happen during training
            if 'crop_external_zero_planes' in preprocessing:
                augmentation_list.append(
                    global_preprocessing_dict['crop_external_zero_planes'](
                        psize))
        for key in ['threshold', 'clip']:
            if key in preprocessing:
                augmentation_list.append(global_preprocessing_dict[key](
                    min=preprocessing[key]['min'],
                    max=preprocessing[key]['max']))

        # first, we want to do the resampling, if it is present - required for inference as well
        if 'resample' in preprocessing:
            if 'resolution' in preprocessing['resample']:
                # resample_split = str(aug).split(':')
                resample_values = tuple(
                    np.array(preprocessing['resample']['resolution']).astype(
                        np.float))
                if len(resample_values) == 2:
                    resample_values = tuple(np.append(resample_values, 1))
                augmentation_list.append(Resample(resample_values))

        # next, we want to do the intensity normalize - required for inference as well
        if 'normalize' in preprocessing:
            augmentation_list.append(global_preprocessing_dict['normalize'])
        elif 'normalize_nonZero' in preprocessing:
            augmentation_list.append(
                global_preprocessing_dict['normalize_nonZero'])
        elif 'normalize_nonZero_masked' in preprocessing:
            augmentation_list.append(
                global_preprocessing_dict['normalize_nonZero_masked'])

    # other augmentations should only happen for training - and also setting the probabilities
    # for the augmentations
    if train and not (augmentations == None):
        for aug in augmentations:
            if aug != 'default_probability':
                actual_function = None

                if aug == 'flip':
                    if ('axes_to_flip' in augmentations[aug]):
                        print(
                            'WARNING: \'flip\' augmentation needs the key \'axis\' instead of \'axes_to_flip\'',
                            file=sys.stderr)
                        augmentations[aug]['axis'] = augmentations[aug][
                            'axes_to_flip']
                    actual_function = global_augs_dict[aug](
                        axes=augmentations[aug]['axis'],
                        p=augmentations[aug]['probability'])
                elif aug in ['rotate_90', 'rotate_180']:
                    for axis in augmentations[aug]['axis']:
                        augmentation_list.append(global_augs_dict[aug](
                            axis=axis, p=augmentations[aug]['probability']))
                elif aug in ['swap', 'elastic']:
                    actual_function = global_augs_dict[aug](
                        patch_size=augmentation_patchAxesPoints,
                        p=augmentations[aug]['probability'])
                elif aug == 'blur':
                    actual_function = global_augs_dict[aug](
                        std=augmentations[aug]['std'],
                        p=augmentations[aug]['probability'])
                elif aug == 'noise':
                    actual_function = global_augs_dict[aug](
                        mean=augmentations[aug]['mean'],
                        std=augmentations[aug]['std'],
                        p=augmentations[aug]['probability'])
                elif aug == 'anisotropic':
                    actual_function = global_augs_dict[aug](
                        axes=augmentations[aug]['axis'],
                        downsampling=augmentations[aug]['downsampling'],
                        p=augmentations[aug]['probability'])
                else:
                    actual_function = global_augs_dict[aug](
                        p=augmentations[aug]['probability'])
                if actual_function is not None:
                    augmentation_list.append(actual_function)

    if augmentation_list:
        transform = Compose(augmentation_list)
    else:
        transform = None
    subjects_dataset = torchio.SubjectsDataset(subjects_list,
                                               transform=transform)
    if not train:
        return subjects_dataset
    if sampler in ('weighted', 'weightedsampler', 'weightedsample'):
        sampler = global_sampler_dict[sampler](psize, probability_map='label')
    else:
        sampler = global_sampler_dict[sampler](psize)
    # all of these need to be read from model.yaml
    patches_queue = torchio.Queue(subjects_dataset,
                                  max_length=q_max_length,
                                  samples_per_volume=q_samples_per_volume,
                                  sampler=sampler,
                                  num_workers=q_num_workers,
                                  shuffle_subjects=True,
                                  shuffle_patches=True,
                                  verbose=q_verbose)
    return patches_queue
Exemplo n.º 29
0
 def test_repr(self):
     sample = Subject(t1=ScalarImage(self.get_image_path('repr_test')))
     assert 'shape' not in repr(sample['t1'])
     sample.load()
     assert 'shape' in repr(sample['t1'])
Exemplo n.º 30
0
from pathlib import Path
import pandas as pd
from torchio import Image, ImagesDataset, INTENSITY, Subject
from resector import RandomResection

images_dir = Path('/tmp/noise')
subject_id = '1423'

def gp(s):
    return f'{subject_id}_t1_pre_{s}.nii.gz'

subject = Subject(
    Image('image', images_dir / gp('on_mni'), INTENSITY),
    Image('resection_noise', images_dir / gp('noise'), None),
    Image('resection_gray_matter_left', images_dir / gp('gray_matter_left_seg'), None),
    Image('resection_resectable_left', images_dir / gp('resectable_left_seg'), None),
    Image('resection_gray_matter_right', images_dir / gp('gray_matter_right_seg'), None),
    Image('resection_resectable_right', images_dir / gp('resectable_right_seg'), None),
)

df_volumes = pd.read_csv(Path('~/episurg/volumes.csv').expanduser())
volumes = df_volumes.Volume.values

transform = RandomResection(
    volumes=volumes,
    # sigmas_range=(0.75, 0.75),
    keep_original=True,
    verbose=True,
    # seed=42,
)