Example #1
1
  def run(self, fixed, moving, outputTrans, meanDistanceType, 
						landmarkTransformType, numberOfLandmarks, maxDistance, 
								numberOfIterations, matchCentroids, checkMeanDistance):
    """Run the actual algorithm"""	
    inputPolyData = moving.GetPolyData() 
    
    icp = vtk.vtkIterativeClosestPointTransform()
	
    icp.SetSource(inputPolyData)
    icp.SetTarget(fixed.GetPolyData())

    if landmarkTransformType == "RigidBody":
      icp.GetLandmarkTransform().SetModeToRigidBody()
    elif landmarkTransformType == "Similarity":
      icp.GetLandmarkTransform().SetModeToSimilarity()
    elif landmarkTransformType == "Affine":    
      icp.GetLandmarkTransform().SetModeToAffine()
	  
    if meanDistanceType == "RMS":
      icp.SetMeanDistanceModeToRMS()
    elif meanDistanceType == "Absolute Value":
      icp.SetMeanDistanceModeToAbsoluteValue()
	  
    icp.SetMaximumNumberOfIterations(numberOfIterations)
    icp.SetMaximumMeanDistance(maxDistance)
    icp.SetMaximumNumberOfLandmarks(numberOfLandmarks)
    icp.SetCheckMeanDistance(int(checkMeanDistance))
    icp.SetStartByMatchingCentroids(int(matchCentroids))
    icp.Update()
	
    outputMatrix = vtk.vtkMatrix4x4()
    icp.GetMatrix(outputMatrix)
    outputTrans.SetAndObserveMatrixTransformToParent(outputMatrix)
    
    return
Example #2
0
  def run(self, inputFiducials, inputModel, outputTransform, transformType=0, numIterations=100):
    """Run iterative closest point registration."""
    logging.info('Running iterative closest point registration')

    fiducialsPolyData = vtk.vtkPolyData()
    self.FiducialsToPolyData(inputFiducials, fiducialsPolyData)

    icpTransform = vtk.vtkIterativeClosestPointTransform()
    icpTransform.SetSource(fiducialsPolyData)
    icpTransform.SetTarget(inputModel.GetPolyData())
    icpTransform.GetLandmarkTransform().SetModeToRigidBody()
    if transformType == 1:
      icpTransform.GetLandmarkTransform().SetModeToSimilarity()
    if transformType == 2:
      icpTransform.GetLandmarkTransform().SetModeToAffine()
    icpTransform.SetMaximumNumberOfIterations(numIterations)
    icpTransform.Modified()
    icpTransform.Update()

    outputTransform.SetMatrixTransformToParent(icpTransform.GetMatrix())
    if slicer.app.majorVersion >= 5 or (slicer.app.majorVersion >= 4 and slicer.app.minorVersion >= 11):
      outputTransform.SetNodeReferenceID(slicer.vtkMRMLTransformNode.GetMovingNodeReferenceRole(),
                                         inputFiducials.GetID())
      outputTransform.SetNodeReferenceID(slicer.vtkMRMLTransformNode.GetFixedNodeReferenceRole(),
                                         inputModel.GetID())

    return True
    def run(self,
            inputFiducials,
            inputModel,
            outputTransform,
            transformType=0,
            numIterations=100):

        self.delayDisplay('Running iterative closest point registration')

        fiducialsPolyData = vtk.vtkPolyData()
        self.FiducialsToPolyData(inputFiducials, fiducialsPolyData)

        icpTransform = vtk.vtkIterativeClosestPointTransform()
        icpTransform.SetSource(fiducialsPolyData)
        icpTransform.SetTarget(inputModel.GetPolyData())
        icpTransform.GetLandmarkTransform().SetModeToRigidBody()
        if transformType == 1:
            icpTransform.GetLandmarkTransform().SetModeToSimilarity()
        if transformType == 2:
            icpTransform.GetLandmarkTransform().SetModeToAffine()
        icpTransform.SetMaximumNumberOfIterations(numIterations)
        icpTransform.Modified()
        icpTransform.Update()

        outputTransform.SetMatrixTransformToParent(icpTransform.GetMatrix())

        return True
