Image Processing¶
The voids.image sub-package provides utilities for segmented image processing,
connectivity analysis, and pore network extraction used in vug sensitivity studies.
Network Extraction¶
voids.image.network_extraction
¶
NetworkExtractionResult
dataclass
¶
Store outputs of an image-to-network extraction workflow.
Attributes:
| Name | Type | Description |
|---|---|---|
image |
ndarray
|
Input phase image used for extraction. |
voxel_size |
float
|
Physical voxel edge length. |
axis_lengths |
dict[str, float]
|
Sample lengths by axis. |
axis_areas |
dict[str, float]
|
Cross-sectional areas normal to each axis. |
flow_axis |
str
|
Axis used for spanning subnetwork pruning. |
network_dict |
dict[str, object]
|
Intermediate extracted network mapping before conversion to
:class: |
sample |
SampleGeometry
|
Sample geometry attached to the network. |
provenance |
Provenance
|
Extraction provenance metadata. |
net_full |
Network
|
Full imported network before spanning pruning. |
net |
Network
|
Axis-spanning subnetwork. |
pore_indices |
ndarray
|
Indices of retained pores in |
throat_mask |
ndarray
|
Mask of retained throats in |
backend |
str
|
Extraction backend identifier (currently |
backend_version |
str | None
|
Backend version string when available. |
Source code in src/voids/image/network_extraction.py
infer_sample_axes
¶
Infer per-axis counts, lengths, areas, and the longest flow axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shape
|
tuple[int, ...]
|
Image shape in voxel counts. |
required |
voxel_size
|
float
|
Edge length of one voxel in the target length unit. |
required |
axis_names
|
tuple[str, ...]
|
Axis labels mapped onto the image shape. |
('x', 'y', 'z')
|
Returns:
| Type | Description |
|---|---|
tuple
|
|
Source code in src/voids/image/network_extraction.py
extract_spanning_pore_network
¶
extract_spanning_pore_network(
phases,
*,
voxel_size,
flow_axis=None,
length_unit="m",
pressure_unit="Pa",
extraction_kwargs=None,
provenance_notes=None,
strict=True,
geometry_repairs="imperial_export",
repair_seed=0,
)
Extract, import, and prune an axis-spanning pore network from an image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
phases
|
ndarray
|
Binary or integer-labeled phase image where nonzero values are active phases passed to the extraction backend. |
required |
voxel_size
|
float
|
Edge length of one voxel in the declared |
required |
flow_axis
|
str | None
|
Requested spanning axis. When omitted, the longest image axis is used. |
None
|
length_unit
|
str
|
Units stored in resulting :class: |
'm'
|
pressure_unit
|
str
|
Units stored in resulting :class: |
'm'
|
extraction_kwargs
|
dict[str, object] | None
|
Keyword arguments forwarded to the extraction backend call. |
None
|
provenance_notes
|
dict[str, object] | None
|
Optional extra provenance metadata attached to the resulting network. |
None
|
strict
|
bool
|
Forwarded to :func: |
True
|
geometry_repairs
|
str | None
|
Optional importer preprocessing mode. The default
|
'imperial_export'
|
repair_seed
|
int | None
|
Seed for any stochastic repair branch when |
0
|
Returns:
| Type | Description |
|---|---|
NetworkExtractionResult
|
Full and pruned networks together with intermediate metadata. |
Notes
Current implementation uses PoreSpy's snow2 backend and normalizes
accepted return styles into a standard network mapping before import.
Source code in src/voids/image/network_extraction.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | |
Segmentation¶
voids.image.segmentation
¶
VolumeCropResult
dataclass
¶
Store cylindrical-support cropping outputs from a grayscale volume.
Attributes:
| Name | Type | Description |
|---|---|---|
raw |
ndarray
|
Original grayscale volume as float array. |
specimen_mask |
ndarray
|
Slice-wise support mask after hole filling. |
common_mask |
ndarray
|
Per-pixel intersection of support masks over all slices. |
crop_bounds_yx |
tuple[int, int, int, int]
|
Maximal common rectangle bounds |
cropped |
ndarray
|
Cropped grayscale volume containing the common inscribed rectangle. |
Source code in src/voids/image/segmentation.py
GrayscaleSegmentationResult
dataclass
¶
Store grayscale preprocessing and binary segmentation outputs.
Attributes:
| Name | Type | Description |
|---|---|---|
crop |
VolumeCropResult
|
Cylindrical-support crop outputs. |
threshold |
float
|
Threshold used for binarization. |
binary |
ndarray
|
Segmented binary volume encoded as |
void_phase |
str
|
Phase polarity used for thresholding ( |
threshold_method |
str
|
Automatic method used when threshold was not explicitly supplied. |
Source code in src/voids/image/segmentation.py
largest_true_rectangle
¶
Return maximal-area axis-aligned rectangle fully contained in a mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mask2d
|
ndarray
|
Two-dimensional boolean support mask. |
required |
Returns:
| Type | Description |
|---|---|
tuple[int, int, int, int]
|
Rectangle bounds |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/voids/image/segmentation.py
crop_nonzero_cylindrical_volume
¶
crop_nonzero_cylindrical_volume(
raw,
*,
background_value=0.0,
show_progress=False,
progress_desc=None,
)
Crop cylindrical specimen support to a common rectangular field of view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
ndarray
|
Raw 3D grayscale volume. |
required |
background_value
|
float
|
Voxels strictly above this value are interpreted as specimen support before hole filling. |
0.0
|
show_progress
|
bool
|
Whether to show progress bars for slice-wise operations. |
False
|
progress_desc
|
str | None
|
Optional progress description string. |
None
|
Returns:
| Type | Description |
|---|---|
VolumeCropResult
|
Structured crop result with masks, bounds, and cropped volume. |
Source code in src/voids/image/segmentation.py
binarize_grayscale_volume
¶
Segment grayscale volume into binary void/solid phases.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cropped
|
ndarray
|
Cropped 3D grayscale volume. |
required |
threshold
|
float | None
|
Explicit threshold; when omitted, an automatic threshold is computed. |
None
|
method
|
str
|
Automatic threshold method name. Supported values are |
'otsu'
|
void_phase
|
str
|
Which side of threshold corresponds to void: |
'dark'
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, float]
|
|
Source code in src/voids/image/segmentation.py
preprocess_grayscale_cylindrical_volume
¶
preprocess_grayscale_cylindrical_volume(
raw,
*,
background_value=0.0,
threshold=None,
threshold_method="otsu",
void_phase="dark",
show_progress=False,
progress_desc=None,
)
Run cylindrical crop and grayscale segmentation in one workflow call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
ndarray
|
Raw 3D grayscale specimen volume. |
required |
background_value
|
float
|
Background/support discriminator for cropping. |
0.0
|
threshold
|
float | None
|
Explicit segmentation threshold. |
None
|
threshold_method
|
str
|
Method used when |
'otsu'
|
void_phase
|
str
|
Phase polarity selector for thresholding. |
'dark'
|
show_progress
|
bool
|
Whether to request progress reporting. |
False
|
progress_desc
|
str | None
|
Optional progress message. |
None
|
Returns:
| Type | Description |
|---|---|
GrayscaleSegmentationResult
|
Crop metadata plus segmented binary volume. |
Source code in src/voids/image/segmentation.py
binarize_2d_with_voids
¶
Segment a 2D grayscale image using the same thresholding policy as 3D.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gray2d
|
ndarray
|
Two-dimensional grayscale image. |
required |
threshold
|
float | None
|
Explicit threshold value. |
None
|
method
|
str
|
Automatic threshold method when |
'otsu'
|
void_phase
|
str
|
Which side of threshold corresponds to void. |
'dark'
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, float]
|
|
Source code in src/voids/image/segmentation.py
Image Connectivity¶
voids.image.connectivity
¶
has_spanning_cluster
¶
Test whether void space percolates from one boundary to the opposite.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
void_mask
|
ndarray
|
Binary image where |
required |
axis_index
|
int
|
Flow/percolation axis index. For a 3D array |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Notes
Connectivity is computed via :func:scipy.ndimage.label with its default
structuring element (face-connected in 3D, edge-connected in 2D). The
criterion is geometric percolation only; it does not assess hydraulic
conductance magnitude.
Assumptions and limitations
- Boundaries are interpreted as the first and last index along the target axis.
- Periodic boundaries are not considered.
- Very thin connections may percolate topologically even if they are not representative of realistic transport in a given experiment.
Source code in src/voids/image/connectivity.py
has_spanning_cluster_2d
¶
2D-specialized wrapper for axis-spanning connectivity checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
void_mask
|
ndarray
|
Two-dimensional binary void mask. |
required |
axis_index
|
int
|
Axis along which percolation is tested ( |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Notes
This function exists for notebook/API compatibility and delegates to
:func:has_spanning_cluster after enforcing 2D inputs.