diff --git a/qim3d/detection/_common_detection_methods.py b/qim3d/detection/_common_detection_methods.py index 0a985d8543eacd858e968963b4a6c8491a011b4d..a79b636245438d5b80577f6b6bc84c5dc5d8cf38 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 e69b6cba63867c27cbedeba05999e201917f77b7..42ad89d1a250048966f38825171f53f5e8ef743f 100644 --- a/qim3d/features/_common_features_methods.py +++ b/qim3d/features/_common_features_methods.py @@ -25,8 +25,8 @@ def volume(obj, **mesh_kwargs) -> float: 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: @@ -34,10 +34,10 @@ def volume(obj, **mesh_kwargs) -> float: 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) ``` @@ -69,7 +69,7 @@ def area(obj, **mesh_kwargs) -> float: 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}") ``` @@ -78,16 +78,16 @@ def area(obj, **mesh_kwargs) -> float: 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 @@ -116,7 +116,7 @@ def sphericity(obj, **mesh_kwargs) -> float: 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: @@ -124,10 +124,10 @@ def sphericity(obj, **mesh_kwargs) -> float: 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" @@ -137,10 +137,10 @@ def sphericity(obj, **mesh_kwargs) -> float: """ 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 f2d421979259e1f676a54f5ec9512cf2cb6c364e..002b0d1b034f09799dfe2aa5986c88b59229253d 100644 --- a/qim3d/filters/_common_filter_methods.py +++ b/qim3d/filters/_common_filter_methods.py @@ -113,13 +113,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( @@ -134,7 +134,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) ```   @@ -182,7 +182,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 9d10df37e4efb270ac539e7ff4c3f22cf7cd6b06..dbba4e53492a444ddef429918a531ce33e370aed 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 ecabeb81135bdbf1d4b0f64c184be62af3dbbf65..09a42ea33d257abfc37ab12915bce0f436746512 100644 --- a/qim3d/gui/data_explorer.py +++ b/qim3d/gui/data_explorer.py @@ -40,9 +40,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/gui/layers2d.py b/qim3d/gui/layers2d.py index 780746a093be02faa74d2595538aa4208f2fc056..26d9639f889a4323460ccd94580385d57493e718 100644 --- a/qim3d/gui/layers2d.py +++ b/qim3d/gui/layers2d.py @@ -25,7 +25,8 @@ import numpy as np from .interface import BaseInterface # from qim3d.processing import layers2d as l2d -from qim3d.processing import overlay_rgb_images, segment_layers, get_lines +from qim3d.processing import segment_layers, get_lines +from qim3d.operations import overlay_rgb_images from qim3d.io import load from qim3d.viz._layers2d import image_with_lines diff --git a/qim3d/io/_convert.py b/qim3d/io/_convert.py index 4ab6c0a99e71eff51949309359dd42c1276f96dd..511039edc6161df2fa9830ca86cdce766ac9d3db 100644 --- a/qim3d/io/_convert.py +++ b/qim3d/io/_convert.py @@ -73,7 +73,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 fe42e410c120b5ab6efe77037d1071579add55de..adc956145ada8f05fc0d400fa2e4a33087054851 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 e5f2191e8f71fd276e9b9460d6dabf4c6e8d4995..1f8544857b846d36cc20324a02449df3fe998972 100644 --- a/qim3d/io/_loading.py +++ b/qim3d/io/_loading.py @@ -568,6 +568,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 d7721ee2a082a0a7db3f993c58ec9207eefcc5f4..dc16357240d5352471d0b295e4eba403d1628e39 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) ``` """ @@ -476,14 +476,14 @@ def save_mesh(filename, 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 535fcae886ce081c20c5bb01628341beba5163c3..ce837ff26aa320c89eb7542e679f4e3716dc6580 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 7c8a3b86d005e467c15a378e3216011cbf3ac60c..871f9f85aab51db797a4b429ab22cf4c7c7756dd 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, model): - 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 353d10bde5dc08f1b44044b9e482d2adf66a346d..9a4b1c85b62334decd965327585af24e1519b14a 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 1c14e16329dbf0a9cce14695c56f927c5b69d820..95e36928b92e60f2a6703835a004c664b97abed5 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 d91ef0a42f1ba8715793a674321219cbbf1d634b..b62a6c4661de6c9ff62b50fce7679789fb7515d8 100644 --- a/qim3d/processing/_layers.py +++ b/qim3d/processing/_layers.py @@ -33,7 +33,7 @@ def segment_layers(data:np.ndarray, inverted:bool = False, n_layers:int = 1, del 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 a7e877d6d01b51c1aa3af9d403dd5447b7a42f6d..8a3814ea04c0dd3144faa147d45a27c93d0ae8b5 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 f43f0dc216a1c49f2d35719e8a6a397340092107..105d913c5630aeaa0cc402e7451bde041b09d9bb 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 b3ece6636b062d24d2002405a08abb1726242f4f..4c3ec5f574f454fe04ab8765f52f5a703a697a27 100644 --- a/qim3d/utils/_doi.py +++ b/qim3d/utils/_doi.py @@ -56,13 +56,14 @@ def get_bibtex(doi): return _log_and_get_text(doi, header) -def cusom_header(doi, header): +def custom_header(doi, header): """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 a754ecb8840b889eed2b3132a98c1c8ea1e9f1f5..40d8d2a2a78fb1ecb7dcacbadae2fc4865225d5a 100644 --- a/qim3d/utils/_misc.py +++ b/qim3d/utils/_misc.py @@ -119,9 +119,10 @@ def sizeof(num, suffix="B"): 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 1c0ed56098696de99ccb1706d58321102317aeb8..21a7e8b541b9b30e92a5c30b822cb13564c35182 100644 --- a/qim3d/viz/_cc.py +++ b/qim3d/viz/_cc.py @@ -10,10 +10,10 @@ def plot_cc( max_cc_to_plot=32, overlay=None, crop=False, - show=True, - cmap: str = "viridis", - vmin: float = None, - vmax: float = None, + display_figure=True, + color_map: str = "viridis", + value_min: float = None, + value_max: float = None, **kwargs, ) -> list[plt.Figure]: """ @@ -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]) ```   @@ -75,21 +75,21 @@ def plot_cc( cc = connected_components.get_cc(component, crop=False) overlay_crop = np.where(cc == 0, 0, overlay) fig = qim3d.viz.slices_grid( - overlay_crop, show=show, cmap=cmap, vmin=vmin, vmax=vmax, **kwargs + overlay_crop, display_figure=display_figure, color_map=color_map, value_min=value_min, value_max=value_max, **kwargs ) 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 2198cd94a0eb703b7a3b95f15a4407397d642a06..3611c9a1466187d3901c581da9294fe647e512b7 100644 --- a/qim3d/viz/_data_exploration.py +++ b/qim3d/viz/_data_exploration.py @@ -77,7 +77,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) ```  """ @@ -473,6 +473,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 @@ -502,12 +505,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, @@ -519,7 +522,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, @@ -690,7 +693,7 @@ def chunks(zarr_path: str, **kwargs): 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 a0926105e4c01cb99ab708d1a42c395246411d3e..43843fb57f0399e24669d1e10d6124e04e2f81c7 100644 --- a/qim3d/viz/_detection.py +++ b/qim3d/viz/_detection.py @@ -25,16 +25,38 @@ def circles(blobs, vol, alpha=0.5, color="#ff9900", **kwargs): 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 b80e9556c22ce8d2fa19806b64f1cecc1f6be625..d2945b2f6dfae23cd22de3e9de6b544067d6b2eb 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 53a7f3a61178534e703c545287ddcd204d26b940..2ff66ae6fc1c87c7c168c4fd33eb09a5f4b391af 100644 --- a/qim3d/viz/_metrics.py +++ b/qim3d/viz/_metrics.py @@ -208,10 +208,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