Synthetic Image Cases¶
voids.generators.porous_image provides package-level helpers for constructing
controlled 2-D and 3-D binary porous images. These are intended for testing,
algorithm development, and reproducible demonstrations before moving to
scanner-derived data.
The central convention is:
Truemeans void,Falsemeans solid or matrix,- all shapes follow NumPy axis order.
Macro/Micro Pore Images¶
The macro/micro generator builds a two-porosity synthetic image from two PoreSpy
blobs fields:
- generate a resolved macropore image,
- generate a finer-scale micropore score field,
- keep micropores only inside the solid matrix of the macropore image,
- combine the two masks.
from voids.generators import generate_macro_micro_blobs_matrix
case = generate_macro_micro_blobs_matrix(
shape=(160, 160, 160),
macro_porosity=0.25,
matrix_microporosity=0.12,
macro_blobiness=1.2,
micropore_blobiness=8.0,
axis_index=0,
seed_start=2026,
max_tries=50,
)
void = case.void
macro = case.macro_void
micropores = case.micropore_void
The invariant is:
The reported total porosity is:
where \(\phi_{\mathrm{micro|matrix}}\) is the micropore fraction measured only in the matrix region of the macro image.
The micropore_blobiness parameter controls the feature scale of the small
pores. In PoreSpy blobs, larger blobiness values produce smaller features,
so a typical macro/micro setup uses:
- lower
macro_blobinessfor broader connected macropores, - higher
micropore_blobinessfor smaller pores in the matrix.
Synthetic interpretation
The micropore mask is a controlled synthetic model, not a calibrated unresolved-porosity law. It is useful for algorithm sensitivity studies, but the values should not be interpreted as a measured carbonate microporosity field without calibration.
Vug Insertions¶
Existing helpers can add idealized circular, elliptical, spherical, or ellipsoidal vugs to a binary matrix:
from voids.generators import insert_spherical_vug
with_vug, vug_mask = insert_spherical_vug(
case.void,
radius_vox=18,
center=(80, 80, 80),
)
The operation is a boolean union, so existing pores remain void.
Export And Import¶
Synthetic cases are ordinary voids image volumes once generated. Export and
import them through the dedicated
Image Volume And Surface Mesh I/O
section, which documents VolumeData, supported voxel formats, STL/OBJ surface
exports, sidecar metadata, and explicit voxel-size handling.
A typical synthetic-case export wraps the generated void mask with physical resolution metadata before writing files:
from voids.io import VolumeData, save_volume_bundle
case_data = VolumeData(
with_vug,
voxel_size=(40.0e-6, 40.0e-6, 40.0e-6),
units={"length": "m"},
metadata=case.metadata,
)
written = save_volume_bundle(
case_data,
"outputs/synthetic_case",
stem="macro_micro_vug",
formats=("raw", "npy", "h5", "nc", "tiff", "stl", "obj"),
)
Read the exported data with load_volume_data when physical resolution matters: