Source code for spam.label.ITKwatershed
"""
Library of wrapper functions for Simple ITK
Copyright (C) 2020 SPAM Contributors
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
"""
import numpy
import SimpleITK
import spam.label
[docs]
def watershed(binary, markers=None, watershedLevel=1):
"""
This function runs an ITK watershed on a binary image and returns a labelled image.
This function uses an interpixel watershed.
Parameters
-----------
binary : 3D numpy array
This image which is non-zero in the areas which should be split by the watershed algorithm
markers : 3D numpy array (optional, default = None)
Not implemented yet, but try!
watershedLevel : int, optional
Watershed level for merging maxima
Returns
--------
labelled : 3D numpy array of ints
3D array where each object is numbered
"""
# def plotme(im):
# im = SimpleITK.GetArrayFromImage(im)
# plt.imshow(im[im.shape[0]//2])
# plt.show()
binary = binary > 0
# Let's convert it 8-bit
binary = binary.astype(numpy.uint8) * 255
bdata = SimpleITK.GetImageFromArray(binary)
if markers is not None:
markers = markers.astype("<u4") if markers.max() > 65535 else markers.astype("<u2")
markers = SimpleITK.GetImageFromArray(markers)
# watershedLevel=1
watershedLineOn = False
fullyConnected = True
# thresholdFilt = SimpleITK.OtsuThresholdImageFilter()
# bdata = thresholdFilt.Execute(data)
# rescaleFilt = SimpleITK.RescaleIntensityImageFilter()
# rescaleFilt.SetOutputMinimum(0)
# rescaleFilt.SetOutputMaximum(65535)
# bdata = rescaleFilt.Execute(data)
# threshold = thresholdFilt.GetThreshold()
# fillFilt = SimpleITK.BinaryFillholeImageFilter()
# bdata = fillFilt.Execute(bdata)
invertFilt = SimpleITK.InvertIntensityImageFilter()
bdata = invertFilt.Execute(bdata)
distanceMapFilt = SimpleITK.DanielssonDistanceMapImageFilter()
distance = distanceMapFilt.Execute(bdata)
distance = invertFilt.Execute(distance)
if markers is None:
watershedFilt = SimpleITK.MorphologicalWatershedImageFilter()
else:
watershedFilt = SimpleITK.MorphologicalWatershedFromMarkersImageFilter()
watershedFilt.SetFullyConnected(fullyConnected)
watershedFilt.SetMarkWatershedLine(watershedLineOn)
if markers is None:
watershedFilt.SetLevel(watershedLevel)
labelImage = watershedFilt.Execute(distance)
else:
labelImage = watershedFilt.Execute(distance, markers)
bdata = invertFilt.Execute(bdata)
maskFilt = SimpleITK.MaskImageFilter()
mask = maskFilt.Execute(labelImage, bdata)
# overlayFilt = SimpleITK.LabelOverlayImageFilter()
# overlay = overlayFilt.Execute(bdata, mask)
lab = SimpleITK.GetArrayFromImage(mask).astype(spam.label.labelType)
return lab