Coverage for /usr/local/lib/python3.8/site-packages/spam/filters/distanceField.py: 100%
11 statements
« prev ^ index » next coverage.py v7.2.3, created at 2023-11-22 13:26 +0000
« prev ^ index » next coverage.py v7.2.3, created at 2023-11-22 13:26 +0000
1# Library of SPAM functions for projecting morphological field onto tetrahedral
2# meshes
3# Copyright (C) 2020 SPAM Contributors
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation, either version 3 of the License, or (at your option)
8# any later version.
9#
10# This program is distributed in the hope that it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13# more details.
14#
15# You should have received a copy of the GNU General Public License along with
16# this program. If not, see <http://www.gnu.org/licenses/>.
19import numpy
20import scipy
23def distanceField(phases, phaseID=1):
24 """
25 This function tranforms an array/image of integers into a continuous field.
26 It works for segmented binary/trinary 3D images or arrays of integers.
27 It has to be run for each phase seperately.
29 It uses of the **Distance Transform Algorithm**.
30 For every voxel belonging to a phase a value indicating the distance
31 (in voxels) of that point to the nearest background point is computed.
32 The DTA is computed for the inverted image as well and the computed
33 distances are setting to negative values.
34 The 2 distance fields are merged into the final continuuos distance field
35 where:
37 .. code-block:: text
39 - positive numbers: distances from the phase to the nearest background
40 voxel
41 - negative values: distances from the background to the nearest phase
42 voxel
43 - zero values: the interface between the considered phase and the
44 background
46 Parameters
47 -----------
48 phases : array
49 The input image/array (each phase should be represented with only
50 one number)
52 phaseID : int, default=1
53 The integer indicating the phase which distance field you want to
54 calculate
56 Returns
57 --------
58 distance field of the phase: array
60 Example
61 --------
62 >>> import tifffile
63 >>> import spam.filters
64 >>> im = tifffile.imread( "mySegmentedImage.tif" )
65 In this image the inclusions are labelled 1 and the matrix 0
66 >>> di = spam.filters.distanceField( im, phase=1 )
67 The resulting distance field is made of float between -1 and 1
69 """
70 # create binary image from phases and phaseID
71 binary = numpy.zeros_like(phases, dtype=bool)
72 binary[phases == phaseID] = True
74 # Create the complementary binary image
75 binaryNot = numpy.logical_not(binary)
77 # Calculate the distance algorithm for the 2 binary images
79 binaryDist = scipy.ndimage.distance_transform_edt(binary).astype("<f4")
80 binaryNotDist = scipy.ndimage.distance_transform_edt(binaryNot).astype("<f4")
82 # normalise if needed
84 # if normalise:
85 # binaryDist = binaryDist / binaryDist.max()
87 # if normalise:
88 # binaryNotDist = binaryNotDist.astype(float)
89 # binaryNotDist = binaryNotDist / binaryNotDist.max()
91 # Step 5: Merge the 2 distance fields into the final one
92 binaryNotDist = (-1.0) * binaryNotDist
93 binaryNotDist = binaryNotDist + binaryDist
95 return binaryNotDist