Skip to content

Add median image filter as a transform #5264

@dzenanz

Description

@dzenanz

Is your feature request related to a problem? Please describe.
One problem is explained in #3178.

Describe the solution you'd like
Add a median filter based on @ebrahimebrahim's medianblur_with_gpu

Describe alternatives you've considered
#3178 mentions some alternatives, such as mean filtering. Those are suboptimal for many use cases.

Additional context
Model it after GaussianSmooth:

class GaussianSmooth(Transform):
"""
Apply Gaussian smooth to the input data based on specified `sigma` parameter.
A default value `sigma=1.0` is provided for reference.
Args:
sigma: if a list of values, must match the count of spatial dimensions of input data,
and apply every value in the list to 1 spatial dimension. if only 1 value provided,
use it for all spatial dimensions.
approx: discrete Gaussian kernel type, available options are "erf", "sampled", and "scalespace".
see also :py:meth:`monai.networks.layers.GaussianFilter`.
"""
backend = [TransformBackends.TORCH]
def __init__(self, sigma: Union[Sequence[float], float] = 1.0, approx: str = "erf") -> None:
self.sigma = sigma
self.approx = approx
def __call__(self, img: NdarrayTensor) -> NdarrayTensor:
img = convert_to_tensor(img, track_meta=get_track_meta())
img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float)
sigma: Union[Sequence[torch.Tensor], torch.Tensor]
if isinstance(self.sigma, Sequence):
sigma = [torch.as_tensor(s, device=img_t.device) for s in self.sigma]
else:
sigma = torch.as_tensor(self.sigma, device=img_t.device)
gaussian_filter = GaussianFilter(img_t.ndim - 1, sigma, approx=self.approx)
out_t: torch.Tensor = gaussian_filter(img_t.unsqueeze(0)).squeeze(0)
out, *_ = convert_to_dst_type(out_t, dst=img, dtype=out_t.dtype)
return out

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions