regionprops_3D#

This is similar to the regionprops in scikit-image but has some extra features that are relevant to 3D images. Note that the scikit-image version has been adding 3D capabilities, make the PoreSpy version less useful.

import porespy as ps
import numpy as np
import matplotlib.pyplot as plt
import scipy.ndimage as spim
/opt/hostedtoolcache/Python/3.8.16/x64/lib/python3.8/site-packages/openpnm/algorithms/_invasion_percolation.py:358: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.
  def _find_trapped_pores(inv_seq, indices, indptr, outlets):  # pragma: no cover
im = ps.generators.rsa([80, 80, 80], r=10, clearance=3)
plt.imshow(im[20, ...], origin='lower', interpolation='none');
/tmp/ipykernel_9265/538947285.py:1: DeprecationWarning: Call to deprecated function (or staticmethod) rsa. (This function will be renamed random_spheres in a future version)
  im = ps.generators.rsa([80, 80, 80], r=10, clearance=3)
../../../_images/7294d7f9b042622b889ede4a71fc11e143b9e581b740e5bc1330b96acf731f02.png

We need to label each sphere so they are recognized as individual regions:

regions = spim.label(im)[0]
plt.imshow(regions[20, ...], origin='lower', interpolation='none');
../../../_images/0cf8fac45533c3dc9639f9794a6bc7f292a2a3d96292e23ac1ac43e5c07ba718.png
props = ps.metrics.regionprops_3D(regions)

props is a list of RegionProperties objects, subclassed from scikit-image. Each RegionProperties object possess the properties as attributes. Note that these are calculated on demand, so the regionsprops_3D function appears very quick, but the work has not yet been done.

props
[<porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17186e50>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d171e6760>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d60ebb490>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d60ebb4c0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d60ebb460>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d60ebbd90>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d60eb6850>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d1f3a22b0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205f40>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205eb0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205d00>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205ca0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205d30>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205f70>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205d60>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205ee0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205e80>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d172059d0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205cd0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205fa0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205b20>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17205c40>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d1788bf40>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d172ef280>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d1c39d160>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17186fd0>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17186f10>,
 <porespy.metrics._regionprops.RegionPropertiesPS at 0x7f0d17186f70>]

The properties of regions 1 are on the RegionsProperties object located at position 0 in the props list:

for d in dir(props[0]):
    if not d.startswith('_'):
        print(d)
area
area_bbox
area_convex
area_filled
axis_major_length
axis_minor_length
bbox
bbox_volume
border
centroid
centroid_local
centroid_weighted
centroid_weighted_local
convex_volume
coords
coords_scaled
dt
eccentricity
equivalent_diameter_area
euler_number
extent
feret_diameter_max
image
image_convex
image_filled
image_intensity
inertia_tensor
inertia_tensor_eigvals
inscribed_sphere
intensity_max
intensity_mean
intensity_min
label
mask
moments
moments_central
moments_hu
moments_normalized
moments_weighted
moments_weighted_central
moments_weighted_hu
moments_weighted_normalized
num_pixels
orientation
perimeter
perimeter_crofton
skeleton
slice
slices
solidity
sphericity
surface_area
surface_mesh_simplices
surface_mesh_vertices
volume

Let’s check a few of the properties:

print(props[0].volume)
4139.0

Because the present function is meant for 3D images, we have added specific terminology, like volume, instead of allowing area to mean volume like the scikit-image version”

print(props[0].area)
4139.0

We do have a surface_area, which is also specific to 3D objects:

print(props[0].surface_area)
1165.306396484375

In addition to scalar metrics, we also provide access to useful images of the region:

plt.imshow(props[0].dt[5, ...]);
../../../_images/40cfc6133874e611c2a3dc38c8669295ebf2666bcad51e394919a8cbd4e74310.png