コード例 #1
0
ファイル: Isobrush.py プロジェクト: pieper/CommonGL
 def onReload(self):
     EditUtil.EditUtil().setCurrentEffect("DefaultTool")
     import Isobrush
     # TODO: this causes a flash of the new widget, but not a big deal since it's only devel mode
     w = Isobrush.IsobrushWidget()
     w.onReload()
     del (w.parent)
     EditUtil.EditUtil().setCurrentEffect("Isobrush")
コード例 #2
0
 def updateSliders(self):
     r = self.structuresView.currentIndex().row()
     if (r > -1):
         ei = slicer.modules.SlicerPathologyWidget.editorWidget.helper.structures.item(
             r, 3).text()
     else:
         ei = EditUtil.EditUtil().getParameterNode().GetParameter(
             'SlicerPathology,tilename') + '-label'
     if ei not in params:
         params[ei] = cparams.copy()
         if (r < 0):
             params[ei][
                 'label'] = slicer.modules.SlicerPathologyWidget.editorWidget.helper.editUtil.getLabelName(
                 )
         else:
             params[ei][
                 'label'] = slicer.modules.SlicerPathologyWidget.editorWidget.helper.structures.item(
                     r, 2).text()
         jstr = json.dumps(params,
                           sort_keys=True,
                           indent=4,
                           separators=(',', ': '))
         self.parameterNode.SetParameter("QuickTCGAEffect,erich", jstr)
     self.frameOtsuSlider.value = params[ei]["otsuRatio"]
     self.frameCurvatureWeightSlider.value = params[ei]["curvatureWeight"]
     self.frameSizeThldSlider.value = params[ei]["sizeThld"]
     self.frameSizeUpperThldSlider.value = params[ei]["sizeUpperThld"]
     self.frameMPPSlider.value = params[ei]["mpp"]
コード例 #3
0
ファイル: CustomEditBox.py プロジェクト: zhuyouhuang/EyeSpot
    def setDefaultParams(self):
        """Configure here all the required params for any LabelEffect (Paint, Draw, ect.)"""
        self.editUtil = EditUtil.EditUtil()
        self.parameterNode = self.editUtil.getParameterNode()

        self.parameterNode.SetParameter("LabelEffect,paintOver", "1") # Enable paintOver
        self.parameterNode.SetParameter("LabelEffect,paintThreshold", "0")   # Enable Threshold checkbox
コード例 #4
0
ファイル: GrowCutCL.py プロジェクト: suixiaodan/SlicerCL
 def updateParameterNode(self, caller, event):
   node = EditUtil.EditUtil().getParameterNode()
   if node != self.parameterNode:
     if self.parameterNode:
       node.RemoveObserver(self.parameterNodeTag)
     self.parameterNode = node
     self.parameterNodeTag = node.AddObserver("ModifiedEvent", self.updateGUIFromMRML)
コード例 #5
0
ファイル: EditorEffectTemplate.py プロジェクト: Slicer/Slicer
 def updateParameterNode(self, caller, event):
   node = EditUtil.getParameterNode()
   if node != self.parameterNode:
     if self.parameterNode:
       node.RemoveObserver(self.parameterNodeTag)
     self.parameterNode = node
     self.parameterNodeTag = node.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
コード例 #6
0
 def updateParam(self, p, v):
     r = self.structuresView.currentIndex().row()
     if (r > -1):
         ei = slicer.modules.SlicerPathologyWidget.editorWidget.helper.structures.item(
             r, 3).text()
     else:
         ei = EditUtil.EditUtil().getParameterNode().GetParameter(
             'SlicerPathology,tilename') + '-label'
     if ei not in params:
         params[ei] = cparams.copy()
         if (r < 0):
             params[ei][
                 'label'] = slicer.modules.SlicerPathologyWidget.editorWidget.helper.editUtil.getLabelName(
                 )
         else:
             params[ei][
                 'label'] = slicer.modules.SlicerPathologyWidget.editorWidget.helper.structures.item(
                     r, 2).text()
     params[ei][p] = v
     cparams[p] = v
     jstr = json.dumps(params,
                       sort_keys=True,
                       indent=4,
                       separators=(',', ': '))
     self.parameterNode.SetParameter("QuickTCGAEffect,erich", jstr)
コード例 #7
0
ファイル: GrowCutCL.py プロジェクト: suixiaodan/SlicerCL
  def step(self, iterations=1):

    if self.pendingEvent:
      if self.pendingEvent.command_execution_status == 0:
        # TODO: is there an attribute for CL_COMPLETE?
        # TODO: also catch error codes here
        #
        # put data back in node
        #
        self.steeredArray[:] = self.labelNext_dev.get()
        self.steeredNode.GetImageData().Modified()
        self.steeredNode.Modified()
      else:
        return

    #
    # get the parameters from MRML
    #
    # TODO: handl any real growcut parameters
    node = EditUtil.EditUtil().getParameterNode()

    #
    # initialize candidates if needed
    #
    if not self.candidatesInitialized:
      self.clProgram.clearShort(
          self.clQueue, self.shape, None, self.candidatesNext_dev.data).wait()
      print("self.candidatesNext_dev mean ", self.candidatesNext_dev.get().mean())
      self.clProgram.initialCandidates(
          self.clQueue, self.shape, None, self.labelArray_dev.data,
          self.candidates_dev.data).wait()
      print("self.labelArray_dev mean ", self.labelArray_dev.get().mean())
      print("self.candidates_dev mean ", self.candidates_dev.get().mean())
      self.candidatesInitialized = True

    #
    # run iterations
    # - save the pending event from the last call so that we can
    #   know when the execution is finished (so the main event loop
    #   is not blocked on this execution)
    #
    for iteration in xrange(iterations):
      self.clProgram.growCut(self.clQueue, self.work_size, None,
          self.backgroundArray_dev.data, self.labelArray_dev.data,
          self.theta_dev.data,
          self.thetaNext_dev.data, self.labelNext_dev.data,
          self.candidates_dev.data, self.candidatesNext_dev.data,
          self.backgroundArrayMax, global_offset=self.work_offset)
      self.clProgram.copyShort(self.clQueue, self.work_size, None,
          self.labelNext_dev.data, self.labelArray_dev.data, global_offset=self.work_offset)
      self.clProgram.copyShort(self.clQueue, self.work_size, None,
          self.candidatesNext_dev.data, self.candidates_dev.data, global_offset=self.work_offset)
      self.clProgram.clearShort(self.clQueue, self.work_size, None,
          self.candidatesNext_dev.data, global_offset=self.work_offset)
      self.pendingEvent = self.clProgram.copyFloat(self.clQueue, self.work_size, None,
          self.thetaNext_dev.data, self.theta_dev.data, global_offset=self.work_offset)
コード例 #8
0
ファイル: TraceAndSelect.py プロジェクト: FastSlice/Extension
    def apply(self, xy, mode=0, forced_path=None, forced_point=None):
        #
        # get the parameters from MRML
        #

        # For sanity purposes, tool can always "paint" over existing labels. If we find some foreseeable reason why we might
        # not want this in all cases, we can re-add to the GUI.

        #
        # get the label and background volume nodes
        #
        labelLogic = self.sliceLogic.GetLabelLayer()
        labelNode = labelLogic.GetVolumeNode()
        backgroundLogic = self.sliceLogic.GetBackgroundLayer()
        backgroundNode = backgroundLogic.GetVolumeNode()

        ##### self.errorMessageFrame.textCursor().insertHtml('Error Detected!')
        ##### self.errorMessageFrame.setStyleSheet("QTextEdit {color:red}")

        #
        # get the ijk location of the clicked point
        # by projecting through patient space back into index
        # space of the volume.  Result is sub-pixel, so round it
        # (note: bg and lb will be the same for volumes created
        # by the editor, but can be different if the use selected
        # different bg nodes, but that is not handled here).
        #
        xyToIJK = labelLogic.GetXYToIJKTransform()
        ijkFloat = xyToIJK.TransformDoublePoint(xy + (0, ))
        ijk = []
        for element in ijkFloat:
            try:
                intElement = int(round(element))
            except ValueError:
                intElement = 0
            ijk.append(intElement)
        ijk.reverse()
        ijk = tuple(ijk)

        ### IJK ACTIVE HERE
        #
        # Get the numpy array for the bg and label
        #
        node = EditUtil.EditUtil().getParameterNode()
        offset = float(node.GetParameter("TraceAndSelect,offsetvalue"))
        if offset != 0 and mode == 0:
            self.progress = qt.QProgressDialog()
            self.progress.setLabelText("Processing Slices...")
            self.progress.setCancelButtonText("Abort Fill")
            self.progress.setMinimum(0)
            self.progress.setMaximum(abs(offset))
            self.progress.setAutoClose(1)
            self.progress.open()
        return self.fill(ijk, [], mode, forced_path, forced_point)
コード例 #9
0
ファイル: GrowCutCL.py プロジェクト: suixiaodan/SlicerCL
 def __init__(self,options,preferredDeviceType='GPU'):
   self.preferredDeviceType = preferredDeviceType
   self.editUtil = EditUtil.EditUtil()
   self.sliceWidget = options.tools[0].sliceWidget
   if hasattr(slicer.modules, 'editorBot'):
     slicer.modules.editorBot.active = False
     del(slicer.modules.editorBot)
   slicer.modules.editorBot = self
   self.interval = 100
   self.active = False
   self.start()
コード例 #10
0
    def __init__(self, options):
        self.editUtil = EditUtil.EditUtil()
        #self.sliceWidget = options.tools[0].sliceWidget
        self.sliceWidget = slicer.app.layoutManager().sliceWidget('Red')
        if hasattr(slicer.modules, 'TCGAEditorBot'):
            slicer.modules.TCGAEditorBot.active = False
            del (slicer.modules.TCGAEditorBot)
        slicer.modules.TCGAEditorBot = self

        self.redSliceWidget = options.redSliceWidget
        self.greenSliceWidget = options.greenSliceWidget
        self.yellowSliceWidget = options.yellowSliceWidget
        self.start()
コード例 #11
0
    def onloadCTButtonClicked(self):
        # widge to load file
        w = qt.QWidget()
        w.resize(320, 240)
        w.setWindowTitle("Select CT Image")
        image_path = qt.QFileDialog.getOpenFileName(w, 'Open File', '/')
        path = str('/'.join(image_path.split('/')[0:-1])) + '/'
        print(path)
        print(image_path)

        if image_path is not None:
            self.image_loaded = True
            print(image_path)

        filetype = ".nrrd"
        self.filetype = filetype
        lm = slicer.app.layoutManager()
        lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView)
        view = lm.threeDWidget(0).threeDView()
        viewNode = view.mrmlViewNode()

        viewNode.SetBackgroundColor((0, 0, 0))
        viewNode.SetBackgroundColor2((0, 0, 0))
        viewNode.SetAxisLabelsVisible(0)
        viewNode.SetBoxVisible(0)

        # load image (master volume)
        load, image = slicer.util.loadVolume(image_path, returnNode=True)
        volumesLogic = slicer.modules.volumes.logic()
        label_name = image.GetName() + "-rough-label"
        label = volumesLogic.CreateLabelVolume(slicer.mrmlScene, image,
                                               label_name)
        label_path = str(path + label_name + filetype)
        print(label_path)

        self.view = view
        self.path = path
        self.image_path = image_path
        self.label_path = label_path
        self.image_name = image.GetName()
        self.label_name = label_name
        self.labelpostfix1 = '_tumor_label'
        self.labelpostfix2 = '_lung_label'

        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetReferenceActiveLabelVolumeID(label.GetID())
        EditUtil.EditUtil().propagateVolumeSelection()

        # switch to Edit module
        slicer.util.selectModule('Editor')
        slicer.modules.EditorWidget.toolsBox.selectEffect('PaintEffect')
コード例 #12
0
    def __init__(self, sliceLogic):
        print("Preparing Growcut interaction")
        self.attributes = ('MouseTool')
        self.displayName = 'FastGrowCut Effect'

        #disconnect all shortcuts that may exist, to allow Fast GrowCut's to work, reconnect once bot is turned off
        slicer.modules.EditorWidget.removeShortcutKeys()
        self.sliceLogic = sliceLogic
        self.editUtil = EditUtil.EditUtil()

        #initialize Fast GrowCut
        self.init_fGrowCut()

        self.fastCrowCutCreated = False
コード例 #13
0
    def __init__(self, sliceLogic):
        print("Preparing CleverSeg interaction")
        self.attributes = ('MouseTool')
        self.displayName = 'CleverSeg Effect'

        # disconnect all shortcuts that may exist, to allow CleverSeg's to work, reconnect once bot is turned off
        slicer.modules.EditorWidget.removeShortcutKeys()
        self.sliceLogic = sliceLogic
        self.editUtil = EditUtil.EditUtil()

        # initialize CleverSeg
        self.init_fCleverSeg()

        self.CleverSegCreated = False
コード例 #14
0
    def onloadMRIFLAIRButtonClicked(self):
        # widge to load file
        w = qt.QWidget()
        w.resize(320, 240)
        w.setWindowTitle("Select MRI FLAIR Image")
        self.FLAIR_image_path = qt.QFileDialog.getOpenFileName(
            w, 'Open File', '/')
        self.FLAIR_path = str('/'.join(
            self.FLAIR_image_path.split('/')[0:-1])) + '/'

        lm = slicer.app.layoutManager()
        lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView)
        view = lm.threeDWidget(0).threeDView()
        viewNode = view.mrmlViewNode()

        viewNode.SetBackgroundColor((0, 0, 0))
        viewNode.SetBackgroundColor2((0, 0, 0))
        viewNode.SetAxisLabelsVisible(0)
        viewNode.SetBoxVisible(0)
        self.view = view

        load, image = slicer.util.loadVolume(self.FLAIR_image_path,
                                             returnNode=True)

        # adding a automated seed point
        volumesLogic = slicer.modules.volumes.logic()
        label_name = image.GetName() + "-rough-label"
        label = volumesLogic.CreateLabelVolume(slicer.mrmlScene, image,
                                               label_name)
        #        label_path  = str(path+label_name+filetype)
        #        print(label_path)
        #
        #        self.view = view
        #        self.path = path
        #        self.image_path = image_path
        #        self.label_path = label_path
        #        self.image_name = image.GetName()
        self.label_name = label_name
        #        self.labelpostfix1 = '_tumor_confidenceconnected'
        #        self.labelpostfix2 = '_lung_confidenceconnected'

        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetReferenceActiveLabelVolumeID(label.GetID())
        EditUtil.EditUtil().propagateVolumeSelection()

        # switch to Edit module
        slicer.util.selectModule('Editor')
        slicer.modules.EditorWidget.toolsBox.selectEffect('PaintEffect')
コード例 #15
0
    def run_qtcga_segmentation_1(self):
        """
        Original recipe
        :return: 
        """
        if self.bEditTCGA:

            self.currentMessage = "Quick TCGA: running nucleus segmentation ..."
            slicer.util.showStatusMessage(self.currentMessage)
            seedArray = slicer.util.array(self.labelNode.GetName())
            self.qTCGASeedArray[:] = seedArray[:]

            node = EditUtil.EditUtil().getParameterNode()  # get the parameters from MRML
            otsuRatio = float(node.GetParameter("ShortCut,otsuRatio"))
            print(otsuRatio)
            curvatureWeight = float(node.GetParameter("ShortCut,curvatureWeight")) / 10
            print(curvatureWeight)
            sizeThld = float(node.GetParameter("ShortCut,sizeThld"))
            print(sizeThld)
            sizeUpperThld = float(node.GetParameter("ShortCut,sizeUpperThld"))
            print(sizeUpperThld)
            mpp = float(node.GetParameter("ShortCut,mpp")) / 100
            print(mpp)

            self.qTCGAMod.SetotsuRatio(otsuRatio)
            self.qTCGAMod.SetcurvatureWeight(curvatureWeight)
            self.qTCGAMod.SetsizeThld(sizeThld)
            self.qTCGAMod.SetsizeUpperThld(sizeUpperThld)
            self.qTCGAMod.Setmpp(mpp)

            self.qTCGAMod.SetSourceVol(self.foregroundNode.GetImageData())
            self.qTCGAMod.SetSeedVol(self.labelNode.GetImageData())
            self.qTCGASegArray[:] = seedArray[:]

            self.labelNode.GetImageData().Modified()
            self.labelNode.Modified()

            self.bEditTCGA = False

            self.currentMessage = "Quick TCGA done: nuclei segmentation is done; press 'F' to enable ROI selection for refinement"
            slicer.util.showStatusMessage(self.currentMessage)

        else:
            self.currentMessage = "Quick TCGA: go to seed labels first by pressing 'E'"
            slicer.util.showStatusMessage(self.currentMessage)
コード例 #16
0
ファイル: TraceAndSelect.py プロジェクト: FastSlice/Extension
    def setErrorMessage(self, errorText, errorColor=0):
        """Call this to seet the message in the error box.
        Parameters: 
          errorText: string to be displayed in the box 
          errorColor: int 1 or 0 (DEFAULT IS 0) that sets the color of the text as either green (1) or red (0)
        Returns: none"""

        if (errorColor == 1):
            errorColor = "QTextEdit {color:Green}"
        elif (errorColor == 0):
            errorColor = "QTextEdit {color:red}"
        else:
            # Why did you do this? Read the function? I'm going to make the text white to punish you
            errorColor = "QTextEdit {color:white}"

        node = EditUtil.EditUtil().getParameterNode()
        node.SetParameter("TraceAndSelect,errorMessage", str(errorText))
        node.SetParameter("TraceAndSelect,errorMessageColor", str(errorColor))
        return
コード例 #17
0
    def runQTCGA_NucleiSegYi(self):
        self.currentMessage = "Quick TCGA: running nucleus segmentation ..."
        slicer.util.showStatusMessage(self.currentMessage)
        seedArray = slicer.util.array(self.labelNode.GetName())
        self.qTCGASeedArray[:] = seedArray[:]

        node = EditUtil.EditUtil().getParameterNode(
        )  # get the parameters from MRML
        otsuRatio = float(node.GetParameter("QuickTCGAEffect,otsuRatio"))
        curvatureWeight = float(
            node.GetParameter("QuickTCGAEffect,curvatureWeight")) / 10
        sizeThld = float(node.GetParameter("QuickTCGAEffect,sizeThld"))
        sizeUpperThld = float(
            node.GetParameter("QuickTCGAEffect,sizeUpperThld"))
        mpp = float(node.GetParameter("QuickTCGAEffect,mpp")) / 100

        self.qTCGAMod.SetotsuRatio(otsuRatio)
        self.qTCGAMod.SetcurvatureWeight(curvatureWeight)
        self.qTCGAMod.SetsizeThld(sizeThld)
        self.qTCGAMod.SetsizeUpperThld(sizeUpperThld)
        self.qTCGAMod.Setmpp(mpp)
        AA = self.foregroundNode.GetImageData()
        a1 = 0
        b1 = 0
        ddd = AA.GetDimensions()
        a2 = ddd[0] - 1
        b2 = ddd[1] - 1
        LL = self.labelNode.GetImageData()
        BB = self.GetTile(AA, a1, b1, a2, b2)
        LL = self.GetTile(LL, a1, b1, a2, b2)
        self.qTCGAMod.SetSourceVol(BB)
        self.qTCGAMod.SetSeedVol(LL)
        self.qTCGAMod.Run_NucleiSegYi()
        self.qTCGASegArray[:] = seedArray[:]
        self.MergeImages(LL, self.labelNode.GetImageData(), a1, b1)
        self.foregroundNode.GetImageData().Modified()
        self.foregroundNode.Modified()
        self.labelNode.GetImageData().Modified()
        self.labelNode.Modified()
        self.currentMessage = "Quick TCGA done: nuclei segmetnation is done; press 'F' to enable ROI selection for refinement"
        slicer.util.showStatusMessage(self.currentMessage)
コード例 #18
0
    def __init__(self, sliceLogic):
        print("Preparing Quick TCGA Interaction")
        self.attributes = 'MouseTool'
        self.displayName = 'ShortCut Effect'

        # disconnect all shortcuts that may exist, to allow ShortCut's to work, reconnect once bot is turned off
        if hasattr(slicer.modules, 'EditorWidget'):
            slicer.modules.EditorWidget.removeShortcutKeys()
        self.sliceLogic = sliceLogic
        self.editUtil = EditUtil.EditUtil()
        self.swRed = slicer.app.layoutManager().sliceWidget('Red').sliceLogic()
        self.sw = slicer.app.layoutManager().sliceWidget('Red')
        self.interactor = self.sw.sliceView().interactor()  # initialize to red slice interactor
        # self.computeCurrSliceSmarter()  # initialize the current slice to something meaningful

        self.mouse_obs_growcut, self.swLUT_growcut = bind_view_observers(self.updateShortCutROI)

        # initialize Fast GrowCut
        self.init_ShortCut()

        self.ShortCutCreated = False
コード例 #19
0
 def onSaveButtonClicked(self):
     bundle = EditUtil.EditUtil().getParameterNode().GetParameter(
         'QuickTCGAEffect,erich')
     tran = json.loads(bundle)
     layers = []
     for key in tran:
         nn = tran[key]
         nn["file"] = key + '.tif'
         layers.append(tran[key])
     j = {}
     j['layers'] = layers
     j['username'] = self.setupUserName.text
     j['sourcetile'] = self.tilename
     j['generator'] = "3DSlicer-4.5.0 with SlicerPathology v1.0a"
     j['timestamp'] = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
     labelNodes = slicer.util.getNodes('vtkMRMLLabelMapVolumeNode*')
     savedMessage = 'Segmentations for the following series were saved:\n\n'
     for label in labelNodes.values():
         labelName = label.GetName()
         labelFileName = os.path.join(self.dataDirButton.directory,
                                      labelName + '.tif')
         print "labelFileName : " + labelFileName
         sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
         sNode.SetFileName(labelFileName)
         sNode.SetWriteFileFormat('tif')
         sNode.SetURI(None)
         success = sNode.WriteData(label)
         if success:
             print "successful writing " + labelFileName
         else:
             print "failed writing " + labelFileName
     jstr = json.dumps(j, sort_keys=True, indent=4, separators=(',', ': '))
     f = open(
         os.path.join(self.dataDirButton.directory,
                      self.tilename + '.json'), 'w')
     f.write(jstr)
     f.close()
コード例 #20
0
ファイル: WandEffect.py プロジェクト: pieper/WandEffect
  def apply(self,xy):
    #
    # get the parameters from MRML
    #
    node = EditUtil.EditUtil().getParameterNode()
    tolerance = float(node.GetParameter("WandEffect,tolerance"))
    maxPixels = float(node.GetParameter("WandEffect,maxPixels"))
    paintOver = int(node.GetParameter("LabelEffect,paintOver"))
    
    #
    # get the label and background volume nodes
    #
    labelLogic = self.sliceLogic.GetLabelLayer()
    labelNode = labelLogic.GetVolumeNode()
    backgroundLogic = self.sliceLogic.GetBackgroundLayer()
    backgroundNode = backgroundLogic.GetVolumeNode()

    #
    # get the ijk location of the clicked point
    # by projecting through patient space back into index
    # space of the volume.  Result is sub-pixel, so round it
    # (note: bg and lb will be the same for volumes created
    # by the editor, but can be different if the use selected
    # different bg nodes, but that is not handled here).
    # 
    xyToIJK = labelLogic.GetXYToIJKTransform().GetMatrix()
    ijkFloat = xyToIJK.MultiplyPoint(xy+(0,1))[:3]
    ijk = []
    for element in ijkFloat:
      try:
        intElement = int(round(element))
      except ValueError:
        intElement = 0
      ijk.append(intElement)
    ijk.reverse()
    ijk = tuple(ijk)

    #
    # Get the numpy array for the bg and label
    #
    import vtk.util.numpy_support
    backgroundImage = backgroundNode.GetImageData()
    labelImage = labelNode.GetImageData()
    shape = list(backgroundImage.GetDimensions())
    shape.reverse()
    backgroundArray = vtk.util.numpy_support.vtk_to_numpy(backgroundImage.GetPointData().GetScalars()).reshape(shape)
    labelArray = vtk.util.numpy_support.vtk_to_numpy(labelImage.GetPointData().GetScalars()).reshape(shape)

    if self.fillMode == 'Plane':
      # select the plane corresponding to current slice orientation
      # for the input volume
      ijkPlane = self.sliceIJKPlane()
      i,j,k = ijk
      if ijkPlane == 'JK':
        backgroundDrawArray = backgroundArray[:,:,k]
        labelDrawArray = labelArray[:,:,k]
        ijk = (i, j)
      if ijkPlane == 'IK':
        backgroundDrawArray = backgroundArray[:,j,:]
        labelDrawArray = labelArray[:,j,:]
        ijk = (i, k)
      if ijkPlane == 'IJ':
        backgroundDrawArray = backgroundArray[i,:,:]
        labelDrawArray = labelArray[i,:,:]
        ijk = (j, k)
    elif self.fillMode == 'Volume':
      backgroundDrawArray = backgroundArray
      labelDrawArray = labelArray

    #
    # do a recursive search for pixels to change
    #
    self.undoRedo.saveState()
    value = backgroundDrawArray[ijk]
    label = EditUtil.EditUtil().getLabel()
    lo = value - tolerance
    hi = value + tolerance
    pixelsSet = 0
    toVisit = [ijk,]
    visited = []    
    while toVisit != []:
      location = toVisit.pop(0)
      try:
        l = labelDrawArray[location]
        b = backgroundDrawArray[location]
      except IndexError:
        continue
      if (not paintOver and l != 0):
        # label filled already and not painting over, leave it alone
        continue
      if (paintOver and l == label):
        # label is the current one, but maybe it was filled with another high/low value,
        # so we have to visit it once (and only once) in this session, too
        visitedCurrentLocation = True
        try:
          visited.index(location)
        except ValueError:
          # not found, so not visited yet
          visitedCurrentLocation = False
        if visitedCurrentLocation:        
          continue
        else:
          visited.append(location)
      if b < lo or b > hi:
        continue
      labelDrawArray[location] = label        
      if l != label:
        # only count those pixels that were changed (to allow step-by-step growing by multiple mouse clicks)
        pixelsSet += 1      
      if pixelsSet > maxPixels:
        toVisit = []
      else:
        if self.fillMode == 'Plane':
          # add the 4 neighbors to the stack
          toVisit.append((location[0] - 1, location[1]     ))
          toVisit.append((location[0] + 1, location[1]     ))
          toVisit.append((location[0]    , location[1] - 1 ))
          toVisit.append((location[0]    , location[1] + 1 ))
        elif self.fillMode == 'Volume':
          # add the 6 neighbors to the stack
          toVisit.append((location[0] - 1, location[1]    , location[2]    ))
          toVisit.append((location[0] + 1, location[1]    , location[2]    ))
          toVisit.append((location[0]    , location[1] - 1, location[2]    ))
          toVisit.append((location[0]    , location[1] + 1, location[2]    ))
          toVisit.append((location[0]    , location[1]    , location[2] - 1))
          toVisit.append((location[0]    , location[1]    , location[2] + 1))

    # signal to slicer that the label needs to be updated
    labelImage.Modified()
    labelNode.Modified()
コード例 #21
0
ファイル: TraceAndSelect.py プロジェクト: FastSlice/Extension
    def fill(self,
             ijk,
             optional_seeds=[],
             mode=0,
             forced_path=None,
             forced_point=None):
        print("Mode: %d" % mode)
        paintOver = 1
        mean = (0, 0)
        count = 0
        node = EditUtil.EditUtil().getParameterNode()

        # Max number of pixels to fill in (does not include path)
        print("@@@MaxPixels:%s" %
              node.GetParameter("TraceAndSelect,maxPixels"))
        maxPixels = float(node.GetParameter("TraceAndSelect,maxPixels"))

        # Minimum intensity value to be detected
        print("@@@Theshold Min:%s" %
              node.GetParameter("TraceAndSelect,paintThresholdMin"))
        thresholdMin = float(
            node.GetParameter("TraceAndSelect,paintThresholdMin"))

        # Maximum intensity value to be detected
        print("@@@Theshold Max:%s" %
              node.GetParameter("TraceAndSelect,paintThresholdMax"))
        thresholdMax = float(
            node.GetParameter("TraceAndSelect,paintThresholdMax"))

        labelLogic = self.sliceLogic.GetLabelLayer()
        labelNode = labelLogic.GetVolumeNode()
        backgroundLogic = self.sliceLogic.GetBackgroundLayer()
        backgroundNode = backgroundLogic.GetVolumeNode()

        import vtk.util.numpy_support, numpy
        backgroundImage = backgroundNode.GetImageData()
        labelImage = labelNode.GetImageData()
        shape = list(backgroundImage.GetDimensions())
        shape.reverse()
        backgroundArray = vtk.util.numpy_support.vtk_to_numpy(
            backgroundImage.GetPointData().GetScalars()).reshape(shape)
        labelArray = vtk.util.numpy_support.vtk_to_numpy(
            labelImage.GetPointData().GetScalars()).reshape(shape)

        ijk_reconstruction_indexes = []
        # THIS SHOULD ALWAYS BE TRUE
        # VOLUME MODE IS DISABLED BECAUSE I HAVE NO CLUE WHAT IT IS
        original_ijk = list(ijk)
        if self.fillMode == 'Plane':
            # select the plane corresponding to current slice orientation
            # for the input volume
            ijkPlane = self.sliceIJKPlane()
            i, j, k = ijk
            if ijkPlane == 'JK':
                backgroundDrawArray = backgroundArray[:, :, k]
                labelDrawArray = labelArray[:, :, k]
                ijk = (i, j)
                ijk_reconstruction_indexes = (0, 1)
            if ijkPlane == 'IK':
                backgroundDrawArray = backgroundArray[:, j, :]
                labelDrawArray = labelArray[:, j, :]
                ijk = (i, k)
                ijk_reconstruction_indexes = (0, 2)
            if ijkPlane == 'IJ':
                backgroundDrawArray = backgroundArray[i, :, :]
                labelDrawArray = labelArray[i, :, :]
                ijk = (j, k)
                ijk_reconstruction_indexes = (1, 2)
        else:
            print(
                "HOW DID YOU DO THAT??? WHAT DID YOU DO TO ACTIVATE VOLUME MODE???"
            )
            self.setErrorMessage("Error: volume mode not supported.")
            return

        # Log info about where the user clicked for debugging purposes
        value = backgroundDrawArray[ijk]
        print("@@@location=", ijk)
        print("@@@value=", value)

        # Get the current label that the user wishes to assign using the tool
        label = EditUtil.EditUtil().getLabel()

        # Use lo and hi for threshold checks
        # Easiest way to do things is check if a pixel is outside the threshold, ie.

        lo = thresholdMin
        hi = thresholdMax

        best_path = []
        fill_point = ijk

        if mode == 0 and forced_path is not None and forced_point is not None:
            best_path = forced_path
            fill_point = forced_point
        else:
            # Build path

            best_path, visited, dead_ends = gimme_a_path(
                ijk, 200, hi, lo, backgroundDrawArray, optional_seeds)
            print("@@@Dead ends:", dead_ends)

            attempts = 0
            max_attempts = 2
            while dead_ends > 150 or dead_ends < 0 and attempts < max_attempts:
                attempts += 1
                lo -= 25
                print("Lowering min tolerance to:", lo)
                node.SetParameter("LabelEffect,paintThresholdMin", str(lo))
                best_path, visited, dead_ends = gimme_a_path(
                    ijk, 200, hi, lo, backgroundDrawArray, optional_seeds)
                print("@@@Dead ends:", dead_ends)

            if dead_ends < 0:
                print("@@@No path found? Weird.")
                self.setErrorMessage(
                    "Error: could not find any suitable path.")
                return

            # Save state before doing anything
            self.undoRedo.saveState()
            for pixel in visited:
                labelDrawArray[pixel] = label

            EditUtil.EditUtil().markVolumeNodeAsModified(labelNode)

            if mode == 1:  # Outline only mode
                print("Outline made, returning.")
                self.setErrorMessage(
                    "Preview complete. No errrors detected.\nLeft click to confirm.\nRight click to try a new outline.\nUndo to remove.",
                    1)
                return (best_path, ijk)

        #
        # Fill path
        #

        # Fill the path using a recursive search
        toVisit = [
            fill_point,
        ]
        extrema = get_extrema(best_path)
        # Create a map that contains the location of the pixels
        # that have been already visited (added or considered to be added).
        # This is required if paintOver is enabled because then we reconsider
        # all pixels (not just the ones that have not labelled yet).
        if paintOver:
            labelDrawVisitedArray = numpy.zeros(labelDrawArray.shape,
                                                dtype='bool')

        pixelsSet = 0
        print("@@@FILLING PATH")
        while toVisit != []:
            location = toVisit.pop(0)

            try:
                l = fetch_val(labelDrawArray, location)
                b = fetch_val(backgroundDrawArray, location)
            except IndexError:
                continue
            if (not paintOver and l != 0):
                # label filled already and not painting over, leave it alone
                continue
            try:
                if (paintOver and l == label):
                    temp1 = mean[0] + location[0]
                    temp2 = mean[1] + location[1]
                    mean = (temp1, temp2)
                    count += 1
                    # label is the current one, but maybe it was filled with another high/low value,
                    # so we have to visit it once (and only once) in this session, too
                    if labelDrawVisitedArray[location]:
                        # visited already, so don't try to fill it again
                        continue
                    else:
                        # we'll visit this pixel now, so mark it as visited
                        labelDrawVisitedArray[location] = True
            except ValueError:
                print("@@@VALUE ERROR!", l)
                print("@@@Location: ", location)
                print("@@@fill_point:", fill_point)
                print("@@@toVisit:", toVisit)
                continue
            if location in best_path:
                continue
            if not (extrema[0] < location[0] < extrema[1]
                    and extrema[2] < location[1] < extrema[3]):
                # Went out of bounds for path
                print("@@@WENT OUT OF BOUNDS FOR PATH!")
                self.setErrorMessage("Error: Went out of bounds for path.")
                self.undoRedo.undo()
                return
            labelDrawArray[location] = label
            if l != label:
                # only count those pixels that were changed (to allow step-by-step growing by multiple mouse clicks)
                pixelsSet += 1
            if pixelsSet > maxPixels:
                toVisit = []
            else:
                # add the 4 neighbors to the stack
                toVisit.append((location[0] - 1, location[1]))
                toVisit.append((location[0] + 1, location[1]))
                toVisit.append((location[0], location[1] - 1))
                toVisit.append((location[0], location[1] + 1))

        # signal to slicer that the label needs to be updated
        ## CHANGE OFFSET
        print("@@@Offset:|%s|" %
              node.GetParameter("TraceAndSelect,offsetvalue"))

        self.offset = float(node.GetParameter("TraceAndSelect,offsetvalue"))
        print("OFFSET SIGN: %s" % math.copysign(1, self.offset))

        if self.offset != 0:
            slices_seen = self.progress.maximum - abs(self.offset)
            if self.progress.wasCanceled:
                self.offset = 0
                layoutManager = slicer.app.layoutManager()
                widget = layoutManager.sliceWidget('Red')
                rednode = widget.sliceLogic().GetSliceNode()
                rednode.SetSliceOffset(rednode.GetSliceOffset() +
                                       math.copysign(1, self.offset))
                node.SetParameter("TraceAndSelect,offsetvalue", str(0))
                self.setErrorMessage(
                    "Fill abandoned after {} slice(s)".format(
                        int(slices_seen)), 1)
                return
            self.progress.setValue(slices_seen)
            layoutManager = slicer.app.layoutManager()
            widget = layoutManager.sliceWidget('Red')
            rednode = widget.sliceLogic().GetSliceNode()
            rednode.SetSliceOffset(rednode.GetSliceOffset() +
                                   math.copysign(1, self.offset))
            node.SetParameter("TraceAndSelect,offsetvalue",
                              str(self.offset - math.copysign(1, self.offset)))
            print(self.offset)

            ### Calc centoid mean stuff here

            recs_mean = (mean[0] / count, mean[1] / count)
            rec_mean = get_optional_seeds(best_path, recs_mean)[0]
            print("MEAN:", rec_mean, recs_mean)
            rec_ijk = list(original_ijk)
            for i in range(0, 3):
                rec_ijk[i] = int(rec_ijk[i] +
                                 int(math.copysign(1, self.offset)))
            rec_ijk[ijk_reconstruction_indexes[0]] = rec_mean[0]
            rec_ijk[ijk_reconstruction_indexes[1]] = rec_mean[1]
            print("RECURSIVE IJK:", rec_ijk)
            print("#########RECURSE#########")
            return self.fill(rec_ijk,
                             optional_seeds=get_optional_seeds(
                                 best_path, recs_mean))

            ###

        print("@@@FILL DONE")
        EditUtil.EditUtil().markVolumeNodeAsModified(labelNode)
        self.setErrorMessage("Fill complete. No errors detected.", 1)

        return
コード例 #22
0
  def apply(self,xy):
    # TODO: save the undo state - not yet available for extensions
    # EditorStoreCheckPoint $_layers(label,node)
    
    #
    # get the parameters from MRML
    #
    node = EditUtil.EditUtil().getParameterNode()
    tolerance = float(node.GetParameter("GooCut,tolerance"))
    maxPixels = float(node.GetParameter("GooCut,maxPixels"))


    #
    # get the label and background volume nodes
    #
    labelLogic = self.sliceLogic.GetLabelLayer()
    labelNode = labelLogic.GetVolumeNode()
    labelNode.SetModifiedSinceRead(1)
    backgroundLogic = self.sliceLogic.GetBackgroundLayer()
    backgroundNode = backgroundLogic.GetVolumeNode()

    #
    # get the ijk location of the clicked point
    # by projecting through patient space back into index
    # space of the volume.  Result is sub-pixel, so round it
    # (note: bg and lb will be the same for volumes created
    # by the editor, but can be different if the use selected
    # different bg nodes, but that is not handled here).
    # 
    xyToIJK = labelLogic.GetXYToIJKTransform().GetMatrix()
    ijkFloat = xyToIJK.MultiplyPoint(xy+(0,1))[:3]
    ijk = []
    for element in ijkFloat:
      try:
        intElement = int(element)
      except ValueError:
        intElement = 0
      ijk.append(intElement)
    ijk.reverse()
    ijk = tuple(ijk)

    #
    # Get the numpy array for the bg and label
    #
    import vtk.util.numpy_support
    backgroundImage = backgroundNode.GetImageData()
    labelImage = labelNode.GetImageData()
    shape = list(backgroundImage.GetDimensions())
    shape.reverse()
    backgroundArray = vtk.util.numpy_support.vtk_to_numpy(backgroundImage.GetPointData().GetScalars()).reshape(shape)
    labelArray = vtk.util.numpy_support.vtk_to_numpy(labelImage.GetPointData().GetScalars()).reshape(shape)

    #
    # do a region growing
    #
    try:
      value = backgroundArray[ijk]
    except IndexError:
      # outside of volume
      return
    label = EditUtil.EditUtil().getLabel()
    lo = value - tolerance
    hi = value + tolerance
    pixelsSet = 0
    toVisit = [ijk,]
    while toVisit != []:
      location = toVisit.pop()
      try:
        l = labelArray[location]
        b = backgroundArray[location]
      except IndexError:
        continue
      if l != 0 or b < lo or b > hi:
        continue
      labelArray[location] = label
      pixelsSet += 1
      if pixelsSet > maxPixels:
        toVisit = []
      else:
        # add the 6 neighbors to the stack
        toVisit.append((location[0] - 1, location[1]    , location[2]    ))
        toVisit.append((location[0] + 1, location[1]    , location[2]    ))
        toVisit.append((location[0]    , location[1] - 1, location[2]    ))
        toVisit.append((location[0]    , location[1] + 1, location[2]    ))
        toVisit.append((location[0]    , location[1]    , location[2] - 1))
        toVisit.append((location[0]    , location[1]    , location[2] + 1))

    labelImage.Modified()
    labelNode.Modified()
