Skip to content
Snippets Groups Projects

Synthetic image gen

Merged s204159 requested to merge synthetic_image_gen into main
1 file
+ 45
27
Compare changes
  • Side-by-side
  • Inline
+ 45
27
@@ -38,7 +38,9 @@ def overlay_rgb_images(background, foreground, alpha=0.5):
@@ -38,7 +38,9 @@ def overlay_rgb_images(background, foreground, alpha=0.5):
# Normalize if we have something
# Normalize if we have something
if np.max(foreground_max_projection) > 0:
if np.max(foreground_max_projection) > 0:
foreground_max_projection = foreground_max_projection / np.max(foreground_max_projection)
foreground_max_projection = foreground_max_projection / np.max(
 
foreground_max_projection
 
)
composite = background * (1 - alpha) + foreground * alpha
composite = background * (1 - alpha) + foreground * alpha
composite = np.clip(composite, 0, 255).astype("uint8")
composite = np.clip(composite, 0, 255).astype("uint8")
@@ -49,27 +51,42 @@ def overlay_rgb_images(background, foreground, alpha=0.5):
@@ -49,27 +51,42 @@ def overlay_rgb_images(background, foreground, alpha=0.5):
return composite.astype("uint8")
return composite.astype("uint8")
def generate_volume(final_shape=(128,128,128), scale=0.05, order=1, max_value=255, threshold=0.5, gamma=1.0, dtype="uint8", base_shape=(128,128,128)):
def generate_volume(
"""Generate a synthetic volume with custom structures.
base_shape=(128, 128, 128),
 
final_shape=(128, 128, 128),
 
noise_scale=0.05,
 
order=1,
 
gamma=1.0,
 
max_value=255,
 
threshold=0.5,
 
dtype="uint8",
 
):
 
"""
 
Generate a 3D volume with Perlin noise, spherical gradient, and optional scaling and gamma correction.
Args:
Args:
shape (tuple): The shape of the volume in (x, y, z) dimensions.
base_shape (tuple, optional): Shape of the initial volume to generate. Defaults to (128, 128, 128).
dtype (str): The data type of the volume.
final_shape (tuple, optional): Desired shape of the final volume. Defaults to (128, 128, 128).
order (int): The order of interpolation for zooming. (Lower is faster)
noise_scale (float, optional): Scale factor for Perlin noise. Defaults to 0.05.
 
order (int, optional): Order of the spline interpolation used in resizing. Defaults to 1.
 
gamma (float, optional): Gamma correction factor. Defaults to 1.0.
 
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.
 
dtype (str, optional): Desired data type of the output volume. Defaults to "uint8".
Returns:
Returns:
numpy.ndarray: The synthetic volume.
numpy.ndarray: Generated 3D volume with specified parameters.
Raises:
Raises:
ValueError: If the shape is not a tuple or the dtype is not a valid data type.
ValueError: If `final_shape` is not a tuple or does not have three elements.
 
ValueError: If `dtype` is not a valid numpy number type.
Note:
Example:
- The function generates a small volume and scales it up using scipy.ndimage.zoom.
import qim3d
- It uses the Perlin noise function from the noise library to generate custom structures.
vol = qim3d.utils.generate_volume()
- The generated volume is not binary and can be used to test visualization tools.
qim3d.viz.slices(vol, vmin=0, vmax=255)
- The shape parameter should be a tuple in the format (x, y, z).
- The dtype parameter should be a valid numpy data type.
"""
"""
 
if not isinstance(final_shape, tuple) or len(final_shape) != 3:
if not isinstance(final_shape, tuple) or len(final_shape) != 3:
raise ValueError("Size must be a tuple")
raise ValueError("Size must be a tuple")
if not np.issubdtype(dtype, np.number):
if not np.issubdtype(dtype, np.number):
@@ -77,25 +94,25 @@ def generate_volume(final_shape=(128,128,128), scale=0.05, order=1, max_value=25
@@ -77,25 +94,25 @@ def generate_volume(final_shape=(128,128,128), scale=0.05, order=1, max_value=25
# Define the dimensions of the shape for generating Perlin noise
# Define the dimensions of the shape for generating Perlin noise
# Initialize the 3D array for the shape
# Initialize the 3D array for the shape
volume = np.empty((base_shape[0], base_shape[1], base_shape[2]),dtype=np.float32)
volume = np.empty((base_shape[0], base_shape[1], base_shape[2]), dtype=np.float32)
# Fill the 3D array with values from the Perlin noise function
# Fill the 3D array with values from the Perlin noise function
for i in range(base_shape[0]):
for i in range(base_shape[0]):
for j in range(base_shape[1]):
for j in range(base_shape[1]):
for k in range(base_shape[2]):
for k in range(base_shape[2]):
# Calculate the distance from the center of the shape
# Calculate the distance from the center of the shape
dist = np.sqrt((i-base_shape[0]/2)**2+(j-base_shape[1]/2)**2+(k-base_shape[2]/2)**2) / np.sqrt(3*((base_shape[0]/2)**2))
dist = np.sqrt(
 
(i - base_shape[0] / 2) ** 2
 
+ (j - base_shape[1] / 2) ** 2
 
+ (k - base_shape[2] / 2) ** 2
 
) / np.sqrt(3 * ((base_shape[0] / 2) ** 2))
# Generate Perlin noise and adjust the values based on the distance from the center
# Generate Perlin noise and adjust the values based on the distance from the center
# This creates a spherical shape with noise
# This creates a spherical shape with noise
volume[i][j][k] = (1+pnoise3(i * scale,
volume[i][j][k] = (1 + pnoise3(i * noise_scale, j * noise_scale, k * noise_scale)) * (
j * scale,
1 - dist
k * scale) ) * (1-dist)
)
# Normalize
# Normalize
volume = (volume - np.min(volume)) / (np.max(volume) - np.min(volume))
volume = (volume - np.min(volume)) / (np.max(volume) - np.min(volume))
@@ -106,13 +123,14 @@ def generate_volume(final_shape=(128,128,128), scale=0.05, order=1, max_value=25
@@ -106,13 +123,14 @@ def generate_volume(final_shape=(128,128,128), scale=0.05, order=1, max_value=25
volume = volume * max_value
volume = volume * max_value
# clip the low values of the volume to create a coherent volume
# clip the low values of the volume to create a coherent volume
volume[volume < threshold*max_value] = 0
volume[volume < threshold * max_value] = 0
# Clip high values
# Clip high values
volume[volume > max_value] = max_value
volume[volume > max_value] = max_value
# Scale up the volume of volume to size
# Scale up the volume of volume to size
volume = scipy.ndimage.zoom(volume, np.array(final_shape)/np.array(base_shape), order=order)
volume = scipy.ndimage.zoom(
volume, np.array(final_shape) / np.array(base_shape), order=order
 
)
return volume.astype(dtype)
return volume.astype(dtype)
\ No newline at end of file
Loading