def loadPhilips4DUSAsSequence(self, loadable): """Load the selection as an Ultrasound, store in a Sequence node """ # get the key info from the "fake" dicom file filePath = loadable.files[0] ds = dicom.read_file(filePath, stop_before_pixels=True) columns = ds.Columns rows = ds.Rows slices = ds[(0x3001, 0x1001)].value # private tag! spacing = ( ds.PhysicalDeltaX * 10, ds.PhysicalDeltaY * 10, ds[(0x3001, 0x1003)].value * 10 # private tag! ) frames = int(ds.NumberOfFrames) imageComponents = frames frameTimeMsec = ds.FrameTime pixelShape = (frames, slices, rows, columns) pixelSize = pixelShape[0] * pixelShape[1] * pixelShape[2] * pixelShape[ 3] totalFileSize = os.path.getsize(filePath) headerSize = totalFileSize - pixelSize outputSequenceNode = slicer.vtkMRMLSequenceNode() for frame in range(frames): imgReader = vtk.vtkImageReader() imgReader.SetFileDimensionality(3) imgReader.SetFileName(filePath) imgReader.SetNumberOfScalarComponents(1) imgReader.SetDataScalarTypeToUnsignedChar() imgReader.SetDataExtent(0, columns - 1, 0, rows - 1, 0, slices - 1) imgReader.SetHeaderSize(headerSize + frame * slices * rows * columns) imgReader.FileLowerLeftOn() imgReader.Update() outputNode = slicer.vtkMRMLScalarVolumeNode() outputNode.SetAndObserveImageData(imgReader.GetOutput()) outputNode.SetSpacing(spacing) timeStampSec = "{:.3f}".format(frame * frameTimeMsec * 0.001) outputSequenceNode.SetDataNodeAtValue(outputNode, timeStampSec) outputSequenceNode.SetName( slicer.mrmlScene.GenerateUniqueName(loadable.name)) slicer.mrmlScene.AddNode(outputSequenceNode) # Create storage node that allows saving node as nrrd outputSequenceStorageNode = slicer.vtkMRMLVolumeSequenceStorageNode() slicer.mrmlScene.AddNode(outputSequenceStorageNode) outputSequenceNode.SetAndObserveStorageNodeID( outputSequenceStorageNode.GetID()) if not hasattr(loadable, 'createBrowserNode') or loadable.createBrowserNode: # Add a browser node and show the volume in the slice viewer for user convenience outputSequenceBrowserNode = slicer.vtkMRMLSequenceBrowserNode() outputSequenceBrowserNode.SetName( slicer.mrmlScene.GenerateUniqueName( outputSequenceNode.GetName() + ' browser')) slicer.mrmlScene.AddNode(outputSequenceBrowserNode) outputSequenceBrowserNode.SetAndObserveMasterSequenceNodeID( outputSequenceNode.GetID()) masterOutputNode = outputSequenceBrowserNode.GetProxyNode( outputSequenceNode) # Automatically select the volume to display appLogic = slicer.app.applicationLogic() selNode = appLogic.GetSelectionNode() selNode.SetReferenceActiveVolumeID(masterOutputNode.GetID()) appLogic.PropagateVolumeSelection() appLogic.FitSliceToAll() slicer.modules.sequencebrowser.setToolBarActiveBrowserNode( outputSequenceBrowserNode) # create Subject hierarchy nodes for the loaded series self.addSeriesInSubjectHierarchy(loadable, masterOutputNode) return outputSequenceNode
def loadAsSequence(self,loadable): """Load the selection as an Ultrasound, store in a Sequence node """ # get the key info from the "fake" dicom file filePath = loadable.files[0] ds = dicom.read_file(filePath, stop_before_pixels=True) columns = ds.Columns rows = ds.Rows slices = ds[(0x3001,0x1001)].value # private tag! spacing = ( ds.PhysicalDeltaX * 10, ds.PhysicalDeltaY * 10, ds[(0x3001,0x1003)].value * 10 # private tag! ) frames = int(ds.NumberOfFrames) imageComponents = frames frameTimeMsec = ds.FrameTime pixelShape = (frames, slices, rows, columns) pixelSize = reduce(lambda x,y : x*y, pixelShape) totalFileSize = os.path.getsize(filePath) headerSize = totalFileSize-pixelSize outputSequenceNode = slicer.vtkMRMLSequenceNode() for frame in range(frames): imgReader = vtk.vtkImageReader() imgReader.SetFileDimensionality(3) imgReader.SetFileName(filePath); imgReader.SetNumberOfScalarComponents(1) imgReader.SetDataScalarTypeToUnsignedChar() imgReader.SetDataExtent(0,columns-1, 0,rows-1, 0,slices-1) imgReader.SetHeaderSize(headerSize+frame*slices*rows*columns) imgReader.FileLowerLeftOn(); imgReader.Update() outputNode = slicer.vtkMRMLScalarVolumeNode() outputNode.SetAndObserveImageData(imgReader.GetOutput()) outputNode.SetSpacing(spacing) timeStampSec = "{:.3f}".format(frame * frameTimeMsec * 0.001) outputSequenceNode.SetDataNodeAtValue(outputNode, timeStampSec) outputSequenceNode.SetName(slicer.mrmlScene.GenerateUniqueName(loadable.name)) slicer.mrmlScene.AddNode(outputSequenceNode) # Create storage node that allows saving node as nrrd outputSequenceStorageNode = slicer.vtkMRMLVolumeSequenceStorageNode() slicer.mrmlScene.AddNode(outputSequenceStorageNode) outputSequenceNode.SetAndObserveStorageNodeID(outputSequenceStorageNode.GetID()) if not hasattr(loadable, 'createBrowserNode') or loadable.createBrowserNode: # Add a browser node and show the volume in the slice viewer for user convenience outputSequenceBrowserNode = slicer.vtkMRMLSequenceBrowserNode() outputSequenceBrowserNode.SetName(slicer.mrmlScene.GenerateUniqueName(outputSequenceNode.GetName()+' browser')) slicer.mrmlScene.AddNode(outputSequenceBrowserNode) outputSequenceBrowserNode.SetAndObserveMasterSequenceNodeID(outputSequenceNode.GetID()) masterOutputNode = outputSequenceBrowserNode.GetVirtualOutputDataNode(outputSequenceNode) # Automatically select the volume to display appLogic = slicer.app.applicationLogic() selNode = appLogic.GetSelectionNode() selNode.SetReferenceActiveVolumeID(masterOutputNode.GetID()) appLogic.PropagateVolumeSelection() appLogic.FitSliceToAll() outputSequenceBrowserNode.ScalarVolumeAutoWindowLevelOff() # for performance optimization # create Subject hierarchy nodes for the loaded series self.addSeriesInSubjectHierarchy(loadable, masterOutputNode) return outputSequenceNode