#============================================================================== # # Project: SharpImage # Module: Cine.py # Language: IronPython # Author: Dan Mueller # Date: $Date: 2007-07-06 10:57:00 +1000 (Fri, 06 Jul 2007) $ # Revision: $Revision: 2 $ # # 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 * clr.AddReference("System.Diagnostics.ProcessCaller") clr.AddReference("ManagedITK.Filtering.Intensity") from System.Diagnostics.ProcessCaller import * from itk import * class CineScript(ThreadedScriptObject): # ------------------------------------------------------------------------- Name = "Cine" Help = """Converts a 3D input image into a cine movie (each slice as a frame). This script requires mencoder to be installed (available from www.mplayerhq.hu).""" Parameters = """(int) BitRate = the higher the value the better the quality. (500) (int) FramesPerSecond = the higher the value the shorter the movie. (25) (string) VideoCodec = \"none\", \"msmpeg4v2\", or \"wmv1\". (\"msmpeg4v2\") (string) OutputFilename = the absolute path of the output movie. (\"InputImagePath.avi\") (string} MencoderPath = the path of the mencoder.exe (\"C:/Utils/mplayer/mencoder.exe\") (bool) DeleteSeries = True and the temporary series images are deleted, otherwise not. (True)""" FramesPerSecond = 25 BitRate = 500 VideoCodec = String( "msmpeg4v2" ) OutputFilename = String.Empty MencoderPath = String( "C:/Utils/mplayer/mencoder.exe" ) TempPath = String( "C:/Temp/{0}" ) TempFile = String.Empty Renderer = None Input = None InputAsUC3 = None DeleteSeries = True # ------------------------------------------------------------------------- def Initialise(self): """ Initialise the environment for running this script. """ """ NOTE: This function is invoked on the main UI thread. """ try: # Initialise the base class ThreadedScriptObject.Initialise( self ) self.Renderer = self.ParentApplication.CurrentRenderer self.Input = self.Renderer.Inputs[0] except Exception, ex: self.HandleException( ex ) self.FinishedWork( False ) self.Finalise( ) def ThreadedDoWork(self): """ Perform the main functions of the script on a background thread. """ try: self.StartedWork() # Set OutputFilename and TempFile self.OutputFilename = Path.Combine( Path.GetDirectoryName(self.Input.Name), Path.GetFileNameWithoutExtension(self.Input.Name) + ".avi" ) if (self.OutputFilename == None or self.OutputFilename.Length == 0): self.OutputFilename = "C:/SharpImageCine.avi" self.TempFile = Path.GetFileNameWithoutExtension(self.Input.Name) + "_{0}.png" if (self.TempFile == None or self.TempFile.Length == 0): self.TempFile = "SharpImageCine_{0}.png" # Make unique TempPath self.TempPath = String.Format( self.TempPath, Guid.NewGuid().ToString() ) Directory.CreateDirectory( self.TempPath ) # Rescale and cast to unsigned char type if (self.Input.PixelType.TypeAsEnum == itkPixelTypeEnum.UnsignedChar): self.InputAsUC3 = self.Input else: self.WriteLineToConsole( "Rescaling and casting image to UC3..." ) self.InputAsUC3 = itkImage_UC3.New() filterRescale = itkRescaleIntensityImageFilter.New( self.Input, self.InputAsUC3 ) self.AddEventHandlersToProcessObject( filterRescale ) filterRescale.SetInput( self.Input ) filterRescale.OutputMinimum = itkPixel( self.InputAsUC3.PixelType, 0 ) filterRescale.OutputMaximum = itkPixel( self.InputAsUC3.PixelType, 255 ) self.WriteLineToConsole( "OutputMinimum=" + filterRescale.OutputMinimum.ToString() ) self.WriteLineToConsole( "OutputMaximum=" + filterRescale.OutputMaximum.ToString() ) filterRescale.UpdateLargestPossibleRegion() filterRescale.GetOutput( self.InputAsUC3 ) self.Input.DisconnectPipeline() self.InputAsUC3.DisconnectPipeline() self.DisposeOfObject( filterRescale ) # Write input image as image series self.WriteTask( "Extracting image as series..." ) seriesFilePath = Path.Combine( self.TempPath, self.TempFile ) self.InputAsUC3.WriteSeries( seriesFilePath ) # Construct args for mencoder args = String.Empty filemask = String.Format( self.TempFile, "*" ) if (String.Compare( self.VideoCodec, "None", True ) == 0): args = "mf://" + filemask + " -mf fps=" + self.FramesPerSecond.ToString() + ":type=png -ovc raw -oac copy -o " + self.OutputFilename else: args = "mf://" + filemask + " -mf fps=" + self.FramesPerSecond.ToString() + ":type=png -ovc lavc -lavcopts vcodec=" + self.VideoCodec + ":vbitrate=" + self.BitRate.ToString() + " -oac copy -o " + self.OutputFilename # Start process and wait for exit self.WriteTask( "Converting series to movie using mencoder..." ) self.WriteLineToConsole( self.MencoderPath + " " + args ) process = ProcessCaller( self.ParentApplication ) process.FileName = self.MencoderPath process.Arguments = args process.WorkingDirectory = self.TempPath process.StdOutReceived += self.ProcessStandardStreamHandler process.StdErrReceived += self.ProcessStandardStreamHandler process.Completed += self.ProcessCompletedHandler process.Failed += self.ProcessFailedHandler process.Start( ) process.WaitUntilDone( ) # Delete temp series images if (self.DeleteSeries): Directory.Delete( self.TempPath, True ) else: self.WriteLineToConsole( "TempPath=" + self.TempPath) # Show output name and finish self.WriteLineToConsole( "OutputFilename=" + self.OutputFilename) self.FinishedWork( True ) except Exception, ex: self.HandleException( ex ) self.FinishedWork( False ) self.Finalise( ) def ProcessStandardStreamHandler(self, process, e): """ Raised when the process writes to the Standard Output stream. """ self.WriteLineToConsole( e.Text ) def ProcessCompletedHandler(self, process, e): """ Raised when the process has completed. """ self.WriteLineToConsole( "Done." ) def ProcessFailedHandler(self, process, e): """ Raised when the process has completed. """ self.WriteLineToConsole( "ERROR: \r" + e.Exception.ToString() )