Skip to content
Snippets Groups Projects

Fade synthetic objects

3 files
+ 90
22
Compare changes
  • Side-by-side
  • Inline

Files

+ 75
1
@@ -2,6 +2,8 @@ import numpy as np
import scipy.ndimage
from noise import pnoise3
import qim3d.processing
def blob(
base_shape: tuple = (128, 128, 128),
final_shape: tuple = (128, 128, 128),
@@ -11,6 +13,7 @@ def blob(
max_value: int = 255,
threshold: float = 0.5,
smooth_borders: bool = False,
object_shape: str = None,
dtype: str = "uint8",
) -> np.ndarray:
"""
@@ -25,6 +28,7 @@ def blob(
max_value (int, optional): Maximum value for the volume intensity. Defaults to 255.
threshold (float, optional): Threshold value for clipping low intensity values. Defaults to 0.5.
smooth_borders (bool, optional): Flag for automatic computation of the threshold value to ensure a blob with no straight edges. If True, the `threshold` parameter is ignored. Defaults to False.
object_shape (str, optional): Shape of the object to generate, either 'sphere', 'cylinder', or 'pipe'. Defaults to None.
dtype (str, optional): Desired data type of the output volume. Defaults to "uint8".
Returns:
@@ -115,4 +119,74 @@ def blob(
volume, np.array(final_shape) / np.array(base_shape), order=order
)
return volume.astype(dtype)
# Fade into a shape if specified
if object_shape == "sphere":
# Arguments for the fade_mask function
geometry = "spherical" # Fade in spherical geometry
target_max_normalized_distance = 1.35 # This value ensures that the object will become spherical
volume = qim3d.processing.operations.fade_mask(volume,
geometry = geometry,
target_max_normalized_distance = target_max_normalized_distance
)
elif object_shape == "cylinder":
# Arguments for the fade_mask function
geometry = "cylindrical" # Fade in cylindrical geometry
axis = np.argmax(final_shape) # Fade along the dimension where the object is the largest
target_max_normalized_distance = 1.35 # This value ensures that the object will become cylindrical
print(f"Before fades, volume is dtype: {volume.dtype}, max value: {np.max(volume)}, unique values: {np.unique(volume)}")
volume = qim3d.processing.operations.fade_mask(volume,
geometry = geometry,
axis = axis,
target_max_normalized_distance = target_max_normalized_distance
)
print(f"After one fade, volume is dtype: {volume.dtype}, max value: {np.max(volume)}, unique values: {np.unique(volume)}")
elif object_shape == "pipe":
# Arguments for the fade_mask function
geometry = "cylindrical" # Fade in cylindrical geometry
axis = np.argmax(final_shape) # Fade along the dimension where the object is the largest
target_max_normalized_distance = 1.35 # This value ensures that the object will become cylindrical
print(f"Before fade, volume is dtype: {volume.dtype}, max value: {np.max(volume)}, unique values: {np.unique(volume)}")
# Fade once for making the object cylindrical
volume = qim3d.processing.operations.fade_mask(volume,
geometry = geometry,
axis = axis,
target_max_normalized_distance = target_max_normalized_distance,
invert = False
)
print(f"First fade, volume is dtype: {volume.dtype}, max value: {np.max(volume)}, unique values: {np.unique(volume)}")
ratio = 0.3 # Ratio of the object that will be faded
decay_rate = 6 # Decay rate for the fade operation
# Fade again with invert = True for making the object a pipe (i.e. with a hole in the middle)
volume = qim3d.processing.operations.fade_mask(volume,
geometry = geometry,
axis = axis,
# ratio = ratio,
# decay_rate = decay_rate,
invert = True
)
print(f"Second fade, volume is dtype: {volume.dtype}, max value: {np.max(volume)}, unique values: {np.unique(volume)}")
# Convert to desired data type
volume = volume.astype(dtype)
print(f"Final volume is dtype: {volume.dtype}, max value: {np.max(volume)}, unique values: {np.unique(volume)}\n")
return volume
Loading