コード例 #23
0
ファイル: TraceAndSelect.py プロジェクト: FastSlice/Extension
    def processEvent(self, caller=None, event=None):
        """
    handle events from the render window interactor
    """

        node = EditUtil.EditUtil().getParameterNode()
        preview = int(node.GetParameter("TraceAndSelect,preview"))
        # Clear any saved outlines if preview has been just disabled
        if not preview:
            if self.prevPath != []:
                self.prevPath = []
                self.prevFillPoint = None
                self.undoRedo.undo()

        # let the superclass deal with the event if it wants to
        super(TraceAndSelectTool, self).processEvent(caller, event)

        # LEFT CLICK
        if event == "LeftButtonPressEvent":
            xy = self.interactor.GetEventPosition()
            sliceLogic = self.sliceWidget.sliceLogic()
            logic = TraceAndSelectLogic(sliceLogic)
            logic.undoRedo = self.undoRedo
            if self.prevPath != []:
                logic.apply(xy,
                            forced_path=self.prevPath,
                            forced_point=self.prevFillPoint)
                self.prevPath = []
                self.prevFillPoint = None
            else:
                logic.apply(xy)
            print("Got a %s at %s in %s" %
                  (event, str(xy),
                   self.sliceWidget.sliceLogic().GetSliceNode().GetName()))
            self.abortEvent(event)
        # RIGHT CLICK
        elif event == "RightButtonPressEvent" and preview:
            xy = self.interactor.GetEventPosition()
            sliceLogic = self.sliceWidget.sliceLogic()
            logic = TraceAndSelectLogic(sliceLogic)
            logic.undoRedo = self.undoRedo
            # Erase stored path and remove from view
            if self.prevPath != []:
                self.prevPath = []
                self.prevFillPoint = None
                logic.undoRedo.undo()
            # Store prevPath and prevFillPoint
            self.prevPath, self.prevFillPoint = logic.apply(xy, 1)
            print("Got a %s at %s in %s" %
                  (event, str(xy),
                   self.sliceWidget.sliceLogic().GetSliceNode().GetName()))
            self.abortEvent(event)
        # SLICE VIEW HAS CHANGED
        elif event == "ModifiedEvent":  # Offset was changed on one of the viewing panels
            # Erase stored path and remove from view
            if self.prevPath != []:
                self.prevPath = []
                self.prevFillPoint = None
                self.undoRedo.undo()
                sliceLogic = self.sliceWidget.sliceLogic()
                logic = TraceAndSelectLogic(sliceLogic)
                logic.setErrorMessage("Previewed path was discarded.", 1)

        else:
            pass

        # events from the slice node
        if caller and caller.IsA('vtkMRMLSliceNode'):
            # here you can respond to pan/zoom or other changes
            # to the view
            pass
コード例 #24
0
    def init_QuickTCGA(self):
        self.emergencyStopFunc = None
        self.dialogBox = qt.QMessageBox(
        )  #will display messages to draw users attention if he does anything wrong
        self.dialogBox.setWindowTitle("QuickTCGA Error")
        self.dialogBox.setWindowModality(
            qt.Qt.NonModal
        )  #will allow user to continue interacting with Slicer

        # TODO: check this claim- might be causing leaks
        # set the image, label nodes (this will not change although the user can
        # alter what is bgrnd/frgrnd in editor)
        # Confused about how info propagates UIarray to UIVol, not the other way, NEEDS AUTO TESTS

        self.labelNode = self.editUtil.getLabelVolume(
        )  #labelLogic.GetVolumeNode()
        self.backgroundNode = self.editUtil.getBackgroundVolume(
        )  #backgroundLogic.GetVolumeNode()
        self.foregroundNode = self.swRed.GetForegroundLayer().GetVolumeNode()

        #perform safety check on right images/labels being selected, #set up images
        #if red slice doesnt have a label or image, go no further
        if type(self.backgroundNode) == type(None) or type(
                self.labelNode) == type(None):
            self.dialogBox.setText(
                "Either Image (must be Background Image) or Label not set in slice views."
            )
            self.dialogBox.show()

        if self.emergencyStopFunc:
            self.emergencyStopFunc()
            return

        volumesLogic = slicer.modules.volumes.logic()

        self.labelName = self.labelNode.GetName(
        )  # record name of label so user, cant trick us
        self.imgBgrdName = self.backgroundNode.GetName()
        self.imgFgrdName = self.foregroundNode.GetName()

        if self.sliceViewMatchEditor(
                self.sliceLogic
        ) == False:  # do nothing, exit function if user has played with images
            if self.emergencyStopFunc:
                self.emergencyStopFunc()
                return

        # QuickTCGA shortcuts

    ##resetQTCGAKey = qt.QKeySequence(qt.Qt.Key_R) # reset initialization flag
    ##runQTCGAClusterKey = qt.QKeySequence(qt.Qt.Key_S) # run fast growcut
        runNucleiSegKey = qt.QKeySequence(qt.Qt.Key_Y)
        ##editTCGAKey = qt.QKeySequence(qt.Qt.Key_E) # edit seed labels
        ##runQTCGATemplateKey = qt.QKeySequence(qt.Qt.Key_T)
        ##runQTCGARefineCurvatureKey = qt.QKeySequence(qt.Qt.Key_U)
        ##runQTCGAShortCutKey = qt.QKeySequence(qt.Qt.Key_C)
        ##runQTCGAShortEditCutKey = qt.QKeySequence(qt.Qt.Key_F)

        print " key to run QuickTCGA segmentation is  Y"

        self.qtkeyconnections = []
        self.qtkeydefsQTCGA = [[runNucleiSegKey, self.runQTCGA_NucleiSegYi]]

        for keydef in self.qtkeydefsQTCGA:
            s = qt.QShortcut(keydef[0], slicer.util.mainWindow()
                             )  # connect this qt event to mainWindow focus
            s.connect('activated()', keydef[1])
            self.qtkeyconnections.append(s)

        self.qTCGALabMod_tag = self.sliceLogic.AddObserver(
            "ModifiedEvent", self.QTCGAChangeLabelInput
        )  # put test listener on the whole window

        # Quick TCGA parameters
        self.bEditTCGA = True
        self.bEditShortCut = False
        self.currentMessage = ""

        seedArray = slicer.util.array(self.labelName)
        self.qTCGASeedArray = seedArray.copy()
        self.qTCGASegArray = seedArray.copy()
        self.qTCGASeedArray[:] = 0
        self.qTCGASegArray[:] = 0

        self.SCutROIRad = 50
        self.volSize = self.labelNode.GetImageData().GetDimensions()
        self.qSCutROIArray = seedArray.copy(
        )  #np.zeros([self.volSize[0],self.volSize[1],1])
        self.qSCutROIArray[:] = 0

        roiVTK = vtk.vtkImageData()
        roiVTK.DeepCopy(self.labelNode.GetImageData())
        self.roiVTK = roiVTK

        import vtkSlicerQuickTCGAModuleLogicPython

        node = EditUtil.EditUtil().getParameterNode(
        )  # get the parameters from MRML
        otsuRatio = float(node.GetParameter("QuickTCGAEffect,otsuRatio"))
        curvatureWeight = float(
            node.GetParameter("QuickTCGAEffect,curvatureWeight")) / 10
        sizeThld = float(node.GetParameter("QuickTCGAEffect,sizeThld"))
        sizeUpperThld = float(
            node.GetParameter("QuickTCGAEffect,sizeUpperThld"))
        mpp = float(node.GetParameter("QuickTCGAEffect,mpp")) / 100
        cparams["otsuRatio"] = otsuRatio
        cparams["curvatureWeight"] = curvatureWeight
        cparams["sizeThld"] = sizeThld
        cparams["sizeUpperThld"] = sizeUpperThld
        cparams["mpp"] = mpp
        qTCGAMod = vtkSlicerQuickTCGAModuleLogicPython.vtkQuickTCGA()
        qTCGAMod.SetSourceVol(self.foregroundNode.GetImageData())
        qTCGAMod.SetotsuRatio(otsuRatio)
        qTCGAMod.SetcurvatureWeight(curvatureWeight)
        qTCGAMod.SetsizeThld(sizeThld)
        qTCGAMod.SetsizeUpperThld(sizeUpperThld)
        qTCGAMod.Setmpp(mpp)
        qTCGAMod.Initialization()
        self.qTCGAMod = qTCGAMod
        self.QuickTCGACreated = True  #tracks if completed the initializtion (so can do stop correctly) of KSlice
  def test_ThresholdThreading(self):
    """
    Replicate the issue reported in bug 1822 where splitting
    a grow-cut produced volume causes a multi-threading related
    issue on mac release builds
    """
    self.delayDisplay("Starting the test")

    #
    # first, get some sample data
    #
    self.delayDisplay("Get some data")
    import SampleData
    head = SampleData.downloadSample("MRHead")

    #
    # now, define an ROI in it
    #
    roi = slicer.vtkMRMLAnnotationROINode()
    slicer.mrmlScene.AddNode(roi)
    roi.SetXYZ(-2, 104, -80)
    roi.SetRadiusXYZ(30, 30, 30)

    #
    # apply the cropping to the head
    #
    cropLogic = slicer.modules.cropvolume.logic()
    cvpn = slicer.vtkMRMLCropVolumeParametersNode()
    cvpn.SetROINodeID( roi.GetID() )
    cvpn.SetInputVolumeNodeID( head.GetID() )
    cropLogic.Apply( cvpn )
    croppedHead = slicer.mrmlScene.GetNodeByID( cvpn.GetOutputVolumeNodeID() )

    #
    # create a label map and set it for editing
    #
    volumesLogic = slicer.modules.volumes.logic()
    croppedHeadLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, croppedHead, croppedHead.GetName() + '-label' )
    selectionNode = slicer.app.applicationLogic().GetSelectionNode()
    selectionNode.SetActiveVolumeID( croppedHead.GetID() )
    selectionNode.SetActiveLabelVolumeID( croppedHeadLabel.GetID() )
    slicer.app.applicationLogic().PropagateVolumeSelection(0)


    #
    # got to the editor and do some drawing
    #
    self.delayDisplay("Paint some things")
    parameterNode = EditUtil.getParameterNode()
    lm = slicer.app.layoutManager()
    paintEffect = EditorLib.PaintEffectOptions()
    paintEffect.setMRMLDefaults()
    paintEffect.__del__()
    sliceWidget = lm.sliceWidget('Red')
    paintTool = EditorLib.PaintEffectTool(sliceWidget)
    EditUtil.setLabel(1)
    paintTool.paintAddPoint(100,100)
    paintTool.paintApply()
    EditUtil.setLabel(2)
    paintTool.paintAddPoint(200,200)
    paintTool.paintApply()
    paintTool.cleanup()
    paintTool = None

    self.delayDisplay("Now grow cut")

    #
    # now do GrowCut
    #
    growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic())
    growCutLogic.growCut()

    #
    # now split the volume, merge it back, and see if it looks right
    #
    preArray = slicer.util.array(croppedHeadLabel.GetName())
    slicer.util.selectModule('Editor')
    slicer.util.findChildren(text='Split Merge Volume')[0].clicked()
    slicer.util.findChildren(text='Merge All')[0].clicked()
    postArray = slicer.util.array(croppedHeadLabel.GetName())

    if (postArray - preArray).max() != 0:
      print("!$!$!#!@#!@!@$%! Test Failed!!")
    else:
      print("Ahh... test passed.")

    self.assertEqual((postArray - preArray).max(), 0)

    self.delayDisplay("Test passed!")
