Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tutorial/demo for 2D slice analysis based on 3D inputs #130

Closed
wyli opened this issue Feb 25, 2021 · 5 comments · Fixed by #747
Closed

tutorial/demo for 2D slice analysis based on 3D inputs #130

wyli opened this issue Feb 25, 2021 · 5 comments · Fixed by #747

Comments

@wyli
Copy link
Contributor

wyli commented Feb 25, 2021

Is your feature request related to a problem? Please describe.
would be great to demonstrate the available options for both training and inference

there were quite a few requests, see also:

@rijobro
Copy link
Contributor

rijobro commented Feb 25, 2021

Feel free to use this if it's of use to you.

For the inverse transformation / test time augmentation notebook, I created a 2D dataset from the 3D brain tumour dataset. I use the slice in the 3D that had the largest segmented volume.

I then saved to file, which obviously isn't necessary, but I found it to be faster. Output is then a list of dictionaries with filenames to the 2D slices: {"image": im_2d_fname, "label": label_2d_fname}. Filenames are preserved from the original images' metadata.

class SliceWithMaxNumLabelsd(MapTransform):
    def __init__(self, keys, label_key):
        self.keys = keys
        self.label_key = label_key

    def __call__(self, data):
        d = dict(data)
        im = d[self.label_key]
        q = np.sum((im > 0).reshape(-1, im.shape[-1]), axis=0)
        _slice = np.where(q == np.max(q))[0][0]
        for key in self.keys:
            d[key] = d[key][..., _slice]
        return d


class SaveSliced(MapTransform):
    def __init__(self, keys, path):
        self.keys = keys
        self.path = path

    def __call__(self, data):
        d = {}
        for key in self.keys:
            fname = os.path.basename(
                data[key + "_meta_dict"]["filename_or_obj"])
            path = os.path.join(self.path, key, fname)
            nib.save(nib.Nifti1Image(data[key], np.eye(4)), path)
            d[key] = path
        return d


keys = ["image", "label"]
data_dir = os.path.join(root_dir, task + "_single_slice")
for key in keys:
    os.makedirs(os.path.join(data_dir, key), exist_ok=True)
transform_2d_slice = Compose([
    LoadImaged(keys),
    AsChannelFirstd("image"),
    AddChanneld("label"),
    SliceWithMaxNumLabelsd(keys, "label"),
    SaveSliced(keys, data_dir),
])
ds_2d = Dataset(data_dicts, transform_2d_slice)
dl_2d = DataLoader(ds_2d, batch_size=1, num_workers=10)
data_dicts_single_slice = list(tqdm(dl_2d))

@rijobro
Copy link
Contributor

rijobro commented Feb 25, 2021

SliceWithMaxNumLabelsd could be generalised and added to MONAI if you'd like. By generalised I mean the user could choose along which spatial axis they want to slice.

@wyli
Copy link
Contributor Author

wyli commented Feb 25, 2021

thanks, I think recently we have a SaveImage transform implemented, might be useful here as well

@rijobro
Copy link
Contributor

rijobro commented Feb 25, 2021

Certainly could, I'll look into updating my PR!

I just noticed that when you refer to a Discussion (e.g., your first link), that discussion doesn't get a link pointing to the issue/PR discussing it. This is a shame, since the people who posted those questions won't necessarily know we're discussing it here.

@hasansari
Copy link

Hello, I am just wondering if there is a new transform implemented in Monai to get 2D samples from 3D volumes. I use RandWeightedCropd during the training to feed random slices into my 2D network. My question is if there is any function to sequentially get all test all of the slices of a 3D volume during the inference stage so I can save the output as a 3D volume?

Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants