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

A utility function to generate sampling points #6704

Closed
wyli opened this issue Jul 11, 2023 · 2 comments · Fixed by #7712
Closed

A utility function to generate sampling points #6704

wyli opened this issue Jul 11, 2023 · 2 comments · Fixed by #7712

Comments

@wyli
Copy link
Contributor

wyli commented Jul 11, 2023

Is your feature request related to a problem? Please describe.
Currently there are a few functions in monai.transforms to help sampling image patches:

  1. map_classes_to_indices to identify all feasible sampling indices
  2. generate_label_classes_crop_centers to subsample and generate spatial coordinates
  3. RandCropByLabelClasses combines 1, 2 and output image patches

Describe the solution you'd like

Would be great to have a helper function to run step 1 and 2 as a single command. The function should output sampling coordinates instead of the final patch

Describe alternatives you've considered

Write the logic with multiple commands: https://gist.github.com/wyli/50c65e686beaf418a32c9cc131f0bdc7

Same idea applies to the other sampling transforms such as RandCropByPosNegLabel

@Yu0610
Copy link
Contributor

Yu0610 commented Dec 4, 2023

I wrote this helper function with the expectation that the output would be the coordinates of the centers. I hope it meets your requirements.

def combineMCtIandGLCCC(
    label: NdarrayOrTensor,
    spatial_size: Sequence[int] | int,
    num_samples: int,
    label_spatial_shape: Sequence[int],
    indices: Sequence[NdarrayOrTensor],
    num_classes: int | None = None,
    image: NdarrayOrTensor | None = None,
    image_threshold: float = 0.0,
    max_samples_per_class: int | None = None,
    ratios: list[float | int] | None = None,
    rand_state: np.random.RandomState | None = None,
    allow_smaller: bool = False,
    warn: bool = True,
) -> list[NdarrayOrTensor]:
    """
    Combine "map_classes_to_indices" and "generate_pos_neg_label_crop_centers" functions, return crop center coordinates.
     Args:
        spatial_size: spatial size of the ROIs to be sampled.
        num_samples: total sample centers to be generated.
        pos_ratio: ratio of total locations generated that have center being foreground.
        label_spatial_shape: spatial shape of the original label data to unravel selected centers.
        fg_indices: pre-computed foreground indices in 1 dimension.
        bg_indices: pre-computed background indices in 1 dimension.
        rand_state: numpy randomState object to align with other modules.
        allow_smaller: if `False`, an exception will be raised if the image is smaller than
            the requested ROI in any dimension. If `True`, any smaller dimensions will be set to
            match the cropped size (i.e., no cropping in that dimension).
        label: use the label data to get the indices of every class.
        num_classes: number of classes for argmax label, not necessary for One-Hot label.
        image: if image is not None, only return the indices of every class that are within the valid
            region of the image (``image > image_threshold``).
        image_threshold: if enabled `image`, use ``image > image_threshold`` to
            determine the valid image content area and select class indices only in this area.
        max_samples_per_class: maximum length of indices in each class to reduce memory consumption.
            Default is None, no subsampling.    
        
        Raises:
        ValueError: When the proposed roi is larger than the image.
        ValueError: When the foreground and background indices lengths are 0.
    """

    indices_ = indices if indices is None else indices
    if indices_ is None:
        if label is None:
            raise ValueError("label must not be None.")
        indices_ = map_classes_to_indices(
            label, num_classes, image, image_threshold, max_samples_per_class
        )
    _shape = None
    if label is not None:
        _shape = label.peek_pending_shape() if isinstance(label, MetaTensor) else label.shape[1:]
    elif image is not None:
        _shape = image.peek_pending_shape() if isinstance(image, MetaTensor) else image.shape[1:]
    if _shape is None:
        raise ValueError("label or image must be provided to infer the output spatial shape.")
    centers = generate_label_classes_crop_centers(
        spatial_size, num_samples, _shape, indices_, ratios, rand_state, allow_smaller, warn
    )
    return centers

@vikashg
Copy link

vikashg commented Jan 4, 2024

@Yu0610 can you start a PR ?

@Yu0610 Yu0610 mentioned this issue Apr 25, 2024
ytl0623 added a commit to ytl0623/MONAI that referenced this issue Apr 25, 2024
Signed-off-by: ytl0623 <[email protected]>
ytl0623 added a commit to ytl0623/MONAI that referenced this issue Apr 25, 2024
Signed-off-by: ytl0623 <[email protected]>
ytl0623 added a commit to ytl0623/MONAI that referenced this issue Apr 25, 2024
Signed-off-by: ytl0623 <[email protected]>
ytl0623 added a commit to ytl0623/MONAI that referenced this issue Apr 25, 2024
Signed-off-by: ytl0623 <[email protected]>
ytl0623 added a commit to ytl0623/MONAI that referenced this issue Apr 25, 2024
Signed-off-by: ytl0623 <[email protected]>
ytl0623 added a commit to ytl0623/MONAI that referenced this issue Apr 25, 2024
Signed-off-by: ytl0623 <[email protected]>
KumoLiu added a commit that referenced this issue May 21, 2024
Fixes #6704

### Description
Combined `map_classes_to_indices` and
`generate_label_classes_crop_centers` to a single function
`map_and_generate_sampling_centers` in monai.transforms.utils.py.

### Types of changes
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [ ] New tests added to cover the changes.
- [ ] Integration tests passed locally by running `./runtests.sh -f -u
--net --coverage`.
- [ ] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [ ] In-line docstrings updated.
- [ ] Documentation updated, tested `make html` command in the `docs/`
folder.

---------

Signed-off-by: ytl0623 <[email protected]>
Co-authored-by: Eric Kerfoot <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Yu <[email protected]>
Co-authored-by: YunLiu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants