hellow, everyone.
i want to creat a segment from a numpy array. and i found the python code in script repository as following.
volumeNode = getNode('MRHead')
segmentationNode = getNode('Segmentation')
segmentId = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName('Segment_1')
# Get segment as numpy array
segmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId, volumeNode)
# Modify the segmentation
segmentArray[:] = 0 # clear the segmentation
segmentArray[ slicer.util.arrayFromVolume(volumeNode) > 80 ] = 1 # create segment by simple thresholding of an image
segmentArray[20:80, 40:90, 30:70] = 1 # fill a rectangular region using numpy indexing
slicer.util.updateSegmentBinaryLabelmapFromArray(segmentArray, segmentationNode, segmentId, volumeNode)
in my own extension, the code line âvolumeNode = getNode(âMRHeadâ)â was be replaced by a qMRMLNodeCombobox in the nodetypes called âvtkMRMLScalarVolumeNodeâ.
the code line âsegmentationNode = getNode(âSegmentationâ)â was be replaced by a qMRMLNodeCombobox in the nodetypes called âvtkMRMLSegmentationNodeâ.
and i convert the âinputSelectorâ and âinputsegmentationâ into def process as following.
def onApplyButton(self) -> None: """Run processing when user clicks "Apply" button.""" with slicer.util.tryWithErrorDisplay(\_("Failed to compute results."), waitCursor=True): \# Compute output self.logic.process(self.ui.inputSelector.currentNode(), self.ui.imageThresholdSliderWidget.value, self.ui.inputlowerpoint.currentNode(), self.ui.inputmidpoint.currentNode(), self.ui.inputupperpoint.currentNode(), self.ui.inputsegmentation.currentNode())
class cutcalciLogic(ScriptedLoadableModuleLogic):
"""This class should implement all the actual computation done by your module. The interface should be such that other python code can import this class and make use of the functionality without requiring an instance of the Widget. Uses ScriptedLoadableModuleLogic base class, available at: https://github.com/Slicer/Slicer/blob/main/Base/Python/slicer/ScriptedLoadableModule.py """ def \__init_\_(self) -> None: """Called when the logic class is instantiated. Can be used for initializing member variables.""" ScriptedLoadableModuleLogic.\__init_\_(self) def getParameterNode(self): return cutcalciParameterNode(super().getParameterNode()) def getFiducialKJI(self, inputpoint, volume): def get_vascular_up2low(self, image, upperpoint, lowerpoint, CT_value): def get_vascular_low2up(self, image, lowerpoint, upperpoint, CT_value): def check_vascular(self, vascular_array, lowerpoint): def get_vascular(self, image, upperpoint, midpoint, lowerpoint): vascular_array= self.get_vascular_up2low(image, upperpoint, lowerpoint, CT_value= 130) while self.check_vascular(vascular_array, lowerpoint)==0: vascular_array_1= self.get_vascular_low2up(image, midpoint, upperpoint) vascular_array_2= self.get_vascular_up2low(image, midpoint, lowerpoint) vascular_array= vascular_array+ vascular_array_1+ vascular_array_2 return vascular_array def process(self, inputVolume: vtkMRMLScalarVolumeNode, imageThreshold: float, inputlowerpoint, inputmidpoint, inputupperpoint, inputsegmentation, showResult: bool = True) -> None: if not inputVolume: raise ValueError("Input volume is invalid") lowerpoint= self.getFiducialKJI(inputlowerpoint, inputVolume) midpoint= self.getFiducialKJI(inputmidpoint, inputVolume) upperpoint= self.getFiducialKJI(inputupperpoint, inputVolume) image_array= slicer.util.arrayFromVolume(inputVolume) #vascular_array= self.get_vascular(image_array,upperpoint, midpoint, lowerpoint) segmentId = inputsegmentation.GetSegmentation().GetSegmentIdBySegmentName('Segment_1') print(lowerpoint) \# Get segment as numpy array segmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(inputsegmentation, segmentId, inputVolume) **#there is an error in this code line** \# Modify the segmentation #segmentArray\[:\] = 0 # clear the segmentation #segmentArray\[ slicer.util.arrayFromVolume(inputVolume) > 80 \] = 1 # create segment by simple thresholding of an image #segmentArray\[20:80, 40:90, 30:70\] = 1 # fill a rectangular region using numpy indexing #slicer.util.updateSegmentBinaryLabelmapFromArray(segmentArray, inputsegmentation, segmentId, inputVolume)
and when i reload and apply this extension.
3D slicer tell me there is an error.
Traceback (most recent call last):
File âD:\program_file\Slicer 5.6.2\bin\Python\slicer\util.pyâ, line 3255, in tryWithErrorDisplay
yield
File âD:/program_file/Slicer 5.6.2/cutcalci/cutcalci/cutcalci.pyâ, line 245, in onApplyButton
self.logic.process(self.ui.inputSelector.currentNode(), self.ui.imageThresholdSliderWidget.value,
File âD:/program_file/Slicer 5.6.2/cutcalci/cutcalci/cutcalci.pyâ, line 423, in processGet segment as numpy array
File âD:\program_file\Slicer 5.6.2\bin\Python\slicer\util.pyâ, line 2138, in arrayFromSegmentBinaryLabelmap
narray = slicer.util.arrayFromVolume(labelmapVolumeNode)
File âD:\program_file\Slicer 5.6.2\bin\Python\slicer\util.pyâ, line 1742, in arrayFromVolume
narray = vtk.util.numpy_support.vtk_to_numpy(vimage.GetPointData().GetScalars()).reshape(nshape)
File âD:\program_file\Slicer 5.6.2\bin\Lib\site-packages\vtkmodules\util\numpy_support.pyâ, line 215, in vtk_to_numpy
typ = vtk_array.GetDataType()
AttributeError: âNoneTypeâ object has no attribute âGetDataTypeâ
iâm sure that it is the code line âsegmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(inputsegmentation, segmentId, inputVolume) â which causes this error. because there the KJI coordinate of lowerpoint can be printed in python console.
so, my problem is how to create a segment from numpy array successfully?




