Skip to content
Snippets Groups Projects

Draft: Notebook update

6 files
+ 66
75
Compare changes
  • Side-by-side
  • Inline

Files

%% Cell type:markdown id: tags:
## Local thickness notebook
%% Cell type:markdown id: tags:
This notebook shows an example of how to determine the **local thickness** of an object in either 2D and 3D using the `qim3d` library. The local thickness at a point within the object is defined as the radius of the largest circle (2D) or sphere (3D) that contains the point and is inside the object.
%% Cell type:markdown id: tags:
In the following, the local thickness is computed for three examples:
* **Example 1**: 2D image of blobs
* **Example 2**: 3D volume of shell
* **Example 3**: 3D volume of cement
The local thickness algorithm is applied by using the `qim3d.processing.local_thickness` function, which expects a binary image/volume. If the input is not already binary, then it will be binarized automatically using Otsu's thresholding method. The `qim3d.processing.local_thickness` function returns a 2D or 3D Numpy array representing the local thickness of the input image/volume.
%% Cell type:markdown id: tags:
#### **Example 1**: Local thickness of 2D image
This example uses a 2D image of blobs (256 x 256), which can be acquired from `qim3d.examples.blobs_256x256`.
The image is loaded using the `load` method from the `io` module. This is followed by a calculation of the local thicknes of the image.
%% Cell type:code id: tags:
``` python
import qim3d
# Load 2D image of blobs
img = qim3d.io.load('../../qim3d/examples/blobs_256x256.png', progress_bar=False)
# Load 2D grayscale image of blobs
img = qim3d.io.load('../../qim3d/examples/blobs_256x256.png', progress_bar=False, log_memory=False)
# Compute the local thickness of the blobs
img_lt = qim3d.processing.local_thickness(img, visualize=True)
img_lt = qim3d.processing.local_thickness(img, visualize=True, )
```
%% Output
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[1], line 3
1 import qim3d
2 # Load 2D image of blobs
----> 3 img = qim3d.io.load('../../qim3d/examples/blobs_256x256.png', progress_bar=False)
5 # Compute the local thickness of the blobs
6 img_lt = qim3d.processing.local_thickness(img, visualize=True)
File ~/qim3d/qim3d/io/_loading.py:841, in load(path, virtual_stack, dataset_name, return_metadata, contains, progress_bar, force_load, dim_order, **kwargs)
839 data = loader.load(path)
840 else:
--> 841 data = loader.load(path)
843 def log_memory_info(data):
844 mem = Memory()
File ~/qim3d/qim3d/io/_loading.py:730, in DataLoader.load(self, path)
728 suggestion = similar_paths[0] # Get the closest match
729 message = f"Invalid path. Did you mean '{suggestion}'?"
--> 730 raise ValueError(repr(message))
731 else:
732 raise ValueError("Invalid path")
ValueError: "Invalid path. Did you mean '../../qim3d/examples/fly_150x256x256.tif'?"
Input image is not binary. It will be binarized using Otsu's method with threshold: 69
%% Cell type:markdown id: tags:
#### **Example 2**: Local thickness of 3D volume
This example uses a 3D volume of a shell (225 x 128 x 128), which can be acquired from `qim3d.examples.shell_225x128x128`.
Likewise, the local thickness is calculated after. Since this image is 3D, there is a slider to evaluate the local thickness through the layers of the volume.
%% Cell type:code id: tags:
``` python
# Import 3D volume of shell
vol = qim3d.examples.shell_225x128x128
# Compute the local thickness of shell
vol_lt = qim3d.processing.local_thickness(vol, visualize=True, axis=0)
```
%% Output
Input image is not binary. It will be binarized using Otsu's method with threshold: 65
%% Cell type:markdown id: tags:
#### **Example 3**: Local thickness of (binary) 3D volume
This example uses a 3D volume of cement (128 x 128 x 128), which can be acquired from `qim3d.examples.cement_128x128x128`.
For the previous two examples, the original image/volume was passed directly to the `qim3d.processing.local_thickness` function, which automatically binarized the input prior to computing the local thickness.
For this example, the original volume will instead first be manually binarized with the `qim3d.detection.blobs` method (see details in the documentation for `qim3d.detection.blobs`). Then the binarized volume (i.e. mask) will be passed to the `qim3d.processing.local_thickness` function, which can then directly compute the local thickness.
%% Cell type:markdown id: tags:
**Importing, filtering and visualizing volume**
First the image is loaded and filtered.
%% Cell type:code id: tags:
``` python
# Import 3D volume of cement
vol = qim3d.examples.cement_128x128x128
# Visualize slices of the original cement volume
fig1 = qim3d.viz.slices_grid(vol, num_slices=5, display_figure=True)
# Apply Gaussian filter to the cement volume
vol_filtered = qim3d.filters.gaussian(vol, sigma=2)
# Visualize slices of the filtered cement volume
fig2 = qim3d.viz.slices_grid(vol_filtered, num_slices=5, display_figure=True)
```
%% Output
%% Cell type:markdown id: tags:
**Detecting blobs in volume, creating binary mask**
Now blobs are detected in the volume, generating both blobs and a binary mask. The mask is visualized to get a sense of the structure.
%% Cell type:code id: tags:
``` python
# Detect blobs in the volume
blobs, mask = qim3d.detection.blobs(
vol_filtered,
min_sigma=1,
max_sigma=8,
threshold=0.001,
overlap=0.1,
background="bright"
)
# Visualize the blob mask
qim3d.viz.slicer(mask)
```
%% Output
Bright background selected, volume will be inverted.
interactive(children=(IntSlider(value=64, description='Slice', max=127), Output()), layout=Layout(align_items=…
%% Cell type:markdown id: tags:
**Computing local thickness**
Lastly, the local thickness of the mask is calculated. Once again, since the volume is 3D, a slider allows for exploration of the local thickness.
%% Cell type:code id: tags:
``` python
# Compute the local thickness of cement (input: binary mask)
mask_lt = qim3d.processing.local_thickness(mask, visualize=True, axis=0)
```
%% Output
Loading