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

Add transform to ignore tumors smaller than x mm^3 #3808

Closed
Nic-Ma opened this issue Feb 15, 2022 · 4 comments
Closed

Add transform to ignore tumors smaller than x mm^3 #3808

Nic-Ma opened this issue Feb 15, 2022 · 4 comments

Comments

@Nic-Ma
Copy link
Contributor

Nic-Ma commented Feb 15, 2022

Is your feature request related to a problem? Please describe.
Feature request from Ahmed: I just faced another interesting use case. Similar to keep largest connected component, Sometimes we want to ignore tumors that are smaller than x mm^3.
If you can implement this as a post transform it would be great.

@ebrahimebrahim
Copy link
Contributor

ebrahimebrahim commented Feb 15, 2022

Since I've been playing with ITK for these kinds of post processing tasks lately, I wanted to share that it's potentially an option here. It could allow for some flexibility/genericness with respect to the segment shape properties the user chooses to base their filter on: physical size, perimeter, centroid location, etc.

examples, assuming seg is a binary label map of shape (1,H,W):

import itk

# Convert tensor to ITK image
seg_itk = itk.image_from_array((seg.numpy()).astype(np.uint8))

# Get connected components
seg_connected_components = itk.ConnectedComponentImageFilter(seg_itk)

# Get a shape statistics object for each connected component
label_map = itk.LabelImageToShapeLabelMapFilter(seg_connected_components.astype(itk.UC))
num_label_objects = label_map.GetNumberOfLabelObjects()

# e.g. get the size of each connected component
[label_map.GetNthLabelObject(n).GetNumberOfPixels() for n in range(num_label_objects)]

# or various other properties
[label_map.GetNthLabelObject(n).GetPerimeter() for n in range(num_label_objects)]
[label_map.GetNthLabelObject(n).GetCentroid() for n in range(num_label_objects)]

@wyli
Copy link
Contributor

wyli commented Oct 5, 2022

def remove_small_objects(
img: NdarrayTensor, min_size: int = 64, connectivity: int = 1, independent_channels: bool = True
) -> NdarrayTensor:

the remove_small_objects has a min_size parameter which could be extended to take into account img.pixdim to compute mm^3 if the first argument img is a metatensor.

@rijobro
Copy link
Contributor

rijobro commented Oct 5, 2022

Should we compute the volume from the number of voxels, or should we require the user to calculate it themselves? Either way it's a trivial calculation, but the large majority of our codebase is in image space (aside from Spacing-esque transforms). I would lean more towards staying in image space and requiring the user to calculate it themselves.

@vikashg
Copy link

vikashg commented Jan 5, 2024

closing because of inactivity and alternate solutions exist.

@vikashg vikashg closed this as completed Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants