|
Tags: 2017 source edit, Replaced |
(334 intermediate revisions by 14 users not shown) |
Line 1: |
Line 1: |
| <noinclude>{{documentation/versioncheck}}</noinclude> | | <noinclude>{{documentation/versioncheck}}</noinclude> |
− | __TOC__
| |
| | | |
− | | + | {{documentation/banner |
− | =Community-contributed modules=
| + | | text = [https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html This page has been moved to read-the-docs.] |
− | | + | | background-color = 8FBC8F }} |
− | Usage: save the .py file to a directory, add the directory to the additional module paths in the Slicer application settings (choose in the menu: Edit / Application settings, click Modules, click >> next to Additional module paths, click Add, and choose the .py file's location).
| |
− | | |
− | ==Segmentation== | |
− | * [https://subversion.assembla.com/svn/slicerrt/trunk/SlicerRt/sandbox/FillRoiModule/FillRoi.py FillRoi.py]: Fill a region of interest in a labelmap volume with a constant value. This can be used after an automatic segmentation for removing certain regions of a volume (such as remove the table from a CT image).
| |
− | | |
− | ==Filters==
| |
− | * [https://raw.github.com/pieper/VolumeMasker/master/VolumeMasker.py VolumeMasker.py]: Update a target volume with the results of setting all input volume voxels to 0 except for those that correspond to a selected label value in an input label map (Used for example in the volume rendering in [https://www.youtube.com/watch?v=dfu2gugHLHs this video).
| |
− | | |
− | ==DICOM==
| |
− | * [https://gist.github.com/pieper/6186477 dicom header browser] to easily scroll through dicom files using dcmdump.
| |
− | | |
− | ==Informatics==
| |
− | * [https://subversion.assembla.com/svn/slicerrt/trunk/SlicerRt/sandbox/MarkupsInfoModule/MarkupsInfo.py MarkupsInfo.py]: Compute the total length between all the points of a markup list.
| |
− | * [https://subversion.assembla.com/svn/slicerrt/trunk/SlicerRt/sandbox/LineProfile/LineProfile.py LineProfile.py]: Compute intensity profile in a volume along a line.
| |
− | | |
− | =Community-contributed examples=
| |
− | | |
− | Usage: Copy-paste the shown code lines or linked .py file contents into Python console in Slicer.
| |
− | | |
− | ==Capture==
| |
− | * Get a MRML node in the scene based on the node name and call methods of that object. For the MRHead sample data:
| |
− | vol=slicer.util.getNode('MR*')
| |
− | vol.GetImageData().GetDimensions()
| |
− | * Capture the full Slicer screen and save it into a file
| |
− | img = qt.QPixmap.grabWidget(slicer.util.mainWindow()).toImage()
| |
− | img.save('c:/tmp/test.png')
| |
− | * [https://subversion.assembla.com/svn/slicerrt/trunk/SlicerRt/sandbox/CaptureRotationVideo/CaptureRotationVideo.py CaptureRotationVideo.py]: Capture a video of the scene rotating in the 3D view
| |
− | | |
− | ==Launching Slicer==
| |
− | * How to open an .mrb file with Slicer at the command line?
| |
− | Slicer.exe --python-code "slicer.util.loadScene( 'f:/2013-08-23-Scene.mrb' )"
| |
− | * How to run a script in the Slicer environment in batch mode (without showing any graphical user interface)?
| |
− | Slicer.exe --python-code "doSomething; doSomethingElse; etc." --testing --no-splash --no-main-window
| |
− | | |
− | ==DICOM==
| |
− | * How to access tags of DICOM images imported into Slicer? For example, to print the first patient's first study's first series' "0020,0032" field:
| |
− | db=slicer.dicomDatabase
| |
− | patientList=db.patients()
| |
− | studyList=db.studiesForPatient(patientList[0])
| |
− | seriesList=db.seriesForStudy(studyList[0])
| |
− | fileList=db.filesForSeries(seriesList[0])
| |
− | print db.fileValue(fileList[0],'0020,0032')
| |
− | | |
− | * How to access tag of a volume loaded from DICOM? For example, get the patient position stored in a volume:
| |
− | volumeName='2: ENT IMRT'
| |
− | n=slicer.util.getNode(volumeName)
| |
− | instUids=n.GetAttribute('DICOM.instanceUIDs').split()
| |
− | filename=slicer.dicomDatabase.fileForInstance(instUids[0])
| |
− | print slicer.dicomDatabase.fileValue(filename,'0018,5100')
| |
− | | |
− | ==Toolbar functions==
| |
− | * How to turn on slice intersections in the crosshair menu on the toolbar:
| |
− | viewNodes = slicer.mrmlScene.GetNodesByClass('vtkMRMLSliceCompositeNode')
| |
− | viewNodes.UnRegister(slicer.mrmlScene)
| |
− | viewNodes.InitTraversal()
| |
− | viewNode = viewNodes.GetNextItemAsObject()
| |
− | while viewNode:
| |
− | viewNode.SetSliceIntersectionVisibility(1)
| |
− | viewNode = viewNodes.GetNextItemAsObject()
| |
− | | |
− | How to find similar functions? For this one I searched for "slice intersections" text in the whole slicer source code, found that the function is implemented in Base\QTGUI\qSlicerViewersToolBar.cxx, then translated the qSlicerViewersToolBarPrivate::setSliceIntersectionVisible(bool visible) method to Python.
| |
− | | |
− | ==Manipulating objects in the slice viewer==
| |
− | * How to define/edit a circular region of interest in a slice viewer?
| |
− | | |
− | Drop two markup points on a slice view and copy-paste the code below into the Python console. After this, as you move the markups you’ll see a circle following the markups.
| |
− | | |
− | # Update the sphere from the fiducial points
| |
− | def UpdateSphere(param1, param2):
| |
− | centerPointCoord = [0.0, 0.0, 0.0]
| |
− | markups.GetNthFiducialPosition(0,centerPointCoord)
| |
− | circumferencePointCoord = [0.0, 0.0, 0.0]
| |
− | markups.GetNthFiducialPosition(1,circumferencePointCoord)
| |
− | sphere.SetCenter(centerPointCoord)
| |
− | radius=math.sqrt((centerPointCoord[0]-circumferencePointCoord[0])**2+(centerPointCoord[1]-circumferencePointCoord[1])**2+(centerPointCoord[2]-circumferencePointCoord[2])**2)
| |
− | sphere.SetRadius(radius)
| |
− | sphere.SetPhiResolution(30)
| |
− | sphere.SetThetaResolution(30)
| |
− | sphere.Update()
| |
− |
| |
− | # Get a reference to the markup
| |
− | markups=slicer.util.getNode('F')
| |
− | # Create the sphere that will intersect the slice viewer
| |
− | sphere = vtk.vtkSphereSource()
| |
− | # Initial positioning of the sphere
| |
− | UpdateSphere(0,0)
| |
− | # Create model node and add to scene
| |
− | model = slicer.vtkMRMLModelNode()
| |
− | model.SetAndObservePolyData(sphere.GetOutput())
| |
− | modelDisplay = slicer.vtkMRMLModelDisplayNode()
| |
− | modelDisplay.SetSliceIntersectionVisibility(True) # Show in slice view
| |
− | modelDisplay.SetVisibility(False) # Hide in 3D view
| |
− | slicer.mrmlScene.AddNode(modelDisplay)
| |
− | model.SetAndObserveDisplayNodeID(modelDisplay.GetID())
| |
− | modelDisplay.SetInputPolyData(model.GetPolyData())
| |
− | slicer.mrmlScene.AddNode(model)
| |
− | # Call UpdateSphere whenever the fiducials are changed
| |
− | markups.AddObserver("ModifiedEvent", UpdateSphere, 2)
| |
− | | |
− | == Add a texture mapped plane to the scene as a model ==
| |
− | Note that model textures are not exposed in the GUI and are not saved in the scene
| |
− | <pre>
| |
− | # use dummy image data here
| |
− | e = vtk.vtkImageEllipsoidSource()
| |
− | | |
− | scene = slicer.mrmlScene
| |
− | | |
− | # Create model node
| |
− | model = slicer.vtkMRMLModelNode()
| |
− | model.SetScene(scene)
| |
− | model.SetName(scene.GenerateUniqueName("2DImageModel"))
| |
− | | |
− | planeSource = vtk.vtkPlaneSource()
| |
− | model.SetAndObservePolyData(planeSource.GetOutput())
| |
− | | |
− | # Create display node
| |
− | modelDisplay = slicer.vtkMRMLModelDisplayNode()
| |
− | modelDisplay.SetColor(1,1,0) # yellow
| |
− | modelDisplay.SetBackfaceCulling(0)
| |
− | modelDisplay.SetScene(scene)
| |
− | scene.AddNode(modelDisplay)
| |
− | model.SetAndObserveDisplayNodeID(modelDisplay.GetID())
| |
− | | |
− | # Add to scene
| |
− | modelDisplay.SetAndObserveTextureImageData(e.GetOutput())
| |
− | scene.AddNode(model)
| |
− | | |
− | | |
− | transform = slicer.vtkMRMLLinearTransformNode()
| |
− | scene.AddNode(transform)
| |
− | model.SetAndObserveTransformNodeID(transform.GetID())
| |
− | | |
− | vTransform = vtk.vtkTransform()
| |
− | vTransform.Scale(50,50,50)
| |
− | vTransform.RotateX(30)
| |
− | transform.SetAndObserveMatrixTransformToParent(vTransform.GetMatrix())
| |
− | </pre>
| |
− | | |
− | | |
− | == Clone a volume ==
| |
− | This example shows how to clone the MRHead sample volume, including its pixel data and display settings.
| |
− | <pre>
| |
− | sourceVolumeNode = slicer.util.getNode('MRHead')
| |
− | | |
− | clonedVolumeNode = slicer.mrmlScene.CopyNode(sourceVolumeNode)
| |
− | | |
− | if sourceVolumeNode.GetDisplayNode() :
| |
− | clonedVolumeDisplayNode = slicer.mrmlScene.CopyNode(sourceVolumeNode.GetDisplayNode())
| |
− | clonedVolumeDisplayNode.Copy(sourceVolumeNode.GetDisplayNode())
| |
− | clonedVolumeNode.SetAndObserveDisplayNodeID(clonedVolumeDisplayNode.GetID())
| |
− | | |
− | if sourceVolumeNode.GetImageData() :
| |
− | clonedImageData = vtk.vtkImageData()
| |
− | clonedImageData.DeepCopy(sourceVolumeNode.GetImageData())
| |
− | clonedVolumeNode.SetAndObserveImageData(clonedImageData)
| |
− | </pre>
| |
− | | |
− | == Modify voxels in a volume ==
| |
− | This example shows how to change voxels values of the MRHead sample volume.
| |
− | The values will be computed by function f(r,a,s,) = (r-10)*(r-10)+(a+15)*(a+15)+s*s.
| |
− | <pre>
| |
− | volumeNode=slicer.util.getNode('MRHead')
| |
− | ijkToRas = vtk.vtkMatrix4x4()
| |
− | volumeNode.GetIJKToRASMatrix(ijkToRas)
| |
− | imageData=volumeNode.GetImageData()
| |
− | extent = imageData.GetExtent()
| |
− | for k in xrange(extent[4], extent[5]+1):
| |
− | for j in xrange(extent[2], extent[3]+1):
| |
− | for i in xrange(extent[0], extent[1]+1):
| |
− | position_Ijk=[i, j, k, 1]
| |
− | position_Ras=ijkToRas.MultiplyPoint(position_Ijk)
| |
− | r=position_Ras[0]
| |
− | a=position_Ras[1]
| |
− | s=position_Ras[2]
| |
− | functionValue=(r-10)*(r-10)+(a+15)*(a+15)+s*s
| |
− | imageData.SetScalarComponentFromDouble(i,j,k,0,functionValue)
| |
− | imageData.SetScalarComponentFromFloat(distortionVectorPosition_Ijk[0], distortionVectorPosition_Ijk[1], distortionVectorPosition_Ijk[2], 0, fillValue)
| |
− | imageData.Modified()
| |
− | </pre>
| |