Example #4
0
  def run(self, inputSourceModel, inputTargetModel, outputSourceToTargetTransform, transformType=0, numIterations=100 ):

    self.delayDisplay('Running iterative closest point registration')

    icpTransform = vtk.vtkIterativeClosestPointTransform()
    icpTransform.SetSource( inputSourceModel.GetPolyData() )
    icpTransform.SetTarget( inputTargetModel.GetPolyData() )
    icpTransform.GetLandmarkTransform().SetModeToRigidBody()
    if transformType == 1:
      icpTransform.GetLandmarkTransform().SetModeToSimilarity()
    if transformType == 2:
      icpTransform.GetLandmarkTransform().SetModeToAffine()
    icpTransform.SetMaximumNumberOfIterations( numIterations )
    icpTransform.Modified()
    icpTransform.Update()

    outputSourceToTargetTransform.SetMatrixTransformToParent( icpTransform.GetMatrix() )

    return True
  def run(self, inputFiducials, inputModel, outputTransform, transformType=0, numIterations=100 ):

    self.delayDisplay('Running iterative closest point registration')

    fiducialsPolyData = vtk.vtkPolyData()
    self.FiducialsToPolyData(inputFiducials, fiducialsPolyData)

    icpTransform = vtk.vtkIterativeClosestPointTransform()
    icpTransform.SetSource( fiducialsPolyData )
    icpTransform.SetTarget( inputModel.GetPolyData() )
    icpTransform.GetLandmarkTransform().SetModeToRigidBody()
    if transformType == 1:
      icpTransform.GetLandmarkTransform().SetModeToSimilarity()
    if transformType == 2:
      icpTransform.GetLandmarkTransform().SetModeToAffine()
    icpTransform.SetMaximumNumberOfIterations( numIterations )
    icpTransform.Modified()
    icpTransform.Update()

    outputTransform.SetMatrixTransformToParent( icpTransform.GetMatrix() )
    outputTransform.AddNodeReferenceID(slicer.vtkMRMLTransformNode.GetMovingNodeReferenceRole(), inputFiducials.GetID())
    outputTransform.AddNodeReferenceID(slicer.vtkMRMLTransformNode.GetFixedNodeReferenceRole(), inputModel.GetID())

    return True
Example #6
0
    def setup(self):
        """Instantiate and connect widgets ..."""

        self.scene = slicer.mrmlScene
        self.icp = vtk.vtkIterativeClosestPointTransform()

        #
        # Reload and Test area
        #
        reloadCollapsibleButton = ctk.ctkCollapsibleButton()
        reloadCollapsibleButton.text = "Reload && Test"
        self.layout.addWidget(reloadCollapsibleButton)
        reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

        # reload button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadButton = qt.QPushButton("Reload")
        self.reloadButton.toolTip = "Reload this module."
        self.reloadButton.name = "SurfaceICPRegistration Reload"
        reloadFormLayout.addWidget(self.reloadButton)
        self.reloadButton.connect('clicked()', self.onReload)

        # reload and test button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadAndTestButton = qt.QPushButton("Reload and Test")
        self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
        reloadFormLayout.addWidget(self.reloadAndTestButton)
        self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

        #
        # Input Surface Volume Collapsible Button
        #
        inputSurfaceCollapsibleButton = ctk.ctkCollapsibleButton()
        inputSurfaceCollapsibleButton.text = "Input Surface Volumes"
        self.layout.addWidget(inputSurfaceCollapsibleButton)
        inputSurfaceFormLayout = qt.QFormLayout(inputSurfaceCollapsibleButton)

        #
        # Input Surface Volume Options
        #
        self.modelSelectors = {}
        self.viewNames = ("Fixed Surface Volume", "Moving Surface Volume")
        for viewName in self.viewNames:
            self.modelSelectors[viewName] = slicer.qMRMLNodeComboBox()
            self.modelSelectors[viewName].nodeTypes = (("vtkMRMLModelNode"),
                                                       "")
            self.modelSelectors[viewName].selectNodeUponCreation = False
            self.modelSelectors[viewName].addEnabled = False
            self.modelSelectors[viewName].removeEnabled = True
            self.modelSelectors[viewName].noneEnabled = True
            self.modelSelectors[viewName].showHidden = False
            self.modelSelectors[viewName].showChildNodeTypes = True
            self.modelSelectors[viewName].setMRMLScene(slicer.mrmlScene)
            self.modelSelectors[viewName].setToolTip(
                "Pick the %s surface volume." % viewName.lower())
            inputSurfaceFormLayout.addRow("%s" % viewName,
                                          self.modelSelectors[viewName])