コード例 #26
0
  def test_sceneImport24281(self):
    """ Ideally you should have several levels of tests.  At the lowest level
    tests should exercise the functionality of the logic with different inputs
    (both valid and invalid).  At higher levels your tests should emulate the
    way the user would interact with your code and confirm that it still works
    the way you intended.
    One of the most important features of the tests is that it should alert other
    developers when their changes will have an impact on the behavior of your
    module.  For example, if a developer removes a feature that you depend on,
    your test should break so they know that the feature is needed.
    """

    self.delayDisplay("Starting the test")
    #
    # first, get some data
    #
    self.delayDisplay("Getting Data")
    import SampleData
    head = SampleData.downloadSample("MRHead")

    #
    # create a label map and set it for editing
    #
    self.delayDisplay("Setting up LabelMap")
    volumesLogic = slicer.modules.volumes.logic()
    headLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, head, head.GetName() + '-label' )
    selectionNode = slicer.app.applicationLogic().GetSelectionNode()
    selectionNode.SetActiveVolumeID( head.GetID() )
    selectionNode.SetActiveLabelVolumeID( headLabel.GetID() )
    slicer.app.applicationLogic().PropagateVolumeSelection(0)

    #
    # got to the editor and do some drawing
    #
    self.delayDisplay("Setting up Editor and drawing")
    parameterNode = EditUtil.getParameterNode()
    lm = slicer.app.layoutManager()
    paintEffectOptions = EditorLib.PaintEffectOptions()
    paintEffectOptions.setMRMLDefaults()
    paintEffectOptions.__del__()

    self.delayDisplay('Paint radius is %s' % parameterNode.GetParameter('PaintEffect,radius'))
    sliceWidget = lm.sliceWidget('Red')
    size = min(sliceWidget.width,sliceWidget.height)
    step = int(size / 12)
    center = int(size / 2)
    parameterNode.SetParameter('PaintEffect,radius', '20')
    paintTool = EditorLib.PaintEffectTool(sliceWidget)
    self.delayDisplay('Paint radius is %s, tool radius is %d' % (parameterNode.GetParameter('PaintEffect,radius'),paintTool.radius))
    for label in range(1,5):
      EditUtil.setLabel(label)
      pos = center - 2*step + (step * label)
      self.delayDisplay('Painting %d, at  (%d,%d)' % (label,pos,pos),200)
      paintTool.paintAddPoint(pos,pos)
      paintTool.paintApply()
    paintTool.cleanup()
    paintTool = None

    #
    # now build:
    # create a model using the command line module
    # based on the current editor parameters
    # - make a new hierarchy node
    #

    self.delayDisplay( "Building..." )

    parameters = {}
    parameters["InputVolume"] = headLabel.GetID()
    # create models for all labels
    parameters["JointSmoothing"] = True
    parameters["StartLabel"] = -1
    parameters["EndLabel"] = -1
    outHierarchy = slicer.vtkMRMLModelHierarchyNode()
    outHierarchy.SetScene( slicer.mrmlScene )
    outHierarchy.SetName( "sceneImport2428Hierachy" )
    slicer.mrmlScene.AddNode( outHierarchy )
    parameters["ModelSceneFile"] = outHierarchy

    modelMaker = slicer.modules.modelmaker
    self.CLINode = None
    self.CLINode = slicer.cli.runSync(modelMaker, self.CLINode, parameters, delete_temporary_files=False)

    self.delayDisplay("Models built")

    success = self.verifyModels()

    success = success and (slicer.mrmlScene.GetNumberOfNodesByClass( "vtkMRMLModelNode" ) > 3)

    self.delayDisplay("Test finished")

    if success:
      self.delayDisplay("Ahh... test passed.")
    else:
      self.delayDisplay("!$!$!#!@#!@!@$%! Test Failed!!")

    self.assertTrue(success)