diff --git a/qim3d/detection/_common_detection_methods.py b/qim3d/detection/_common_detection_methods.py index 131ec1e45e40ebcd15c83de260938bcdbd360c59..9ed4833442ef103035c5d376aee8ec178218200a 100644 --- a/qim3d/detection/_common_detection_methods.py +++ b/qim3d/detection/_common_detection_methods.py @@ -37,13 +37,14 @@ def blobs( Example: ```python import qim3d + import qim3d.detection # Get data vol = qim3d.examples.cement_128x128x128 - vol_blurred = qim3d.processing.gaussian(vol, sigma=2) + vol_blurred = qim3d.filters.gaussian(vol, sigma=2) # Detect blobs, and get binary mask - blobs, mask = qim3d.processing.blob_detection( + blobs, mask = qim3d.detection.blobs( vol_blurred, min_sigma=1, max_sigma=8, @@ -55,7 +56,7 @@ def blobs( # Visualize detected blobs qim3d.viz.circles(blobs, vol, alpha=0.8, color='blue') ``` -  +  ```python # Visualize binary mask diff --git a/qim3d/features/_common_features_methods.py b/qim3d/features/_common_features_methods.py index 63838ef17634d493fd5de0ec4e806d4568200918..574d8b899db2a89e785403f3c01789c864c891e7 100644 --- a/qim3d/features/_common_features_methods.py +++ b/qim3d/features/_common_features_methods.py @@ -27,8 +27,8 @@ def volume(obj: np.ndarray|trimesh.Trimesh, mesh = qim3d.io.load_mesh('path/to/mesh.obj') # Compute the volume of the mesh - volume = qim3d.processing.volume(mesh) - print('Volume:', volume) + vol = qim3d.features.volume(mesh) + print('Volume:', vol) ``` Compute volume from a np.ndarray: @@ -36,10 +36,10 @@ def volume(obj: np.ndarray|trimesh.Trimesh, import qim3d # Generate a 3D blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Compute the volume of the blob - volume = qim3d.processing.volume(synthetic_blob, level=0.5) + volume = qim3d.features.volume(synthetic_blob, level=0.5) print('Volume:', volume) ``` @@ -73,7 +73,7 @@ def area(obj: np.ndarray|trimesh.Trimesh, mesh = qim3d.io.load_mesh('path/to/mesh.obj') # Compute the surface area of the mesh - area = qim3d.processing.area(mesh) + area = qim3d.features.area(mesh) print(f"Area: {area}") ``` @@ -82,16 +82,16 @@ def area(obj: np.ndarray|trimesh.Trimesh, import qim3d # Generate a 3D blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Compute the surface area of the blob - volume = qim3d.processing.area(synthetic_blob, level=0.5) + volume = qim3d.features.area(synthetic_blob, level=0.5) print('Area:', volume) ``` """ if isinstance(obj, np.ndarray): log.info("Converting volume to mesh.") - obj = qim3d.processing.create_mesh(obj, **mesh_kwargs) + obj = qim3d.mesh.from_volume(obj, **mesh_kwargs) return obj.area @@ -122,7 +122,7 @@ def sphericity(obj: np.ndarray|trimesh.Trimesh, mesh = qim3d.io.load_mesh('path/to/mesh.obj') # Compute the sphericity of the mesh - sphericity = qim3d.processing.sphericity(mesh) + sphericity = qim3d.features.sphericity(mesh) ``` Compute sphericity from a np.ndarray: @@ -130,10 +130,10 @@ def sphericity(obj: np.ndarray|trimesh.Trimesh, import qim3d # Generate a 3D blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Compute the sphericity of the blob - sphericity = qim3d.processing.sphericity(synthetic_blob, level=0.5) + sphericity = qim3d.features.sphericity(synthetic_blob, level=0.5) ``` !!! info "Limitations due to pixelation" @@ -143,10 +143,10 @@ def sphericity(obj: np.ndarray|trimesh.Trimesh, """ if isinstance(obj, np.ndarray): log.info("Converting volume to mesh.") - obj = qim3d.processing.create_mesh(obj, **mesh_kwargs) + obj = qim3d.mesh.from_volume(obj, **mesh_kwargs) - volume = qim3d.processing.volume(obj) - area = qim3d.processing.area(obj) + volume = qim3d.features.volume(obj) + area = qim3d.features.area(obj) if area == 0: log.warning("Surface area is zero, sphericity is undefined.") diff --git a/qim3d/filters/_common_filter_methods.py b/qim3d/filters/_common_filter_methods.py index 59b0be1291ff2f3480b44dc3df524c9794a2c6ed..ddd663fa0cb68e30ba92d9563fc95d7f3b9fdbfb 100644 --- a/qim3d/filters/_common_filter_methods.py +++ b/qim3d/filters/_common_filter_methods.py @@ -116,13 +116,13 @@ class Pipeline: Example: ```python import qim3d - from qim3d.processing import Pipeline, Median, Gaussian, Maximum, Minimum + from qim3d.filters import Pipeline, Median, Gaussian, Maximum, Minimum # Get data vol = qim3d.examples.fly_150x256x256 # Show original - qim3d.viz.slices_grid(vol, axis=0, show=True) + fig1 = qim3d.viz.slices_grid(vol, num_slices=5, display_figure=True) # Create filter pipeline pipeline = Pipeline( @@ -137,7 +137,7 @@ class Pipeline: vol_filtered = pipeline(vol) # Show filtered - qim3d.viz.slices_grid(vol_filtered, axis=0) + fig2 = qim3d.viz.slices_grid(vol_filtered, num_slices=5, display_figure=True) ```   @@ -185,7 +185,7 @@ class Pipeline: Example: ```python import qim3d - from qim3d.processing import Pipeline, Maximum, Median + from qim3d.filters import Pipeline, Maximum, Median # Create filter pipeline pipeline = Pipeline( diff --git a/qim3d/generate/_aggregators.py b/qim3d/generate/_aggregators.py index 262b047ef703ef379432f4a18441617cf5475613..5635e6c3a8249da68bc868d1f5e3c220ef5c9c8a 100644 --- a/qim3d/generate/_aggregators.py +++ b/qim3d/generate/_aggregators.py @@ -189,10 +189,10 @@ def noise_object_collection( # Generate synthetic collection of objects num_objects = 15 - synthetic_collection, labels = qim3d.generate.collection(num_objects = num_objects) + synthetic_collection, labels = qim3d.generate.noise_object_collection(num_objects = num_objects) # Visualize synthetic collection - qim3d.viz.vol(synthetic_collection) + qim3d.viz.volumetric(synthetic_collection) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_collection_default.html" width="100%" height="500" frameborder="0"></iframe> @@ -203,8 +203,8 @@ def noise_object_collection( ```python # Visualize labels - cmap = qim3d.viz.colormaps.objects(nlabels=num_objects) - qim3d.viz.slicer(labels, cmap=cmap, vmax=num_objects) + cmap = qim3d.viz.colormaps.segmentation(num_labels=num_objects) + qim3d.viz.slicer(labels, color_map=cmap, value_max=num_objects) ```  @@ -233,7 +233,7 @@ def noise_object_collection( import qim3d # Generate synthetic collection of cylindrical structures - vol, labels = qim3d.generate.collection(num_objects = 40, + vol, labels = qim3d.generate.noise_object_collection(num_objects = 40, collection_shape = (300, 150, 150), min_shape = (280, 10, 10), max_shape = (290, 15, 15), @@ -248,14 +248,14 @@ def noise_object_collection( ) # Visualize synthetic collection - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_collection_cylinder.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(vol, n_slices=15) + qim3d.viz.slices_grid(vol, num_slices=15) ```  @@ -264,7 +264,7 @@ def noise_object_collection( import qim3d # Generate synthetic collection of tubular (hollow) structures - vol, labels = qim3d.generate.collection(num_objects = 10, + vol, labels = qim3d.generate.noise_object_collection(num_objects = 10, collection_shape = (200, 200, 200), min_shape = (180, 25, 25), max_shape = (190, 35, 35), @@ -279,13 +279,13 @@ def noise_object_collection( ) # Visualize synthetic collection - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_collection_tube.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(vol, n_slices=15, axis=1) + qim3d.viz.slices_grid(vol, num_slices=15, slice_axis=1) ```  """ diff --git a/qim3d/generate/_generators.py b/qim3d/generate/_generators.py index 78bf607bc5643a8b6570a29feac0f217059ff800..5cab885d803368e834b576bad1d5090216b7f253 100644 --- a/qim3d/generate/_generators.py +++ b/qim3d/generate/_generators.py @@ -43,16 +43,16 @@ def noise_object( import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Visualize 3D volume - qim3d.viz.vol(synthetic_blob) + qim3d.viz.volumetric(synthetic_blob) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_blob.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(synthetic_blob, vmin = 0, vmax = 255, n_slices = 15) + qim3d.viz.slices_grid(synthetic_blob, value_min = 0, value_max = 255, num_slices = 15) ```  @@ -61,7 +61,7 @@ def noise_object( import qim3d # Generate tubular synthetic blob - vol = qim3d.generate.blob(base_shape = (10, 300, 300), + vol = qim3d.generate.noise_object(base_shape = (10, 300, 300), final_shape = (100, 100, 100), noise_scale = 0.3, gamma = 2, @@ -70,13 +70,13 @@ def noise_object( ) # Visualize synthetic object - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_blob_cylinder.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(vol, n_slices=15, axis=1) + qim3d.viz.slices_grid(vol, num_slices=15, slice_axis=1) ```  @@ -85,7 +85,7 @@ def noise_object( import qim3d # Generate tubular synthetic blob - vol = qim3d.generate.blob(base_shape = (200, 100, 100), + vol = qim3d.generate.noise_object(base_shape = (200, 100, 100), final_shape = (400, 100, 100), noise_scale = 0.03, gamma = 0.12, @@ -94,13 +94,13 @@ def noise_object( ) # Visualize synthetic blob - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_blob_tube.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize - qim3d.viz.slices_grid(vol, n_slices=15) + qim3d.viz.slices_grid(vol, num_slices=15) ```  """ @@ -178,7 +178,7 @@ def noise_object( axis = np.argmax(volume.shape) # Fade along the dimension where the object is the largest target_max_normalized_distance = 1.4 # This value ensures that the object will become cylindrical - volume = qim3d.processing.operations.fade_mask(volume, + volume = qim3d.operations.fade_mask(volume, geometry = geometry, axis = axis, target_max_normalized_distance = target_max_normalized_distance @@ -193,7 +193,7 @@ def noise_object( target_max_normalized_distance = 1.4 # This value ensures that the object will become cylindrical # Fade once for making the object cylindrical - volume = qim3d.processing.operations.fade_mask(volume, + volume = qim3d.operations.fade_mask(volume, geometry = geometry, axis = axis, decay_rate = decay_rate, @@ -202,7 +202,7 @@ def noise_object( ) # Fade again with invert = True for making the object a tube (i.e. with a hole in the middle) - volume = qim3d.processing.operations.fade_mask(volume, + volume = qim3d.operations.fade_mask(volume, geometry = geometry, axis = axis, decay_rate = decay_rate, diff --git a/qim3d/gui/data_explorer.py b/qim3d/gui/data_explorer.py index ee3ba16d5a90f3facbebc8580b906e52c745bc50..fb800ab225d4dbad88c48491b84145a2882fe01d 100644 --- a/qim3d/gui/data_explorer.py +++ b/qim3d/gui/data_explorer.py @@ -43,9 +43,9 @@ class Interface(BaseInterface): """ Parameters: ----------- - show_header (bool, optional): If true, prints starting info into terminal. Default is False verbose (bool, optional): If true, prints info during session into terminal. Defualt is False. figsize (int, optional): Sets the size of plots displaying the slices. Default is 8. + display_saturation_percentile (int, optional): Sets the display saturation percentile. Defaults to 99. """ super().__init__( title = "Data Explorer", diff --git a/qim3d/io/_convert.py b/qim3d/io/_convert.py index 0d776822689430b733dfa1467ecdff0b48d87bb1..026143581cafe72cb40861eab18cccb29ddec1f3 100644 --- a/qim3d/io/_convert.py +++ b/qim3d/io/_convert.py @@ -74,7 +74,6 @@ class Convert: Args: tif_path (str): path to the tiff file zarr_path (str): path to the zarr file - chunks (tuple, optional): chunk size for the zarr file. Defaults to (64, 64, 64). Returns: zarr.core.Array: zarr array containing the data from the tiff file diff --git a/qim3d/io/_downloader.py b/qim3d/io/_downloader.py index 18e36ca591ad2bf0859cc2b05f18d0033de3f8ee..1dff4f11b54fecec4fb6b2702031642cdab5cc87 100644 --- a/qim3d/io/_downloader.py +++ b/qim3d/io/_downloader.py @@ -52,7 +52,7 @@ class Downloader: downloader = qim3d.io.Downloader() data = downloader.Cowry_Shell.Cowry_DOWNSAMPLED(load_file=True) - qim3d.viz.orthogonal(data, cmap = "magma") + qim3d.viz.slicer_orthogonal(data, color_map="magma") ```  """ diff --git a/qim3d/io/_loading.py b/qim3d/io/_loading.py index e3d7d45bc220a04c0e96e4efd5fbb2f94cc3c99a..2eb2c773525b0f7bd3746b876bda96e1fc919948 100644 --- a/qim3d/io/_loading.py +++ b/qim3d/io/_loading.py @@ -570,6 +570,10 @@ class DataLoader: Args: path (str): Directory path + + returns: + numpy.ndarray, numpy.memmap or tuple: The loaded volume. + If 'self.return_metadata' is True, returns a tuple (volume, metadata). """ import pydicom diff --git a/qim3d/io/_saving.py b/qim3d/io/_saving.py index a7053c00fde4b7d4541b1a01286f18ad669e811d..eb6c39e521afdf25502ba7077edaac65d66230f0 100644 --- a/qim3d/io/_saving.py +++ b/qim3d/io/_saving.py @@ -7,7 +7,7 @@ Example: import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) qim3d.io.save("fly.tif", synthetic_blob) ``` @@ -17,7 +17,7 @@ Example: import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) qim3d.io.save("slices", synthetic_blob, basename="fly-slices", sliced_dim=0) ``` @@ -438,9 +438,9 @@ def save( import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + vol = qim3d.generate.noise_object(noise_scale = 0.015) - qim3d.io.save("blob.tif", synthetic_blob, replace=True) + qim3d.io.save("blob.tif", vol, replace=True) ``` Volumes can also be saved with one file per slice: @@ -448,9 +448,9 @@ def save( import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + vol = qim3d.generate.noise_object(noise_scale = 0.015) - qim3d.io.save("slices", synthetic_blob, basename="blob-slices", sliced_dim=0) + qim3d.io.save("slices", vol, basename="blob-slices", sliced_dim=0) ``` """ @@ -479,14 +479,14 @@ def save_mesh( ```python import qim3d - vol = qim3d.generate.blob(base_shape=(32, 32, 32), + vol = qim3d.generate.noise_object(base_shape=(32, 32, 32), final_shape=(32, 32, 32), noise_scale=0.05, order=1, gamma=1.0, max_value=255, threshold=0.5) - mesh = qim3d.processing.create_mesh(vol) + mesh = qim3d.mesh.from_volume(vol) qim3d.io.save_mesh("mesh.obj", mesh) ``` """ diff --git a/qim3d/mesh/_common_mesh_methods.py b/qim3d/mesh/_common_mesh_methods.py index 87cb9d8bfc792ca939d2e0afab00eff4510c2a91..d6f184dca6021a4d7f50da79d6381d4a1a38b4fd 100644 --- a/qim3d/mesh/_common_mesh_methods.py +++ b/qim3d/mesh/_common_mesh_methods.py @@ -31,7 +31,7 @@ def from_volume( Example: ```python import qim3d - vol = qim3d.generate.blob(base_shape=(128,128,128), + vol = qim3d.generate.noise_object(base_shape=(128,128,128), final_shape=(128,128,128), noise_scale=0.03, order=1, @@ -40,7 +40,7 @@ def from_volume( threshold=0.5, dtype='uint8' ) - mesh = qim3d.processing.create_mesh(vol, step_size=3) + mesh = qim3d.mesh.from_volume(vol, step_size=3) qim3d.viz.mesh(mesh.vertices, mesh.faces) ``` <iframe src="https://platform.qim.dk/k3d/mesh_visualization.html" width="100%" height="500" frameborder="0"></iframe> diff --git a/qim3d/ml/_ml_utils.py b/qim3d/ml/_ml_utils.py index f46a7481fe93cd299eb43566bd947c7ea3355daf..5930926693dd2654fc1798c4d8ff41c564e90943 100644 --- a/qim3d/ml/_ml_utils.py +++ b/qim3d/ml/_ml_utils.py @@ -40,18 +40,21 @@ def train_model( val_loss (dict): Dictionary with average losses and batch losses for validation loop. Example: + import qim3d + from qim3d.ml import train_model + # defining the model. - model = qim3d.utils.UNet() + model = qim3d.ml.UNet() # choosing the hyperparameters - hyperparameters = qim3d.utils.hyperparameters(model) + hyperparameters = qim3d.ml.models.Hyperparameters(model) # DataLoaders train_loader = MyTrainLoader() val_loader = MyValLoader() # training the model. - train_loss,val_loss = train_model(model, hyperparameters, train_loader, val_loader) + train_loss,val_loss = qim3d.ml.train_model(model, hyperparameters, train_loader, val_loader) """ params_dict = hyperparameters() n_epochs = params_dict["n_epochs"] @@ -186,9 +189,10 @@ def inference(data: torch.utils.data.Dataset, model: torch.nn.Module) -> tuple[t - The function does not assume the model is already in evaluation mode (model.eval()). Example: + import qim3d dataset = MySegmentationDataset() model = MySegmentationModel() - inference(data,model) + qim3d.ml.inference(data,model) """ # Get device diff --git a/qim3d/ml/models/_unet.py b/qim3d/ml/models/_unet.py index 27ee78a4009b235253662c8af50c76baca4870f4..f27f741041bf497121818b8b98d0ac911a791b24 100644 --- a/qim3d/ml/models/_unet.py +++ b/qim3d/ml/models/_unet.py @@ -104,10 +104,10 @@ class Hyperparameters: # This examples shows how to define a UNet model and its hyperparameters. # Defining the model - my_model = qim3d.models.UNet(size='medium') + my_model = qim3d.ml.UNet(size='medium') # Choosing the hyperparameters - hyperparams = qim3d.models.Hyperparameters(model=my_model, n_epochs=20, learning_rate=0.001) + hyperparams = qim3d.ml.Hyperparameters(model=my_model, n_epochs=20, learning_rate=0.001) params_dict = hyperparams() # Get the hyperparameters optimizer = params_dict['optimizer'] diff --git a/qim3d/operations/_common_operations_methods.py b/qim3d/operations/_common_operations_methods.py index 5975c30ea3c43f95995559597c8a61f02790809a..680f2d1d6d0edc84c11c961e490dcb663792c95b 100644 --- a/qim3d/operations/_common_operations_methods.py +++ b/qim3d/operations/_common_operations_methods.py @@ -30,15 +30,15 @@ def remove_background( import qim3d vol = qim3d.examples.cement_128x128x128 - qim3d.viz.slices_grid(vol, vmin=0, vmax=255) + fig1 = qim3d.viz.slices_grid(vol, value_min=0, value_max=255, num_slices=5, display_figure=True) ```  ```python - vol_filtered = qim3d.processing.operations.remove_background(vol, + vol_filtered = qim3d.operations.remove_background(vol, min_object_radius=3, background="bright") - qim3d.viz.slices_grid(vol_filtered, vmin=0, vmax=255) + fig2 = qim3d.viz.slices_grid(vol_filtered, value_min=0, value_max=255, num_slices=5, display_figure=True) ```  """ @@ -81,15 +81,16 @@ def fade_mask( Example: ```python import qim3d - qim3d.viz.vol(vol) + vol = qim3d.io.load('yourVolume.tif') + qim3d.viz.volumetric(vol) ``` Image before edge fading has visible artifacts from the support. Which obscures the object of interest.  ```python import qim3d - vol_faded = qim3d.processing.operations.edge_fade(vol, decay_rate=4, ratio=0.45, geometric='cylindrical') - qim3d.viz.vol(vol_faded) + vol_faded = qim3d.operations.fade_mask(vol, decay_rate=4, ratio=0.45, geometric='cylindrical') + qim3d.viz.volumetrics(vol_faded) ``` Afterwards the artifacts are faded out, making the object of interest more visible for visualization purposes.  diff --git a/qim3d/processing/_layers.py b/qim3d/processing/_layers.py index 306a12844f8be1356ff1d48f4cd832532d6acb75..65fdbbd61cfe1c1b8bb02d2ea793bf8ec73c5ce8 100644 --- a/qim3d/processing/_layers.py +++ b/qim3d/processing/_layers.py @@ -40,7 +40,7 @@ def segment_layers(data: np.ndarray, layers = qim3d.processing.segment_layers(layers_image, n_layers = 2) layer_lines = qim3d.processing.get_lines(layers) - from matplotlib import pyplot as plt + import matplotlib.pyplot as plt plt.imshow(layers_image, cmap='gray') plt.axis('off') diff --git a/qim3d/processing/_local_thickness.py b/qim3d/processing/_local_thickness.py index 947f8865cfdbdbed4438d0f1e416498502de0e4a..5396fedb6f6875e55a4db6de7ceeafa72392891b 100644 --- a/qim3d/processing/_local_thickness.py +++ b/qim3d/processing/_local_thickness.py @@ -50,7 +50,7 @@ def local_thickness( # Generate synthetic collection of blobs num_objects = 15 - synthetic_collection, labels = qim3d.generate.collection(num_objects = num_objects) + synthetic_collection, labels = qim3d.generate.noise_object_collection(num_objects = num_objects) # Extract one slice to show that localthickness works on 2D slices too slice = synthetic_collection[:,:,50] diff --git a/qim3d/segmentation/_common_segmentation_methods.py b/qim3d/segmentation/_common_segmentation_methods.py index ba4f231d16a43b5718328e817905e8df28e7c551..979ab6fd863841ff8d95b999f9832f1ed6fa4ceb 100644 --- a/qim3d/segmentation/_common_segmentation_methods.py +++ b/qim3d/segmentation/_common_segmentation_methods.py @@ -24,17 +24,17 @@ def watershed(bin_vol: np.ndarray, min_distance: int = 5) -> tuple[np.ndarray, i import qim3d vol = qim3d.examples.cement_128x128x128 - binary = qim3d.processing.filters.gaussian(vol, sigma = 2)<60 + bin_vol = qim3d.filters.gaussian(vol, sigma = 2)<60 - qim3d.viz.slices_grid(binary, axis=1) + fig1 = qim3d.viz.slices_grid(bin_vol, slice_axis=1, display_figure=True) ```  ```python - labeled_volume, num_labels = qim3d.processing.operations.watershed(binary) + labeled_volume, num_labels = qim3d.segmentation.watershed(bin_vol) - cmap = qim3d.viz.colormaps.objects(num_labels) - qim3d.viz.slices_grid(labeled_volume, axis = 1, cmap = cmap) + cmap = qim3d.viz.colormaps.segmentation(num_labels) + fig2 = qim3d.viz.slices_grid(labeled_volume, slice_axis=1, color_map=cmap, display_figure=True) ```  diff --git a/qim3d/segmentation/_connected_components.py b/qim3d/segmentation/_connected_components.py index 45725feec526e0a31de67a0737f99d6f955d2333..190266d4f6c39954e26f6f421dec893a69319a13 100644 --- a/qim3d/segmentation/_connected_components.py +++ b/qim3d/segmentation/_connected_components.py @@ -83,7 +83,7 @@ def get_3d_cc(image: np.ndarray) -> CC: ```python import qim3d vol = qim3d.examples.cement_128x128x128[50:150]<60 - cc = qim3d.processing.get_3d_cc(vol) + cc = qim3d.segmentation.get_3d_cc(vol) ``` """ connected_components, num_connected_components = label(image) diff --git a/qim3d/utils/__init__.py b/qim3d/utils/__init__.py index 0c7d5b30a7b3daf15b80d5995e6d0e4a1f18e5cc..c996bbb6f3608b3b9d56f24ac100cb5949b035cd 100644 --- a/qim3d/utils/__init__.py +++ b/qim3d/utils/__init__.py @@ -1,4 +1,4 @@ -from . import _doi +from ._doi import * from ._system import Memory from ._misc import ( diff --git a/qim3d/utils/_doi.py b/qim3d/utils/_doi.py index 02095f335610b266b0dd57088787eab2697190fd..1859ed53eeb7c5e0ffa62da3066868b1de73053a 100644 --- a/qim3d/utils/_doi.py +++ b/qim3d/utils/_doi.py @@ -59,10 +59,11 @@ def get_bibtex(doi: str): def custom_header(doi: str, header: str) -> str: """Allows a custom header to be passed - For example: + Example: + import qim3d doi = "https://doi.org/10.1101/2022.11.08.515664" header = {"Accept": "text/bibliography"} - response = qim3d.utils.doi.cusom_header(doi, header) + custom_header = qim3d.utils.custom_header(doi, header) """ return _log_and_get_text(doi, header) diff --git a/qim3d/utils/_misc.py b/qim3d/utils/_misc.py index 3d8660b445a65577ef3b4c7d16af613b44785aac..8ccc2258abee3b23395bd90af1fc4728cf22418f 100644 --- a/qim3d/utils/_misc.py +++ b/qim3d/utils/_misc.py @@ -119,9 +119,10 @@ def sizeof(num: float, suffix: str = "B") -> str: Example: - >>> sizeof(1024) + >>> import qim3d + >>> qim3d.utils.sizeof(1024) '1.0 KB' - >>> sizeof(1234567890) + >>> qim3d.utils.sizeof(1234567890) '1.1 GB' """ for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]: diff --git a/qim3d/viz/_cc.py b/qim3d/viz/_cc.py index 083b53cbfd70007c83097bf241e6e4f53b37592b..875980be2b6e5d0ca284e9aabb6e32a6411d94ee 100644 --- a/qim3d/viz/_cc.py +++ b/qim3d/viz/_cc.py @@ -25,23 +25,23 @@ def plot_cc( max_cc_to_plot (int, optional): The maximum number of connected components to plot. Defaults to 32. overlay (optional): Overlay image. Defaults to None. crop (bool, optional): Whether to crop the image to the cc. Defaults to False. - show (bool, optional): Whether to show the figure. Defaults to True. - cmap (str, optional): Specifies the color map for the image. Defaults to "viridis". - vmin (float, optional): Together with vmax define the data range the colormap covers. By default colormap covers the full range. Defaults to None. - vmax (float, optional): Together with vmin define the data range the colormap covers. By default colormap covers the full range. Defaults to None + display_figure (bool, optional): Whether to show the figure. Defaults to True. + color_map (str, optional): Specifies the color map for the image. Defaults to "viridis". + value_min (float, optional): Together with vmax define the data range the colormap covers. By default colormap covers the full range. Defaults to None. + value_max (float, optional): Together with vmin define the data range the colormap covers. By default colormap covers the full range. Defaults to None **kwargs: Additional keyword arguments to pass to `qim3d.viz.slices_grid`. Returns: - figs (list[plt.Figure]): List of figures, if `show=False`. + figs (list[plt.Figure]): List of figures, if `display_figure=False`. Example: ```python import qim3d vol = qim3d.examples.cement_128x128x128[50:150] vol_bin = vol<80 - cc = qim3d.processing.get_3d_cc(vol_bin) - qim3d.viz.plot_cc(cc, crop=True, show=True, overlay=None, n_slices=5, component_indexs=[4,6,7]) - qim3d.viz.plot_cc(cc, crop=True, show=True, overlay=vol, n_slices=5, component_indexs=[4,6,7]) + cc = qim3d.segmentation.get_3d_cc(vol_bin) + qim3d.viz.plot_cc(cc, crop=True, display_figure=True, overlay=None, num_slices=5, component_indexs=[4,6,7]) + qim3d.viz.plot_cc(cc, crop=True, display_figure=True, overlay=vol, num_slices=5, component_indexs=[4,6,7]) ```   @@ -79,17 +79,17 @@ def plot_cc( ) else: # assigns discrete color map to each connected component if not given - if "cmap" not in kwargs: - kwargs["cmap"] = qim3d.viz.colormaps.segmentation(len(component_indexs)) + if "color_map" not in kwargs: + kwargs["color_map"] = qim3d.viz.colormaps.segmentation(len(component_indexs)) # Plot the connected component without overlay fig = qim3d.viz.slices_grid( - connected_components.get_cc(component, crop=crop), show=show, **kwargs + connected_components.get_cc(component, crop=crop), display_figure=display_figure, **kwargs ) figs.append(fig) - if not show: + if not display_figure: return figs return diff --git a/qim3d/viz/_data_exploration.py b/qim3d/viz/_data_exploration.py index e03f08526b176ff61d878cf11876473c7a36577c..a578edd5c4e46ba13210a117fe1f2acbdd3d740a 100644 --- a/qim3d/viz/_data_exploration.py +++ b/qim3d/viz/_data_exploration.py @@ -79,7 +79,7 @@ def slices_grid( import qim3d vol = qim3d.examples.shell_225x128x128 - qim3d.viz.slices_grid_grid(vol, num_slices=15) + qim3d.viz.slices_grid(vol, num_slices=15) ```  """ @@ -475,6 +475,9 @@ def fade_mask( value_min (float, optional): Together with value_max define the data range the colormap covers. By default colormap covers the full range. Defaults to None. value_max (float, optional): Together with value_min define the data range the colormap covers. By default colormap covers the full range. Defaults to None + Returns: + slicer_obj (widgets.HBox): The interactive widget for visualizing fade mask on slices of a 3D volume. + Example: ```python import qim3d @@ -504,12 +507,12 @@ def fade_mask( ) axes[0].imshow( - slice_img, cmap=color_map, value_min=new_value_min, value_max=new_value_max + slice_img, cmap=color_map, vmin=new_value_min, vmax=new_value_max ) axes[0].set_title("Original") axes[0].axis("off") - mask = qim3d.processing.operations.fade_mask( + mask = qim3d.operations.fade_mask( np.ones_like(volume), decay_rate=decay_rate, ratio=ratio, @@ -521,7 +524,7 @@ def fade_mask( axes[1].set_title("Mask") axes[1].axis("off") - masked_volume = qim3d.processing.operations.fade_mask( + masked_volume = qim3d.operations.fade_mask( volume, decay_rate=decay_rate, ratio=ratio, @@ -692,7 +695,7 @@ def chunks(zarr_path: str, **kwargs)-> widgets.interactive: viz_widget = widgets.Output() with viz_widget: viz_widget.clear_output(wait=True) - fig = qim3d.viz.slices_grid_grid(chunk, **kwargs) + fig = qim3d.viz.slices_grid(chunk, **kwargs) display(fig) elif visualization_method == "volume": viz_widget = widgets.Output() diff --git a/qim3d/viz/_detection.py b/qim3d/viz/_detection.py index 14ba42bff77169a2a18f24591b92e353e479d32c..d10fc32cd7c5dd296166f575b74bb994806c1ec9 100644 --- a/qim3d/viz/_detection.py +++ b/qim3d/viz/_detection.py @@ -25,16 +25,38 @@ def circles(blobs: tuple[float,float,float,float], vol: np.ndarray, alpha: float Returns: slicer_obj (ipywidgets.interactive): An interactive widget for visualizing the blobs. + Example: + ```python + import qim3d + import qim3d.detection + + # Get data + vol = qim3d.examples.cement_128x128x128 + + # Detect blobs, and get binary mask + blobs, _ = qim3d.detection.blobs( + vol, + min_sigma=1, + max_sigma=8, + threshold=0.001, + overlap=0.1, + background="bright" + ) + + # Visualize detected blobs with circles method + qim3d.viz.circles(blobs, vol, alpha=0.8, color='blue') + ``` +  """ def _slicer(z_slice): clear_output(wait=True) fig = qim3d.viz.slices_grid( - vol, - n_slices=1, - position=z_slice, - cmap="gray", - show_position=False, + vol[z_slice:z_slice + 1], + num_slices=1, + color_map="gray", + display_figure=False, + display_positions=False, **kwargs ) # Add circles from deteced blobs diff --git a/qim3d/viz/_k3d.py b/qim3d/viz/_k3d.py index b45a138ccaf80682851dc53bff770a29e11c6172..f86ff9b847c09b32a2bc2e43a6ba54889ce6fcf2 100644 --- a/qim3d/viz/_k3d.py +++ b/qim3d/viz/_k3d.py @@ -35,7 +35,6 @@ def volumetric( Args: img (numpy.ndarray): The input 3D image data. It should be a 3D numpy array. aspectmode (str, optional): Determines the proportions of the scene's axes. Defaults to "data". - If `'data'`, the axes are drawn in proportion with the axes' ranges. If `'cube'`, the axes are drawn as a cube, regardless of the axes' ranges. show (bool, optional): If True, displays the visualization inline. Defaults to True. @@ -206,7 +205,7 @@ def mesh( ```python import qim3d - vol = qim3d.generate.blob(base_shape=(128,128,128), + vol = qim3d.generate.noise_object(base_shape=(128,128,128), final_shape=(128,128,128), noise_scale=0.03, order=1, @@ -215,7 +214,7 @@ def mesh( threshold=0.5, dtype='uint8' ) - mesh = qim3d.processing.create_mesh(vol, step_size=3) + mesh = qim3d.mesh.from_volume(vol, step_size=3) qim3d.viz.mesh(mesh.vertices, mesh.faces) ``` <iframe src="https://platform.qim.dk/k3d/mesh_visualization.html" width="100%" height="500" frameborder="0"></iframe> diff --git a/qim3d/viz/_local_thickness.py b/qim3d/viz/_local_thickness.py index c07438eec0c6dfb06f72c80373d4698fbffec6bc..243dc36066bd1fd99e307f04b6e94bf17abf7a25 100644 --- a/qim3d/viz/_local_thickness.py +++ b/qim3d/viz/_local_thickness.py @@ -42,7 +42,7 @@ def local_thickness( ```python import qim3d - fly = qim3d.examples.fly_150x256x256 # 3D volume + fly = qim3d.examples.fly_150x256x256 lt_fly = qim3d.processing.local_thickness(fly) qim3d.viz.local_thickness(fly, lt_fly, axis=0) ``` diff --git a/qim3d/viz/_metrics.py b/qim3d/viz/_metrics.py index 16d7c7ce94bf427e82c20221d6226333f11b1bd5..f1f41785c4d94a8f156bfddceaf54dff6a4a27fa 100644 --- a/qim3d/viz/_metrics.py +++ b/qim3d/viz/_metrics.py @@ -215,10 +215,11 @@ def grid_pred( None Example: + import qim3d dataset = MySegmentationDataset() model = MySegmentationModel() - in_targ_preds = qim3d.utils.models.inference(dataset,model) - grid_pred(in_targ_preds, cmap_im='viridis', alpha=0.5) + in_targ_preds = qim3d.ml.inference(dataset,model) + qim3d.viz.grid_pred(in_targ_preds, cmap_im='viridis', alpha=0.5) """ import torch