#
# Input Inicial Transform Options
#
        self.volumeInitialTransformSelectors = {}
        self.volumeInitialTransformSelectors[
            "Initial Transform"] = slicer.qMRMLNodeComboBox()
        self.volumeInitialTransformSelectors["Initial Transform"].nodeTypes = (
            ("vtkMRMLLinearTransformNode"), "")
        self.volumeInitialTransformSelectors[
            "Initial Transform"].selectNodeUponCreation = False
        self.volumeInitialTransformSelectors[
            "Initial Transform"].addEnabled = False
        self.volumeInitialTransformSelectors[
            "Initial Transform"].removeEnabled = True
        self.volumeInitialTransformSelectors[
            "Initial Transform"].noneEnabled = True
        self.volumeInitialTransformSelectors[
            "Initial Transform"].showHidden = False
        self.volumeInitialTransformSelectors[
            "Initial Transform"].showChildNodeTypes = True
        self.volumeInitialTransformSelectors["Initial Transform"].setMRMLScene(
            slicer.mrmlScene)
        self.volumeInitialTransformSelectors["Initial Transform"].setToolTip(
            "Pick the initial Transform file")
        inputSurfaceFormLayout.addRow(
            "(Optional) Initial Transform",
            self.volumeInitialTransformSelectors["Initial Transform"])

        #
        # Input Registration Parameters Collapsible Button
        #
        inputRegistrationParametersCollapsibleButton = ctk.ctkCollapsibleButton(
        )
        inputRegistrationParametersCollapsibleButton.text = "Input Registration Parameters"
        self.layout.addWidget(inputRegistrationParametersCollapsibleButton)
        inputRegistrationParametersFormLayout = qt.QFormLayout(
            inputRegistrationParametersCollapsibleButton)

        #
        # Landmark Transform Mode TYPE SELECTION
        # - allows selection of the active registration type to display
        #
        self.landmarkTransformTypeBox = qt.QGroupBox("Landmark Transform Mode")
        self.landmarkTransformTypeBox.setLayout(qt.QFormLayout())
        self.landmarkTransformTypeButtons = {}
        self.landmarkTransformTypes = ("RigidBody", "Similarity", "Affine")
        for landmarkTransformType in self.landmarkTransformTypes:
            self.landmarkTransformTypeButtons[
                landmarkTransformType] = qt.QRadioButton()
            self.landmarkTransformTypeButtons[
                landmarkTransformType].text = landmarkTransformType
            self.landmarkTransformTypeButtons[
                landmarkTransformType].setToolTip(
                    "Pick the type of registration")
            self.landmarkTransformTypeButtons[landmarkTransformType].connect(
                "clicked()",
                lambda t=landmarkTransformType: self.onLandmarkTrandformType(t
                                                                             ))
            self.landmarkTransformTypeBox.layout().addWidget(
                self.landmarkTransformTypeButtons[landmarkTransformType])
        inputRegistrationParametersFormLayout.addWidget(
            self.landmarkTransformTypeBox)

        #
        # Mean Distance Mode TYPE SELECTION
        #
        self.meanDistanceTypeBox = qt.QGroupBox("Mean Distance Mode")
        self.meanDistanceTypeBox.setLayout(qt.QFormLayout())
        self.meanDistanceTypeButtons = {}
        self.meanDistanceTypes = ("RMS", "Absolute Value")
        inputRegistrationParametersFormLayout.addWidget(
            self.landmarkTransformTypeBox)
        for meanDistanceType in self.meanDistanceTypes:
            self.meanDistanceTypeButtons[meanDistanceType] = qt.QRadioButton()
            self.meanDistanceTypeButtons[
                meanDistanceType].text = meanDistanceType
            self.meanDistanceTypeButtons[meanDistanceType].setToolTip(
                "Pick the type of registration")
            self.meanDistanceTypeButtons[meanDistanceType].connect(
                "clicked()",
                lambda t=meanDistanceType: self.onMeanDistanceType(t))
            self.meanDistanceTypeBox.layout().addWidget(
                self.meanDistanceTypeButtons[meanDistanceType])
        inputRegistrationParametersFormLayout.addWidget(
            self.meanDistanceTypeBox)

        #
        # Start by Matching Centroids Options
        #
        self.startMatchingCentroids = qt.QCheckBox()
        self.startMatchingCentroids.checked = True
        self.startMatchingCentroids.connect("toggled(bool)",
                                            self.onMatchCentroidsLinearActive)
        inputRegistrationParametersFormLayout.addRow(
            "Start by matching centroids ", self.startMatchingCentroids)

        #
        # Check Mean Distance Options
        #
        self.checkMeanDistance = qt.QCheckBox()
        self.checkMeanDistance.checked = True
        self.checkMeanDistance.connect("toggled(bool)",
                                       self.onCheckMeanDistanceActive)
        inputRegistrationParametersFormLayout.addRow("Check Mean Distance ",
                                                     self.checkMeanDistance)

        # Number of Iterations
        numberOfIterations = ctk.ctkSliderWidget()
        numberOfIterations.connect('valueChanged(double)',
                                   self.numberOfIterationsValueChanged)
        numberOfIterations.decimals = 0
        numberOfIterations.minimum = 50
        numberOfIterations.maximum = 80000
        numberOfIterations.value = 50
        inputRegistrationParametersFormLayout.addRow("Number of Iterations:",
                                                     numberOfIterations)

        # Number of Landmarks
        numberOfLandmarks = ctk.ctkSliderWidget()
        numberOfLandmarks.connect('valueChanged(double)',
                                  self.numberOfLandmarksValueChanged)
        numberOfLandmarks.decimals = 0
        numberOfLandmarks.minimum = 0
        numberOfLandmarks.maximum = 10000
        numberOfLandmarks.value = 200
        inputRegistrationParametersFormLayout.addRow("Number of Landmarks:",
                                                     numberOfLandmarks)

        # Maximum Distance
        maxDistance = ctk.ctkSliderWidget()
        maxDistance.connect('valueChanged(double)',
                            self.maxDistanceValueChanged)
        maxDistance.decimals = 4
        maxDistance.minimum = 0.0001
        maxDistance.maximum = 10
        maxDistance.value = 0.01
        inputRegistrationParametersFormLayout.addRow("Maximum Distance:",
                                                     maxDistance)

        #
        # Output Surface Collapsible Button
        #
        outputSurfaceCollapsibleButton = ctk.ctkCollapsibleButton()
        outputSurfaceCollapsibleButton.text = "Output Files"
        self.layout.addWidget(outputSurfaceCollapsibleButton)
        outputSurfaceFormLayout = qt.QFormLayout(
            outputSurfaceCollapsibleButton)

        #
        # Output Surface Volume Options
        #
        self.modelOutputSurfaceSelectors = {}
        self.modelOutputSurfaceSelectors[
            "Output Surface Volume"] = slicer.qMRMLNodeComboBox()
        self.modelOutputSurfaceSelectors["Output Surface Volume"].nodeTypes = (
            ("vtkMRMLModelNode"), "")
        self.modelOutputSurfaceSelectors[
            "Output Surface Volume"].addEnabled = True
        self.modelOutputSurfaceSelectors[
            "Output Surface Volume"].selectNodeUponCreation = True
        self.modelOutputSurfaceSelectors[
            "Output Surface Volume"].removeEnabled = True
        self.modelOutputSurfaceSelectors[
            "Output Surface Volume"].noneEnabled = True
        self.modelOutputSurfaceSelectors[
            "Output Surface Volume"].showHidden = False
        self.modelOutputSurfaceSelectors[
            "Output Surface Volume"].showChildNodeTypes = True
        self.modelOutputSurfaceSelectors["Output Surface Volume"].setMRMLScene(
            slicer.mrmlScene)
        self.modelOutputSurfaceSelectors["Output Surface Volume"].setToolTip(
            "Pick the Output Surface Volume")
        outputSurfaceFormLayout.addRow(
            "Output Surface Volume",
            self.modelOutputSurfaceSelectors["Output Surface Volume"])

        #
        # Output Transform Options
        #
        self.volumeOutputTransformSelectors = {}
        self.volumeOutputTransformSelectors[
            "Output Transform"] = slicer.qMRMLNodeComboBox()
        self.volumeOutputTransformSelectors["Output Transform"].nodeTypes = ((
            "vtkMRMLLinearTransformNode"), "")
        self.volumeOutputTransformSelectors[
            "Output Transform"].selectNodeUponCreation = True
        self.volumeOutputTransformSelectors[
            "Output Transform"].addEnabled = True
        self.volumeOutputTransformSelectors[
            "Output Transform"].removeEnabled = True
        self.volumeOutputTransformSelectors[
            "Output Transform"].noneEnabled = True
        self.volumeOutputTransformSelectors[
            "Output Transform"].showHidden = False
        self.volumeOutputTransformSelectors[
            "Output Transform"].showChildNodeTypes = True
        self.volumeOutputTransformSelectors["Output Transform"].setMRMLScene(
            slicer.mrmlScene)
        self.volumeOutputTransformSelectors["Output Transform"].setToolTip(
            "Pick the Output Transform file")
        outputSurfaceFormLayout.addRow(
            "Output Transform",
            self.volumeOutputTransformSelectors["Output Transform"])

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Run Registration")
        self.applyButton.toolTip = "Run the registration algorithm."
        self.applyButton.enabled = True
        outputSurfaceFormLayout.addRow(self.applyButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        #for selector in self.volumeSelectors.values():
        #  selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onApplyButton)
        #self.volumeInitialTransformSelectors.values().connect('currentNodeChanged(vtkMRMLNode*)', self.onVolumeInitialTransformSelect)

        # listen to the scene
        #self.addObservers()

        # Add vertical spacer
        self.layout.addStretch(1)
Example #7
0
    def IterativeClosestPoint(self, source, target, reference=[]):
        # Iterative closest point surface registration

        icp = vtk.vtkIterativeClosestPointTransform()

        try:
            icp.SetSource(source.GetPolyData())
            icp.SetTarget(target.GetPolyData())
        except:
            icp.SetSource(source)
            icp.SetTarget(target)

        if self.icp_mode == 'Rigid':
            icp.GetLandmarkTransform().SetModeToRigidBody()
        elif self.icp_mode == 'Similarity':
            icp.GetLandmarkTransform().SetModeToSimilarity()
        elif self.icp_mode == 'Affine':
            icp.GetLandmarkTransform().SetModeToAffine()

        # icp.DebugOn()
        icp.SetMaximumNumberOfIterations(int(self.IterationNumber))
        icp.SetMaximumNumberOfLandmarks(int(self.LandmarkNumber))
        icp.SetMaximumMeanDistance(
            self.RMS_Number
        )  # A small number would use the maximum number of iterations
        icp.StartByMatchingCentroidsOn()

        # RMS mode is the square root of the average of the sum of squares of the closest point distances
        icp.SetMeanDistanceModeToRMS()

        icp.Modified()
        icp.Update()

        # Apply the resulting transform to the vtk poly data
        icpTransformFilter = vtk.vtkTransformPolyDataFilter()
        try:
            icpTransformFilter.SetInputData(source.GetPolyData())
        except:
            icpTransformFilter.SetInputData(source)

        icpTransformFilter.SetTransform(icp)
        icpTransformFilter.Update()

        # Update the source object with the transformed object
        transformedSource = icpTransformFilter.GetOutput()

        # If there is a reference surface apply the ICP transform to it
        if reference != []:

            # Apply the resulting transform also to the reference surface vtk poly data
            icpTransformFilter = vtk.vtkTransformPolyDataFilter()
            try:
                icpTransformFilter.SetInputData(reference.GetPolyData())
            except:
                icpTransformFilter.SetInputData(reference)

            icpTransformFilter.SetTransform(icp)
            icpTransformFilter.Update()

            # Update the source object with the transformed object
            transformedReference = icpTransformFilter.GetOutput()

            # Is there is a referece surface return that instead
            return transformedReference
        else:
            # If there in NOT a reference surface, return the registered source
            return transformedSource
  def setup(self):
    """Instantiate and connect widgets ..."""
    
    self.scene = slicer.mrmlScene
    self.icp = vtk.vtkIterativeClosestPointTransform()
	
    #
    # Reload and Test area
    #
    reloadCollapsibleButton = ctk.ctkCollapsibleButton()
    reloadCollapsibleButton.text = "Reload && Test"
    self.layout.addWidget(reloadCollapsibleButton)
    reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

    # reload button
    # (use this during development, but remove it when delivering
    #  your module to users)
    self.reloadButton = qt.QPushButton("Reload")
    self.reloadButton.toolTip = "Reload this module."
    self.reloadButton.name = "SurfaceICPRegistration Reload"
    reloadFormLayout.addWidget(self.reloadButton)
    self.reloadButton.connect('clicked()', self.onReload)

    # reload and test button
    # (use this during development, but remove it when delivering
    #  your module to users)
    self.reloadAndTestButton = qt.QPushButton("Reload and Test")
    self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
    reloadFormLayout.addWidget(self.reloadAndTestButton)
    self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

    #
    # Input Surface Volume Collapsible Button
    #
    inputSurfaceCollapsibleButton = ctk.ctkCollapsibleButton()
    inputSurfaceCollapsibleButton.text = "Input Surface Volumes"
    self.layout.addWidget(inputSurfaceCollapsibleButton)
    inputSurfaceFormLayout = qt.QFormLayout(inputSurfaceCollapsibleButton)
    
	#
	# Input Surface Volume Options
	#
    self.modelSelectors = {}
    self.viewNames = ("Fixed Surface Volume", "Moving Surface Volume")
    for viewName in self.viewNames:
      self.modelSelectors[viewName] = slicer.qMRMLNodeComboBox() 
      self.modelSelectors[viewName].nodeTypes = ( ("vtkMRMLModelNode"), "" ) 
      self.modelSelectors[viewName].selectNodeUponCreation = False
      self.modelSelectors[viewName].addEnabled = False
      self.modelSelectors[viewName].removeEnabled = True
      self.modelSelectors[viewName].noneEnabled = True
      self.modelSelectors[viewName].showHidden = False
      self.modelSelectors[viewName].showChildNodeTypes = True
      self.modelSelectors[viewName].setMRMLScene( slicer.mrmlScene )
      self.modelSelectors[viewName].setToolTip( "Pick the %s surface volume." % viewName.lower() )
      inputSurfaceFormLayout.addRow("%s" % viewName, self.modelSelectors[viewName])
	
	#
	# Input Inicial Transform Options
	#
    self.volumeInitialTransformSelectors = {}
    self.volumeInitialTransformSelectors["Initial Transform"] = slicer.qMRMLNodeComboBox()
    self.volumeInitialTransformSelectors["Initial Transform"].nodeTypes = ( ("vtkMRMLLinearTransformNode"), "" )
    self.volumeInitialTransformSelectors["Initial Transform"].selectNodeUponCreation = False
    self.volumeInitialTransformSelectors["Initial Transform"].addEnabled = False
    self.volumeInitialTransformSelectors["Initial Transform"].removeEnabled = True
    self.volumeInitialTransformSelectors["Initial Transform"].noneEnabled = True
    self.volumeInitialTransformSelectors["Initial Transform"].showHidden = False
    self.volumeInitialTransformSelectors["Initial Transform"].showChildNodeTypes = True
    self.volumeInitialTransformSelectors["Initial Transform"].setMRMLScene( slicer.mrmlScene )
    self.volumeInitialTransformSelectors["Initial Transform"].setToolTip("Pick the initial Transform file")
    inputSurfaceFormLayout.addRow("(Optional) Initial Transform", self.volumeInitialTransformSelectors["Initial Transform"])
    
	#
    # Input Registration Parameters Collapsible Button
    #
    inputRegistrationParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    inputRegistrationParametersCollapsibleButton.text = "Input Registration Parameters"
    self.layout.addWidget(inputRegistrationParametersCollapsibleButton)
    inputRegistrationParametersFormLayout = qt.QFormLayout(inputRegistrationParametersCollapsibleButton)
	
    #
    # Landmark Transform Mode TYPE SELECTION
    # - allows selection of the active registration type to display
    #
    self.landmarkTransformTypeBox = qt.QGroupBox("Landmark Transform Mode")
    self.landmarkTransformTypeBox.setLayout(qt.QFormLayout())
    self.landmarkTransformTypeButtons = {}
    self.landmarkTransformTypes = ("RigidBody", "Similarity", "Affine")
    for landmarkTransformType in self.landmarkTransformTypes:
      self.landmarkTransformTypeButtons[landmarkTransformType] = qt.QRadioButton()
      self.landmarkTransformTypeButtons[landmarkTransformType].text = landmarkTransformType
      self.landmarkTransformTypeButtons[landmarkTransformType].setToolTip("Pick the type of registration")
      self.landmarkTransformTypeButtons[landmarkTransformType].connect("clicked()",
                                      lambda t=landmarkTransformType: self.onLandmarkTrandformType(t))
      self.landmarkTransformTypeBox.layout().addWidget(self.landmarkTransformTypeButtons[landmarkTransformType])
    inputRegistrationParametersFormLayout.addWidget(self.landmarkTransformTypeBox)

	#
	# Mean Distance Mode TYPE SELECTION
	#
    self.meanDistanceTypeBox = qt.QGroupBox("Mean Distance Mode")
    self.meanDistanceTypeBox.setLayout(qt.QFormLayout())
    self.meanDistanceTypeButtons = {}
    self.meanDistanceTypes = ("RMS", "Absolute Value")
    inputRegistrationParametersFormLayout.addWidget(self.landmarkTransformTypeBox)
    for meanDistanceType in self.meanDistanceTypes:
      self.meanDistanceTypeButtons[meanDistanceType] = qt.QRadioButton()
      self.meanDistanceTypeButtons[meanDistanceType].text = meanDistanceType
      self.meanDistanceTypeButtons[meanDistanceType].setToolTip("Pick the type of registration")
      self.meanDistanceTypeButtons[meanDistanceType].connect("clicked()",
                                      lambda t=meanDistanceType: self.onMeanDistanceType(t))
      self.meanDistanceTypeBox.layout().addWidget(self.meanDistanceTypeButtons[meanDistanceType])
    inputRegistrationParametersFormLayout.addWidget(self.meanDistanceTypeBox)
    
    #
	# Start by Matching Centroids Options
	#
    self.startMatchingCentroids = qt.QCheckBox()
    self.startMatchingCentroids.checked = True
    self.startMatchingCentroids.connect("toggled(bool)", self.onMatchCentroidsLinearActive)
    inputRegistrationParametersFormLayout.addRow("Start by matching centroids ", self.startMatchingCentroids)
	
	#
	# Check Mean Distance Options
	#
    self.checkMeanDistance = qt.QCheckBox()
    self.checkMeanDistance.checked = True
    self.checkMeanDistance.connect("toggled(bool)", self.onCheckMeanDistanceActive)
    inputRegistrationParametersFormLayout.addRow("Check Mean Distance ", self.checkMeanDistance)	
	
    # Number of Iterations
    numberOfIterations = ctk.ctkSliderWidget()
    numberOfIterations.connect('valueChanged(double)', self.numberOfIterationsValueChanged)
    numberOfIterations.decimals = 0
    numberOfIterations.minimum = 50
    numberOfIterations.maximum = 80000
    numberOfIterations.value = 50
    inputRegistrationParametersFormLayout.addRow("Number of Iterations:", numberOfIterations)
    
	# Number of Landmarks
    numberOfLandmarks = ctk.ctkSliderWidget()
    numberOfLandmarks.connect('valueChanged(double)', self.numberOfLandmarksValueChanged)
    numberOfLandmarks.decimals = 0
    numberOfLandmarks.minimum = 0
    numberOfLandmarks.maximum = 10000
    numberOfLandmarks.value = 200
    inputRegistrationParametersFormLayout.addRow("Number of Landmarks:", numberOfLandmarks)
	
	# Maximum Distance
    maxDistance = ctk.ctkSliderWidget()
    maxDistance.connect('valueChanged(double)', self.maxDistanceValueChanged)
    maxDistance.decimals = 4
    maxDistance.minimum = 0.0001
    maxDistance.maximum = 10
    maxDistance.value = 0.01
    inputRegistrationParametersFormLayout.addRow("Maximum Distance:", maxDistance)

    #
    # Output Surface Collapsible Button
    #
    outputSurfaceCollapsibleButton = ctk.ctkCollapsibleButton()
    outputSurfaceCollapsibleButton.text = "Output Files"
    self.layout.addWidget(outputSurfaceCollapsibleButton)
    outputSurfaceFormLayout = qt.QFormLayout(outputSurfaceCollapsibleButton)	
	
    #
	# Output Surface Volume Options
	#
    self.modelOutputSurfaceSelectors = {}	
    self.modelOutputSurfaceSelectors["Output Surface Volume"] = slicer.qMRMLNodeComboBox() 
    self.modelOutputSurfaceSelectors["Output Surface Volume"].nodeTypes = ( ("vtkMRMLModelNode"), "" ) 	
    self.modelOutputSurfaceSelectors["Output Surface Volume"].addEnabled = True
    self.modelOutputSurfaceSelectors["Output Surface Volume"].selectNodeUponCreation = True
    self.modelOutputSurfaceSelectors["Output Surface Volume"].removeEnabled = True
    self.modelOutputSurfaceSelectors["Output Surface Volume"].noneEnabled = True
    self.modelOutputSurfaceSelectors["Output Surface Volume"].showHidden = False
    self.modelOutputSurfaceSelectors["Output Surface Volume"].showChildNodeTypes = True
    self.modelOutputSurfaceSelectors["Output Surface Volume"].setMRMLScene( slicer.mrmlScene )
    self.modelOutputSurfaceSelectors["Output Surface Volume"].setToolTip( "Pick the Output Surface Volume" )
    outputSurfaceFormLayout.addRow("Output Surface Volume", self.modelOutputSurfaceSelectors["Output Surface Volume"])
    
	#
	# Output Transform Options
	#
    self.volumeOutputTransformSelectors = {}
    self.volumeOutputTransformSelectors["Output Transform"] = slicer.qMRMLNodeComboBox()
    self.volumeOutputTransformSelectors["Output Transform"].nodeTypes = ( ("vtkMRMLLinearTransformNode"), "" )
    self.volumeOutputTransformSelectors["Output Transform"].selectNodeUponCreation = True
    self.volumeOutputTransformSelectors["Output Transform"].addEnabled = True
    self.volumeOutputTransformSelectors["Output Transform"].removeEnabled = True
    self.volumeOutputTransformSelectors["Output Transform"].noneEnabled = True
    self.volumeOutputTransformSelectors["Output Transform"].showHidden = False
    self.volumeOutputTransformSelectors["Output Transform"].showChildNodeTypes = True
    self.volumeOutputTransformSelectors["Output Transform"].setMRMLScene( slicer.mrmlScene )
    self.volumeOutputTransformSelectors["Output Transform"].setToolTip("Pick the Output Transform file")
    outputSurfaceFormLayout.addRow("Output Transform", self.volumeOutputTransformSelectors["Output Transform"])
	
	
	#
    # Apply Button
    #
    self.applyButton = qt.QPushButton("Run Registration")
    self.applyButton.toolTip = "Run the registration algorithm."
    self.applyButton.enabled = True
    outputSurfaceFormLayout.addRow(self.applyButton)

    # connections
    self.applyButton.connect('clicked(bool)', self.onApplyButton)
    #for selector in self.volumeSelectors.values():
    #  selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onApplyButton)
    #self.volumeInitialTransformSelectors.values().connect('currentNodeChanged(vtkMRMLNode*)', self.onVolumeInitialTransformSelect)

    # listen to the scene
    #self.addObservers()

    # Add vertical spacer
    self.layout.addStretch(1)