#============================================================================== # # Project: SharpImage # Module: SpeedToPathNoGradient.py # Language: IronPython # Author: Dan Mueller # Date: $Date$ # Revision: $Revision$ # # Copyright (c) Queensland University of Technology (QUT) 2007. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without even # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the above copyright notices for more information. # #============================================================================== # Import the base script class import ThreadedScript from ThreadedScript import * # Add reference and import required libraries clr.AddReference("ManagedITK.Optimizers") clr.AddReference("ManagedITK.Paths") from itk import * class SpeedToPathNoGradientScript(ThreadedScriptObject): # ------------------------------------------------------------------------- Name = "SpeedToPathNoGradient" Help = """Extract minimal paths between the given points using Fast Marching. The input is a cost function and must be in the range [0.0, 1.0]. The IterateNeighborhoodOptimizer is used, which does not use the gradient.""" Parameters = """(double) TerminationValue = the arrival value to terminate the gradient descent. (2.0)""" Renderer = None Input = None Form = None Paths = None TerminationValue = 2.0 # ------------------------------------------------------------------------- def Run(self): """ The entry-point for this script. """ self.Initialise() # NOTE: DoWork() will be invoked when Continue is clicked. # NOTE: Finalise() will be invoked when FinishedWork() is called. def Initialise(self): """ Initialise the environment for running this script. """ """ NOTE: This function is invoked on the main UI thread. """ ScriptObject.Initialise(self) self.Renderer = self.ParentApplication.CurrentRenderer self.Input = self.Renderer.Inputs[0] self.Form = siFormSelectPaths( self.Renderer ) self.Form.Continue += self.Continue self.Form.Cancel += self.Cancel self.ParentApplication.AddTool( self.Form ) self.ParentApplication.SetApplicationAsReady( 0 ) def ThreadedDoWork(self): """ Perform the main functions of the script. """ """ NOTE: This function is invoked on a background thread. """ try: # Start the work self.StartedWork() self.WriteImageName( "Input=", self.Input ) # Setup cost function cost = itkSingleImageCostFunction.New( self.Input ); # Setup the optimizer optimizer = itkIterateNeighborhoodOptimizer.New() optimizer.Minimize = True optimizer.FullyConnected = True optimizer.NeighborhoodSize = self.Input.Spacing # Setup the path extraction filter filterPath = itkSpeedFunctionToPathFilter.New( self.Input ) filterPath.SetInput( self.Input ) filterPath.SetCostFunction( cost ) filterPath.SetOptimizer( optimizer ) filterPath.TerminationValue = self.TerminationValue self.WriteLineToConsole( "TerminationValue=" + self.TerminationValue.ToString() ) # Setup the path info for selection in self.Form.Paths: info = itkPathInfo( self.Input.Dimension ) info.StartPoint = selection.Start info.EndPoint = selection.End for way in selection.WayPoints: info.AddWayPoint( way ) filterPath.AddPathInfo( info ) # Get the paths filterPath.Update( ) self.WriteLineToConsole( "Extracted " + filterPath.NumberOfOutputs.ToString() + " paths" ) self.Paths = List[itkPolyLineParametricPath]( filterPath.NumberOfOutputs ) for i in range( filterPath.NumberOfOutputs ): self.Paths.Add( itkPolyLineParametricPath.New(self.Input.Dimension) ) filterPath.GetOutput( i, self.Paths[i] ) self.Paths[i].DisconnectPipeline( ) numpts = self.Paths[i].GetVertexList().Length if ( numpts <= 1): self.WriteLineToConsole( "WARNING: Path " + i.ToString() + " has 0 vertices" ) else: self.WriteLineToConsole( "Path " + i.ToString() + " has " + numpts.ToString() + " vertices" ) # Clean up and finish cost.Dispose( ) optimizer.Dispose( ) filterPath.Dispose( ) self.FinishedWork( True ) except Exception, ex: self.HandleException( ex ) self.FinishedWork( False ) self.Finalise( ) def Continue(self, sender, args): """ Allow processing to continue. """ self.DoWork() def Cancel(self, sender, args): """ Cancel the script. """ self.Path = None ScriptObject.Finalise( self ) def Finalise(self): """ Finalise the environment after running this script. """ """ NOTE: This function is invoked on the main UI thread. """ if (self.Paths != None and self.Paths.Count > 0): # Show path on input for path in self.Paths: self.Renderer.Inputs.Add( path ) # Set the input name pathInput = Path.GetDirectoryName( self.Input.Name ) nameInput = Path.GetFileNameWithoutExtension( self.Input.Name ) extInput = Path.GetExtension( self.Input.Name ) pathOutput = Path.Combine( pathInput, nameInput + "_" + "Path" + extInput ) self.Input.Name = pathOutput # Repaint the renderer self.Renderer.Repaint( ) # Finalise base ScriptObject.Finalise( self ) def FinishedWork(self, success): """ Inform listeners that the work has finished. """ self.UnregisterEventHandlers( ) ScriptObject.FinishedWork( self, success ) if ( success ): self.ParentApplication.Invoke( CallTarget0(self.Finalise) ) def UnregisterEventHandlers(self): """ Unregister all the event handlers. """ if (self.Form != None): self.Form.Continue -= self.Continue self.Form.Cancel -= self.Cancel self.Form = None