Skip to content

Commit

Permalink
Merge pull request #1005 from PMEAL/fix_scikit_image_deprecations
Browse files Browse the repository at this point in the history
Changed `skeletonize_3d` to `skeletonize` to deal with skimage deprecation, plus a few other related fixes #maint
Updated requirements in pyproject.toml to force use of skimage 0.24 because watershed in 0.25 returns different results #maint
  • Loading branch information
jgostick authored Jan 15, 2025
2 parents b08a0f2 + 51b82d1 commit f6a1423
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,4 @@ examples/networks/*.vt*
examples/**/*.vtp
examples/**/*.tif
*.mphtxt
*.DS_Store
4 changes: 2 additions & 2 deletions examples/filters/reference/apply_padded.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"metadata": {},
"source": [
"## `func`\n",
"A good use case is `skeletonize_3d`, which has edge artifacts that can be reduced if the image is pre-padded. It works on 2D or 3D images."
"A good use case is `skeletonize`, which has edge artifacts that can be reduced if the image is pre-padded. It works on 2D or 3D images."
]
},
{
Expand All @@ -96,7 +96,7 @@
},
"outputs": [],
"source": [
"func = skimage.morphology.skeletonize_3d"
"func = skimage.morphology.skeletonize"
]
},
{
Expand Down
6 changes: 3 additions & 3 deletions examples/filters/reference/prune_branches.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"import porespy as ps\n",
"import scipy.ndimage as spim\n",
"import matplotlib.pyplot as plt\n",
"from skimage.morphology import skeletonize_3d\n",
"from skimage.morphology import skeletonize\n",
"ps.visualization.set_mpl_style()"
]
},
Expand All @@ -34,7 +34,7 @@
"metadata": {},
"source": [
"## `im`\n",
"The function requires a skeleton such as that produced by ``skimage.mophology.skeletonize_3d``:"
"The function requires a skeleton such as that produced by ``skimage.mophology.skeletonize``:"
]
},
{
Expand Down Expand Up @@ -118,7 +118,7 @@
],
"source": [
"im = ps.generators.blobs(shape=[250, 250], blobiness=1, porosity=0.6)\n",
"sk = skeletonize_3d(im)\n",
"sk = skeletonize(im)\n",
"sk1 = ps.filters.prune_branches(sk)\n",
"\n",
"fig, ax = plt.subplots(1, 2, figsize=[12, 6])\n",
Expand Down
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ dependencies = [
"pandas",
"psutil",
"rich",
"scikit-image",
"scikit-image<0.25.0",
"scipy",
"tqdm",
"pywavelets",
"setuptools",
]
readme = "README.md"
requires-python = ">= 3.8"
requires-python = ">= 3.10"

[project.optional-dependencies]
build = ["hatch"]
Expand Down Expand Up @@ -125,6 +125,7 @@ packages = ["src/porespy"]
[tool.pytest.ini_options]
minversion = "6.0"
addopts = [
"--assert=plain",
"-ra -v",
"--ignore=docs/conf.py",
"--ignore=examples/generators/reference/fractal_noise.ipynb",
Expand All @@ -138,6 +139,7 @@ python_functions = "test_*"
testpaths = ["test", "examples"]
norecursedirs = [".git", ".github", ".ipynb_checkpoints", "build", "dist"]


[tool.coverage.run]
source = ["src/porespy"]
[tool.coverage.report]
Expand Down
2 changes: 1 addition & 1 deletion src/porespy/filters/_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def apply_padded(im, pad_width, func, pad_val=1, **kwargs):
Notes
-----
A use case for this is when using ``skimage.morphology.skeletonize_3d``
A use case for this is when using ``skimage.morphology.skeletonize``
to ensure that the skeleton extends beyond the edges of the image.
Examples
Expand Down
6 changes: 3 additions & 3 deletions src/porespy/metrics/_regionprops.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from skimage.measure import marching_cubes
except ImportError:
from skimage.measure import marching_cubes_lewiner as marching_cubes
from skimage.morphology import skeletonize_3d, ball
from skimage.morphology import skeletonize, ball
from skimage.measure import regionprops
from skimage.measure._regionprops import RegionProperties
from pandas import DataFrame
Expand Down Expand Up @@ -191,7 +191,7 @@ def regionprops_3D(im):
as the region to the actual surface area of the region.
'skeleton'
The medial axis of the region obtained using the ``skeletonize_3D``
The medial axis of the region obtained using the ``skeletonize``
method from **skimage**.
'convex_volume'
Expand Down Expand Up @@ -274,7 +274,7 @@ def sphericity(self):

@property
def skeleton(self):
return skeletonize_3d(self.mask)
return skeletonize(self.mask)

@property
def surface_area(self):
Expand Down
2 changes: 1 addition & 1 deletion src/porespy/tools/_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def unpad(im, pad_width):
Notes
-----
A use case for this is when using ``skimage.morphology.skeletonize_3d``
A use case for this is when using ``skimage.morphology.skeletonize``
to ensure that the skeleton extends beyond the edges of the image, but the
padding should be subsequently removed.
Expand Down
30 changes: 20 additions & 10 deletions test/unit/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from edt import edt
import porespy as ps
import scipy.ndimage as spim
from skimage.morphology import disk, ball, skeletonize_3d
from skimage.morphology import disk, ball
from skimage.util import random_noise
from scipy.stats import norm
ps.settings.tqdm['disable'] = True
Expand Down Expand Up @@ -466,24 +466,33 @@ def test_chunked_func_w_ill_defined_filter(self):
overlap=5)

def test_prune_branches(self):
im = ps.generators.lattice_spheres(shape=[100, 100, 100], r=4)
skel1 = skeletonize_3d(im)
from skimage.morphology import skeletonize
im = ps.generators.random_spheres([100, 100, 100], r=4, seed=0)
skel1 = skeletonize(im)
skel2 = ps.filters.prune_branches(skel1)
assert skel1.sum() > skel2.sum()

def test_prune_branches_n2(self):
im = ps.generators.lattice_spheres(shape=[100, 100, 100], r=4)
skel1 = skeletonize_3d(im)
from skimage.morphology import skeletonize
im = ps.generators.random_spheres([100, 100, 100], r=4, seed=0)
skel1 = skeletonize(im)
skel2 = ps.filters.prune_branches(skel1, iterations=1)
skel3 = ps.filters.prune_branches(skel1, iterations=2)
assert skel1.sum() > skel2.sum()
assert skel2.sum() == skel3.sum()
assert skel2.sum() > skel3.sum()
skel4 = ps.filters.prune_branches(skel1, iterations=3)
assert skel3.sum() > skel4.sum()

def test_apply_padded(self):
from skimage.morphology import skeletonize
im = ps.generators.blobs(shape=[100, 100])
skel1 = skeletonize_3d(im)
skel2 = ps.filters.apply_padded(im=im, pad_width=20, pad_val=1,
func=skeletonize_3d)
skel1 = skeletonize(im)
skel2 = ps.filters.apply_padded(
im=im,
pad_width=20,
pad_val=1,
func=skeletonize,
)
assert (skel1.astype(bool)).sum() != (skel2.astype(bool)).sum()

def test_trim_small_clusters(self):
Expand Down Expand Up @@ -514,7 +523,8 @@ def test_hold_peaks_algorithm(self):

def test_nl_means_layered(self):
im = ps.generators.blobs(shape=[50, 50, 50], blobiness=.5)
im2 = random_noise(im, seed=0)
np.random.seed(0)
im2 = random_noise(im)
filt = ps.filters.nl_means_layered(im=im2)
p1 = (filt[0, ...] > 0.5).sum()
p2 = (im[0, ...]).sum()
Expand Down
17 changes: 10 additions & 7 deletions test/unit/test_network_size_factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

class NetworkSizeFactorTest():
def setup_class(self):
np.random.seed(10)
im = ps.generators.blobs(shape=[50, 50, 50])
im = ps.generators.blobs(shape=[50, 50, 50], seed=10)
self.im = im[:15, :15, :15]
self.snow = ps.networks.snow2(self.im, boundary_width=0,
parallelization=None)
Expand All @@ -15,8 +14,10 @@ def test_diffusive_size_factor_DNS(self):
regions = self.snow.regions
net = self.snow.network
conns = net['throat.conns']
size_factors = ps.networks.diffusive_size_factor_DNS(regions,
throat_conns=conns)
size_factors = ps.networks.diffusive_size_factor_DNS(
regions,
throat_conns=conns,
)
values = np.array([1.43456123, 0.9612569, 1.22389664,
0.14359343, 0.18617079, 1.30144843,
0.22238891, 1.32222092])
Expand All @@ -27,9 +28,11 @@ def test_diffusive_size_factor_DNS_voxel_size(self):
regions = self.snow.regions
net = self.snow.network
conns = net['throat.conns']
size_factors = ps.networks.diffusive_size_factor_DNS(regions,
throat_conns=conns,
voxel_size=voxel_size)
size_factors = ps.networks.diffusive_size_factor_DNS(
regions,
throat_conns=conns,
voxel_size=voxel_size,
)
values = np.array([1.43456123, 0.9612569, 1.22389664,
0.14359343, 0.18617079, 1.30144843,
0.22238891, 1.32222092])*voxel_size
Expand Down
2 changes: 1 addition & 1 deletion test/unit/test_parallel_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from edt import edt
import porespy as ps
import scipy.ndimage as spim
from skimage.morphology import skeletonize_3d
from skimage.morphology import skeletonize
ps.settings.loglevel = "CRITICAL"
ps.settings.tqdm['disable'] = True

Expand Down
2 changes: 1 addition & 1 deletion test/unit/test_simulations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from edt import edt
import porespy as ps
import scipy.ndimage as spim
from skimage.morphology import disk, ball, skeletonize_3d
from skimage.morphology import disk, ball, skeletonize
from skimage.util import random_noise
from scipy.stats import norm

Expand Down

0 comments on commit f6a1423

Please sign in to comment.