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

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/>. 

17 

18 

19import numpy 

20import scipy 

21 

22 

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. 

28 

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: 

36 

37 .. code-block:: text 

38 

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 

45 

46 Parameters 

47 ----------- 

48 phases : array 

49 The input image/array (each phase should be represented with only 

50 one number) 

51 

52 phaseID : int, default=1 

53 The integer indicating the phase which distance field you want to 

54 calculate 

55 

56 Returns 

57 -------- 

58 distance field of the phase: array 

59 

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 

68 

69 """ 

70 # create binary image from phases and phaseID 

71 binary = numpy.zeros_like(phases, dtype=bool) 

72 binary[phases == phaseID] = True 

73 

74 # Create the complementary binary image 

75 binaryNot = numpy.logical_not(binary) 

76 

77 # Calculate the distance algorithm for the 2 binary images 

78 

79 binaryDist = scipy.ndimage.distance_transform_edt(binary).astype("<f4") 

80 binaryNotDist = scipy.ndimage.distance_transform_edt(binaryNot).astype("<f4") 

81 

82 # normalise if needed 

83 

84 # if normalise: 

85 # binaryDist = binaryDist / binaryDist.max() 

86 

87 # if normalise: 

88 # binaryNotDist = binaryNotDist.astype(float) 

89 # binaryNotDist = binaryNotDist / binaryNotDist.max() 

90 

91 # Step 5: Merge the 2 distance fields into the final one 

92 binaryNotDist = (-1.0) * binaryNotDist 

93 binaryNotDist = binaryNotDist + binaryDist 

94 

95 return binaryNotDist