Skip to content

SynthShapes.texturizing

The SynthShapes.texturizing module provides tools for converting labeled data into textured intensity images, facilitating the creation of synthetic medical images with realistic textures.

LabelsToIntensities

LabelsToIntensities(mu=1, sigma=2, min=0.1, max=0.5, transform=None)

Bases: Module

Convert a set of labeled data with unique IDs into intensity images using Gaussian Mixture Models.

This module transforms (int) labeled tensors, where each label represents a distinct region or structure, into intensity images. It applies a Gaussian Mixture Model (GMM) to texturize and assign semi-realistic intensity values to each label with randomly sampled mean values, facilitating the generation of synthetic images with varied textures.

Initialize the LabelsToIntensities module.

PARAMETER DESCRIPTION
mu

Mean of GMM.

TYPE: float DEFAULT: 1

sigma

Sigma of GMM.

TYPE: float DEFAULT: 2

min

Minimum value of the output tensor (except background zeros)

TYPE: float DEFAULT: 0.1

max

Maximum value of output tensor.

TYPE: float DEFAULT: 0.5

transform

Single transform or moduledict

TYPE: Module DEFAULT: None

Source code in SynthShapes/texturizing.py
def __init__(
    self,
    mu: Union[float, int] = 1,
    sigma: Union[float, int] = 2,
    min: Union[float, int] = 0.1,
    max: Union[float, int] = 0.5,
    transform: nn.Module = None
):
    """
    Initialize the `LabelsToIntensities` module.

    Parameters
    ----------
    mu : float
        Mean of GMM.
    sigma : float
        Sigma of GMM.
    min : float
        Minimum value of the output tensor (except background zeros)
    max : float
        Maximum value of output tensor.
    transform : torch.nn.Module
        Single transform or moduledict
    """
    super(LabelsToIntensities, self).__init__()
    self.mu = mu
    self.sigma = sigma
    self.min = min
    self.max = max
    if transform is None:
        self.transform = RandomGaussianMixtureTransform(mu=1, sigma=2)
    else:
        self.transform = transform

forward

forward(labels)

Convert labeled data into intensity images by applying the GMM.

PARAMETER DESCRIPTION
labels

Labels of shape (D, H, W) with unique integer IDs

TYPE: Tensor

RETURNS DESCRIPTION
Tensor

An intensity image tensor where each label has been replaced by a corresponding intensity value (the average intensity value for that region). Background regions (label=0) are set to zero. Output shape is identical to input: (D, H, W)

Source code in SynthShapes/texturizing.py
def forward(self, labels: torch.Tensor) -> torch.Tensor:
    """
    Convert labeled data into intensity images by applying the GMM.

    Parameters
    ----------
    labels : torch.Tensor
        Labels of shape (D, H, W) with unique integer IDs

    Returns
    -------
    torch.Tensor
        An intensity image tensor where each label has been replaced by
        a corresponding intensity value (the average intensity value for
        that region). Background regions (label=0) are set to zero.
        Output shape is identical to input: (D, H, W)
    """
    # Create a mask for all labels (background = 0, labels = 1)
    label_mask = torch.clone(labels) != 0
    # Assign intensities by applying transform
    intensities = self.transform(labels)
    # Invert mask and zero all background values
    intensities[~label_mask] = 0
    return intensities

TexturizeLabels

TexturizeLabels(sigma=2, intensity=1, transform=None)

Bases: Module

PARAMETER DESCRIPTION
sigma

Standard deviation for label textures.

TYPE: float DEFAULT: 2

intensity

TYPE: float DEFAULT: 1

Source code in SynthShapes/texturizing.py
def __init__(self, sigma: float = 2, intensity: float = 1,
             transform=None):
    """
    Parameters
    ----------
    sigma: Sampler or float
        Standard deviation for label textures.
    intensity 
    """
    super(TexturizeLabels, self).__init__()
    self.sigma = cc.Uniform.make(make_range(0, sigma))
    self.intensity = cc.Uniform.make(make_range(0, intensity))
    if transform is None:
        self.transform = torch.nn.Sequential(
            cc.RandomGaussianMixtureTransform(sigma=self.sigma),
            cc.RandomGammaNoiseTransform(),
            cc.MulFieldTransform(vmin=0.1, vmax=0.75)
            )
    else:
        self.transform = transform

ParenchymaSynthesizer

ParenchymaSynthesizer()

Bases: Module

A torch.nn.Module subclass that synthesizes a background tensor by applying a series of transformations.

Source code in SynthShapes/texturizing.py
def __init__(self):
    """
    A torch.nn.Module subclass that synthesizes a background tensor
    by applying a series of transformations.
    """
    super(ParenchymaSynthesizer, self).__init__()

    # Define the transformations to be applied sequentially
    self.parenchyma_transform = torch.nn.Sequential(
        cc.RandomGaussianMixtureTransform(mu=1, sigma=2),
        MinMaxScaler(),
        cc.RandomGammaNoiseTransform(),
        MinMaxScaler(),
        cc.MulFieldTransform(vmin=0.1, vmax=0.75),
        MinMaxScaler(),
    )

    # Define the final quantile transform
    self.quantile_transform = cc.QuantileTransform()

    # Define the blender
    self.blender = Blender()

    # Define the initial smooth label map generator
    self.random_smooth_label_map = cc.RandomSmoothLabelMap()

    # Final MinMaxScaler to normalize the background
    self.final_scaler = MinMaxScaler()

forward

forward(intensities_list, alpha=0.4)

Synthesizes the background by applying the defined transformations and blending multiple intensity tensors.

PARAMETER DESCRIPTION
intensities_list

A list of tensors with intensities to blend into the background.

TYPE: list of torch.Tensor

alpha

The blending parameter controlling the influence of intensities in the background.

TYPE: float DEFAULT: 0.4

RETURNS DESCRIPTION
Tensor

The synthesized background tensor.

Source code in SynthShapes/texturizing.py
def forward(self, intensities_list: list, alpha: float = 0.4
            ) -> torch.Tensor:
    """
    Synthesizes the background by applying the defined transformations
    and blending multiple intensity tensors.

    Parameters
    ----------
    intensities_list : list of torch.Tensor
        A list of tensors with intensities to blend into the background.
    alpha : float
        The blending parameter controlling the influence of intensities in
        the background.

    Returns
    -------
    torch.Tensor
        The synthesized background tensor.
    """
    # Initialize the parenchyma tensor with ones and apply the smooth
    # label map.
    # Assuming all tensors are on same device.
    device = intensities_list[0].device
    parenchyma = torch.ones_like(intensities_list[0]).to(device)
    parenchyma = self.random_smooth_label_map(parenchyma)
    parenchyma += 1

    # Apply the sequential transformations
    parenchyma = self.parenchyma_transform(parenchyma)

    # Blend each intensity tensor in the list with the parenchyma
    for intensities in intensities_list:
        parenchyma = self.blender(
            foreground=intensities,
            background=parenchyma,
            mask=(intensities > 0).bool(),
            alpha=alpha)

    # Apply final scaling and quantile transform
    parenchyma = self.final_scaler(parenchyma)
    parenchyma = self.quantile_transform(parenchyma)

    return parenchyma