Coverage for /usr/local/lib/python3.10/site-packages/spam/label/ITKwatershed.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-24 17:26 +0000

1# Library of wrapper functions for Simple ITK 

2# Copyright (C) 2020 SPAM Contributors 

3# 

4# This program is free software: you can redistribute it and/or modify it 

5# under the terms of the GNU General Public License as published by the Free 

6# Software Foundation, either version 3 of the License, or (at your option) 

7# any later version. 

8# 

9# This program is distributed in the hope that it will be useful, but WITHOUT 

10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 

11# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 

12# more details. 

13# 

14# You should have received a copy of the GNU General Public License along with 

15# this program. If not, see <http://www.gnu.org/licenses/>. 

16 

17import numpy 

18import SimpleITK 

19import spam.label 

20 

21 

22def watershed(binary, markers=None, watershedLevel=1): 

23 """ 

24 This function runs an ITK watershed on a binary image and returns a labelled image. 

25 This function uses an interpixel watershed. 

26 

27 Parameters 

28 ----------- 

29 binary : 3D numpy array 

30 This image which is non-zero in the areas which should be split by the watershed algorithm 

31 

32 markers : 3D numpy array (optional, default = None) 

33 Not implemented yet, but try! 

34 

35 watershedLevel : int, optional 

36 Watershed level for merging maxima 

37 

38 Returns 

39 -------- 

40 labelled : 3D numpy array of ints 

41 3D array where each object is numbered 

42 """ 

43 

44 # def plotme(im): 

45 # im = SimpleITK.GetArrayFromImage(im) 

46 # plt.imshow(im[im.shape[0]//2]) 

47 # plt.show() 

48 

49 binary = binary > 0 

50 

51 # Let's convert it 8-bit 

52 binary = binary.astype(numpy.uint8) * 255 

53 

54 bdata = SimpleITK.GetImageFromArray(binary) 

55 

56 if markers is not None: 

57 markers = markers.astype("<u4") if markers.max() > 65535 else markers.astype("<u2") 

58 markers = SimpleITK.GetImageFromArray(markers) 

59 

60 # watershedLevel=1 

61 watershedLineOn = False 

62 fullyConnected = True 

63 

64 # thresholdFilt = SimpleITK.OtsuThresholdImageFilter() 

65 # bdata = thresholdFilt.Execute(data) 

66 

67 # rescaleFilt = SimpleITK.RescaleIntensityImageFilter() 

68 # rescaleFilt.SetOutputMinimum(0) 

69 # rescaleFilt.SetOutputMaximum(65535) 

70 # bdata = rescaleFilt.Execute(data) 

71 

72 # threshold = thresholdFilt.GetThreshold() 

73 

74 # fillFilt = SimpleITK.BinaryFillholeImageFilter() 

75 # bdata = fillFilt.Execute(bdata) 

76 

77 invertFilt = SimpleITK.InvertIntensityImageFilter() 

78 bdata = invertFilt.Execute(bdata) 

79 

80 distanceMapFilt = SimpleITK.DanielssonDistanceMapImageFilter() 

81 distance = distanceMapFilt.Execute(bdata) 

82 

83 distance = invertFilt.Execute(distance) 

84 

85 if markers is None: 

86 watershedFilt = SimpleITK.MorphologicalWatershedImageFilter() 

87 else: 

88 watershedFilt = SimpleITK.MorphologicalWatershedFromMarkersImageFilter() 

89 watershedFilt.SetFullyConnected(fullyConnected) 

90 watershedFilt.SetMarkWatershedLine(watershedLineOn) 

91 

92 if markers is None: 

93 watershedFilt.SetLevel(watershedLevel) 

94 labelImage = watershedFilt.Execute(distance) 

95 else: 

96 labelImage = watershedFilt.Execute(distance, markers) 

97 

98 bdata = invertFilt.Execute(bdata) 

99 

100 maskFilt = SimpleITK.MaskImageFilter() 

101 mask = maskFilt.Execute(labelImage, bdata) 

102 

103 # overlayFilt = SimpleITK.LabelOverlayImageFilter() 

104 # overlay = overlayFilt.Execute(bdata, mask) 

105 

106 lab = SimpleITK.GetArrayFromImage(mask).astype(spam.label.labelType) 

107 

108 return lab