def pad(self, pixels=10, value=255): """ Add the specified number of pixels at the picture borders. Pixels can be a list formatted as [left,right,bottom,top]. Parameters ---------- pixels : int,list , optional number of pixels to be added (or a list of length 4). The default is 10. value : int, optional intensity value (gray-scale color) of the padding. The default is 255. """ x0, x1, y0, y1, _z0, _z1 = self._data.GetExtent() pf = vtk.vtkImageConstantPad() pf.SetInputData(self._data) pf.SetConstant(value) if utils.isSequence(pixels): pf.SetOutputWholeExtent(x0 - pixels[0], x1 + pixels[1], y0 - pixels[2], y1 + pixels[3], 0, 0) else: pf.SetOutputWholeExtent(x0 - pixels, x1 + pixels, y0 - pixels, y1 + pixels, 0, 0) pf.Update() img = pf.GetOutput() return self._update(img)
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkImageConstantPad(), 'Processing.', ('vtkImageData',), ('vtkImageData',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def update_image(self): reslice = vtk.vtkImageReslice() if self.origin_x is not None: # add padding so that origin_x is in the middle of the image pad = vtk.vtkImageConstantPad() pad.SetInputConnection(self.reader.GetOutputPort()) pad.SetConstant(BG_HU) # GetExtent() returns a tuple (minX, maxX, minY, maxY, minZ, maxZ) extent = list(self.reader.GetOutput().GetExtent()) x_size = extent[1] - extent[0] extent[0] -= max(x_size - 2 * self.origin_x, 0) extent[1] += max(2 * self.origin_x - x_size, 0) pad.SetOutputWholeExtent(*extent) reslice.SetInputConnection(pad.GetOutputPort()) else: reslice.SetInputConnection(self.reader.GetOutputPort()) transform = vtk.vtkPerspectiveTransform() # gantry tilt transform.Shear(0, *self.shear_params) if self.angle_z != 0 or self.angle_y != 0: transform.RotateWXYZ(-self.angle_z, 0, 0, 1) # top transform.RotateWXYZ(self.angle_y, 0, 1, 0) # front reslice.SetResliceTransform(transform) reslice.SetInterpolationModeToCubic() reslice.AutoCropOutputOn() reslice.SetBackgroundLevel(BG_HU) reslice.Update() spacings_lists = reslice.GetOutput().GetSpacing() if self.spacing == 'auto': min_spacing = min(spacings_lists) if not min_spacing: raise ValueError('Invalid scan. Path: {}'.format( self.scan_dir)) spacing = [min_spacing, min_spacing, min_spacing] elif self.spacing == 'none': spacing = None else: spacing = self.spacing if spacing is None: self.image = reslice else: resample = vtkImageResample() resample.SetInputConnection(reslice.GetOutputPort()) resample.SetAxisOutputSpacing(0, spacing[0]) # x axis resample.SetAxisOutputSpacing(1, spacing[1]) # y axis resample.SetAxisOutputSpacing(2, spacing[2]) # z axis resample.SetInterpolationModeToCubic() resample.Update() self.image = resample
def __init__(self, module_manager): # initialise our base class ModuleBase.__init__(self, module_manager) self._reslicer = vtk.vtkImageReslice() self._probefilter = vtk.vtkProbeFilter() self._config.paddingValue = 0.0 #This is retarded - we (sometimes, see below) need the padder #to get the image extent big enough to satisfy the probe filter. #No apparent logical reason, but it throws an exception if we don't. self._padder = vtk.vtkImageConstantPad() configList = [( 'Padding value:', 'paddingValue', 'base:float', 'text', 'The value used to pad regions that are outside the supplied volume.' )] # initialise any mixins we might have ScriptedConfigModuleMixin.__init__( self, configList, { 'Module (self)': self, 'vtkImageReslice': self._reslicer, 'vtkProbeFilter': self._probefilter, 'vtkImageConstantPad': self._padder }) module_utils.setup_vtk_object_progress( self, self._reslicer, 'Transforming image (Image Reslice)') module_utils.setup_vtk_object_progress( self, self._probefilter, 'Performing remapping (Probe Filter)') self.sync_module_logic_with_config()
def __init__(self, module_manager): # initialise our base class ModuleBase.__init__(self, module_manager) self._reslicer = vtk.vtkImageReslice() self._probefilter = vtk.vtkProbeFilter() self._config.paddingValue = 0.0 #This is retarded - we (sometimes, see below) need the padder #to get the image extent big enough to satisfy the probe filter. #No apparent logical reason, but it throws an exception if we don't. self._padder = vtk.vtkImageConstantPad() configList = [ ('Padding value:', 'paddingValue', 'base:float', 'text', 'The value used to pad regions that are outside the supplied volume.')] # initialise any mixins we might have ScriptedConfigModuleMixin.__init__( self, configList, {'Module (self)': self, 'vtkImageReslice': self._reslicer, 'vtkProbeFilter': self._probefilter, 'vtkImageConstantPad': self._padder}) module_utils.setup_vtk_object_progress(self, self._reslicer, 'Transforming image (Image Reslice)') module_utils.setup_vtk_object_progress(self, self._probefilter, 'Performing remapping (Probe Filter)') self.sync_module_logic_with_config()
def generate(self, input_path, output_directory, part_name): input_path = work_dir + "/vtk_image/itk_tile_0_2_6.vti" reader = vtk.vtkXMLImageDataReader() reader.SetFileName(input_path) reader.Update() pad_filter = vtk.vtkImageConstantPad() pad_filter.SetInputConnection(reader.GetOutputPort()) pad_filter.SetConstant(0) pad_filter.SetOutputWholeExtent(reader.GetOutput().GetExtent()[0]-5, reader.GetOutput().GetExtent()[1]+5, reader.GetOutput().GetExtent()[2]-5, reader.GetOutput().GetExtent()[3]+5, reader.GetOutput().GetExtent()[4]-5, reader.GetOutput().GetExtent()[5]+5) pad_filter.Update() writer = vtk.vtkXMLImageDataWriter() writer.SetFileName(work_dir + "/surface/itk_tile_0_2_6_pad.vti") writer.SetInputConnection(pad_filter.GetOutputPort()) writer.Update() myArguments = 'vmtklevelsetsegmentation -ifile ' + work_dir + "/surface/itk_tile_0_2_6_pad.vti" + ' -ofile ' + output_path+"/itk_tile_0_2_6_ls.vti" myPype = pypes.PypeRun(myArguments) myArguments = 'vmtkmarchingcubes -ifile ' + output_path+"/itk_tile_0_2_6_ls.vti" + ' -ofile ' + output_path+"/itk_tile_0_2_6_model.vtp" myPype = pypes.PypeRun(myArguments)
def __init__(self, module_manager): # initialise our base class ModuleBase.__init__(self, module_manager) # what a lame-assed filter, we have to make dummy inputs! # if we don't have a dummy input (but instead a None input) it # bitterly complains when we do a GetOutput() (it needs the input # to know the type of the output) - and GetPolyDataOutput() also # doesn't work. # NB: this does mean that our probeFilter NEEDS a PolyData as # probe geometry! ss = vtk.vtkSphereSource() ss.SetRadius(0) self._dummyInput = ss.GetOutput() #This is also retarded - we (sometimes, see below) need the "padder" #to get the image extent big enough to satisfy the probe filter. #No apparent logical reason, but it throws an exception if we don't. self._padder = vtk.vtkImageConstantPad() self._source = None self._input = None self._probeFilter = vtk.vtkProbeFilter() self._probeFilter.SetInput(self._dummyInput) NoConfigModuleMixin.__init__( self, {'Module (self)' : self, 'vtkProbeFilter' : self._probeFilter}) module_utils.setup_vtk_object_progress(self, self._probeFilter, 'Mapping source on input') self.sync_module_logic_with_config()
def Update(self): # If a dummy input is defined then, probaby a diagnostic run asking # for output data type is performed. In such case, just generate a # blank ImageData object just to be able to determine filter's output # data type. if self._padding == (0, 0, 0): self._output = self._input return # XXX: (note the date: Mon Mar 25 22:57:45 CET 2013) # Ok, when we arrived here, it means that we're doing sometging # significant. source = self._input self._output = vtk.vtkImageData() padx, pady, padz = self._padding initial_extent = self._input.GetWholeExtent() sx, sy, sz = self._input.GetSpacing() if __debug__: print "\tInitial image extent: " + str(initial_extent) print "\tInitial image origin: " + str(self._input.GetOrigin()) print "\tRequested padding: %d, %d, %d" % (padx, pady, padz) translator = vtk.vtkImageChangeInformation() translator.SetExtentTranslation(padx, pady, padz) translator.SetOriginTranslation(-padx * sx, -pady * sy, -padz * sz) translator.SetInput(source) # Now we actually pad the image filling the extended canvas with the # "0" value. pad_filter = vtk.vtkImageConstantPad() pad_filter.SetConstant(0) pad_filter.SetOutputWholeExtent(initial_extent[0], initial_extent[1] + 2 * padx, initial_extent[2], initial_extent[3] + 2 * pady, initial_extent[4], initial_extent[5] + 2 * padz) pad_filter.SetInput(translator.GetOutput()) pad_filter.Update() # Assign the resulting image to the output self._output = pad_filter.GetOutput() if __debug__: print "\tFinal image extent: " + str(self._output.GetWholeExtent()) print "\tFinal image origin: " + str(self._output.GetOrigin())
def Update(self): # If a dummy input is defined then, probaby a diagnostic run asking # for output data type is performed. In such case, just generate a # blank ImageData object just to be able to determine filter's output # data type. if self._padding == (0, 0, 0): self._output = self._input return # XXX: (note the date: Mon Mar 25 22:57:45 CET 2013) # Ok, when we arrived here, it means that we're doing sometging # significant. source = self._input self._output = vtk.vtkImageData() padx, pady, padz = self._padding initial_extent = self._input.GetWholeExtent() sx, sy, sz = self._input.GetSpacing() if __debug__: print "\tInitial image extent: " + str(initial_extent) print "\tInitial image origin: " + str(self._input.GetOrigin()) print "\tRequested padding: %d, %d, %d" % (padx, pady, padz) translator = vtk.vtkImageChangeInformation() translator.SetExtentTranslation(padx, pady, padz) translator.SetOriginTranslation(-padx*sx, -pady*sy, -padz*sz) translator.SetInput(source) # Now we actually pad the image filling the extended canvas with the # "0" value. pad_filter = vtk.vtkImageConstantPad() pad_filter.SetConstant(0) pad_filter.SetOutputWholeExtent(initial_extent[0], initial_extent[1]+2*padx, initial_extent[2], initial_extent[3]+2*pady, initial_extent[4], initial_extent[5]+2*padz) pad_filter.SetInput(translator.GetOutput()) pad_filter.Update() # Assign the resulting image to the output self._output = pad_filter.GetOutput() if __debug__: print "\tFinal image extent: " + str(self._output.GetWholeExtent()) print "\tFinal image origin: " + str(self._output.GetOrigin())
def __init__(self, parent=None): # Defaults self.filename = "" self.gaussStandardDeviation = 1.2 self.gaussRadius = 2 self.magnification = 1 self.isosurface = 1 self.actorColor = [1.000, 0.000, 0.000] self.actorOpacity = 1.0 self.actorVisibility = 1 self.actorPickable = 1 self.pipelineType = "MarchingCubes" # In the future we could define other types of pipelines self.pipelineDataType = None self.actorAdded = False self.processing_log = None self.image_info = None # Elements of the VTK pipeline self.reader = None self.gauss = vtk.vtkImageGaussianSmooth() self.pad = vtk.vtkImageConstantPad() self.resampler = vtk.vtkImageResize() self.marchingCubes = vtk.vtkImageMarchingCubes() self.mapper = vtk.vtkPolyDataMapper() self.mapperDS = vtk.vtkDataSetMapper() self.actor = vtk.vtkActor() self.transformPolyData = vtk.vtkTransformPolyDataFilter() # The vtkTransform is part of the pipeline. The matrix defines the vtkTransform, but we # store a copy in self.matrix for retrieval later. self.rigidBodyTransform = vtk.vtkTransform() self.rigidBodyTransform.Identity() self.rigidBodyTransform.PostMultiply() # Important so that transform concatenations is correct! self.matrix = vtk.vtkMatrix4x4() self.dim = [1,1,1] self.pos = [0,0,0] self.el_size_mm = [0.082,0.082,0.082] self.extent = [0,1,0,1,0,1] self.origin = [0,0,0] self.validForExtrusion = False
def execute(self, inputs, update = 0, last = 0): """ Execute the filter with given inputs and return the output """ if not lib.ProcessingFilter.ProcessingFilter.execute(self, inputs): return None self.calculateMaximumDimensions() if self.parameters["PadDatasets"] and not self.padFilter: maxX, maxY, maxZ = self.maxDimensions self.padFilter = vtk.vtkImageConstantPad() self.padFilter.SetConstant(0) self.padFilter.SetOutputWholeExtent(0, maxX-1, 0, maxY-1, 0, maxZ-1) self.calculateTimepointMapping() image = self.getImageForTimepoint(self.getCurrentTimepoint()) if self.parameters["PadDatasets"]: self.padFilter.RemoveAllInputs() self.padFilter.SetInput(image) image = self.padFilter.GetOutput() return image
def cropOrientedImage(masterImageData, roiNode): """Clip master image data with annotation ROI and return result in a new vtkOrientedImageData""" # This is a utility function, also used in FloodFilling effect. # Probably we should apply relative transform between ROI and master image data node worldToImageMatrix = vtk.vtkMatrix4x4() masterImageData.GetWorldToImageMatrix(worldToImageMatrix) bounds = [0, 0, 0, 0, 0, 0] roiNode.GetRASBounds(bounds) corner1RAS = [bounds[0], bounds[2], bounds[4], 1] corner1IJK = [0, 0, 0, 0] worldToImageMatrix.MultiplyPoint(corner1RAS, corner1IJK) corner2RAS = [bounds[1], bounds[3], bounds[5], 1] corner2IJK = [0, 0, 0, 0] worldToImageMatrix.MultiplyPoint(corner2RAS, corner2IJK) extent = [0, -1, 0, -1, 0, -1] for i in range(3): lowerPoint = min(corner1IJK[i], corner2IJK[i]) upperPoint = max(corner1IJK[i], corner2IJK[i]) extent[2 * i] = int(math.floor(lowerPoint)) extent[2 * i + 1] = int(math.ceil(upperPoint)) imageToWorldMatrix = vtk.vtkMatrix4x4() masterImageData.GetImageToWorldMatrix(imageToWorldMatrix) clippedMasterImageData = slicer.vtkOrientedImageData() padder = vtk.vtkImageConstantPad() padder.SetInputData(masterImageData) padder.SetOutputWholeExtent(extent) padder.Update() clippedMasterImageData.ShallowCopy(padder.GetOutput()) clippedMasterImageData.SetImageToWorldMatrix(imageToWorldMatrix) return clippedMasterImageData
#indexer.SetNumberOfColors(5) # causes errors! indexedImage = indexer.GetOutput() indexedImage.Update() lookuptable = indexer.GetLookupTable() # fix annoyance with indexed image - not relevant for oof since we # will be using the material image for this for i in xrange(20): for j in xrange(20): for k in xrange(20): value = indexedImage.GetScalarComponentAsFloat(i,j,k,0) if value % 2 == 0: indexedImage.SetScalarComponentFromFloat(i,j,k,0,0) # fix annoyance with image extent! padder = vtk.vtkImageConstantPad() padder.SetInput(indexedImage) padder.SetOutputWholeExtent(0,20,0,20,0,20) padder.SetConstant(100) indexedImage = padder.GetOutput() indexedImage.Update() mapper.SetInput(indexedImage) color = vtk.vtkColorTransferFunction() num=lookuptable.GetNumberOfColors() for i in (0,1,3,5,7): rgb = lookuptable.GetTableValue(i) color.AddRGBPoint(i,rgb[0],rgb[1],rgb[2]) volproperty.SetColor(color) print "made indexed image"
def createModelBaseOnVolume(self, holefilledImageNode, outputModelNode): if holefilledImageNode: holefilledImageData = holefilledImageNode.GetImageData() cast = vtk.vtkImageCast() cast.SetInputData(holefilledImageData) cast.SetOutputScalarTypeToUnsignedChar() cast.Update() labelVolumeNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLLabelMapVolumeNode") slicer.mrmlScene.AddNode(labelVolumeNode) labelVolumeNode.SetName("Threshold") labelVolumeNode.SetSpacing(holefilledImageData.GetSpacing()) labelVolumeNode.SetOrigin(holefilledImageData.GetOrigin()) matrix = vtk.vtkMatrix4x4() holefilledImageNode.GetIJKToRASMatrix(matrix) labelVolumeNode.SetIJKToRASMatrix(matrix) labelImage = cast.GetOutput() labelVolumeNode.SetAndObserveImageData(labelImage) transformIJKtoRAS = vtk.vtkTransform() matrix = vtk.vtkMatrix4x4() labelVolumeNode.GetRASToIJKMatrix(matrix) transformIJKtoRAS.SetMatrix(matrix) transformIJKtoRAS.Inverse() padder = vtk.vtkImageConstantPad() padder.SetInputData(labelImage) padder.SetConstant(0) extent = labelImage.GetExtent() padder.SetOutputWholeExtent(extent[0], extent[1] + 2, extent[2], extent[3] + 2, extent[4], extent[5] + 2) cubes = vtk.vtkDiscreteMarchingCubes() cubes.SetInputConnection(padder.GetOutputPort()) cubes.GenerateValues(1, 1, 1) cubes.Update() smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(cubes.GetOutputPort()) smoother.SetNumberOfIterations(10) smoother.BoundarySmoothingOn() smoother.FeatureEdgeSmoothingOff() smoother.SetFeatureAngle(120.0) smoother.SetPassBand(0.001) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() pthreshold = vtk.vtkThreshold() pthreshold.SetInputConnection(smoother.GetOutputPort()) pthreshold.ThresholdBetween(1, 1) ## Label 1 pthreshold.ReleaseDataFlagOn() geometryFilter = vtk.vtkGeometryFilter() geometryFilter.SetInputConnection(pthreshold.GetOutputPort()) geometryFilter.ReleaseDataFlagOn() decimator = vtk.vtkDecimatePro() decimator.SetInputConnection(geometryFilter.GetOutputPort()) decimator.SetFeatureAngle(60) decimator.SplittingOff() decimator.PreserveTopologyOn() decimator.SetMaximumError(1) decimator.SetTargetReduction(0.5) #0.001 only reduce the points by 0.1%, 0.5 is 50% off decimator.ReleaseDataFlagOff() decimator.Update() smootherPoly = vtk.vtkSmoothPolyDataFilter() smootherPoly.SetRelaxationFactor(0.33) smootherPoly.SetFeatureAngle(60) smootherPoly.SetConvergence(0) if transformIJKtoRAS.GetMatrix().Determinant() < 0: reverser = vtk.vtkReverseSense() reverser.SetInputConnection(decimator.GetOutputPort()) reverser.ReverseNormalsOn() reverser.ReleaseDataFlagOn() smootherPoly.SetInputConnection(reverser.GetOutputPort()) else: smootherPoly.SetInputConnection(decimator.GetOutputPort()) Smooth = 10 smootherPoly.SetNumberOfIterations(Smooth) smootherPoly.FeatureEdgeSmoothingOff() smootherPoly.BoundarySmoothingOff() smootherPoly.ReleaseDataFlagOn() smootherPoly.Update() transformer = vtk.vtkTransformPolyDataFilter() transformer.SetInputConnection(smootherPoly.GetOutputPort()) transformer.SetTransform(transformIJKtoRAS) transformer.ReleaseDataFlagOn() transformer.Update() normals = vtk.vtkPolyDataNormals() normals.SetInputConnection(transformer.GetOutputPort()) normals.SetFeatureAngle(60) normals.SetSplitting(True) normals.ReleaseDataFlagOn() stripper = vtk.vtkStripper() stripper.SetInputConnection(normals.GetOutputPort()) stripper.ReleaseDataFlagOff() stripper.Update() outputModel = stripper.GetOutput() outputModelNode.SetAndObservePolyData(outputModel) outputModelNode.SetAttribute("vtkMRMLModelNode.modelCreated","True") outputModelNode.GetDisplayNode().SetVisibility(1) slicer.mrmlScene.RemoveNode(labelVolumeNode) pass
pow = 0 amt = amt + -1 while 1: amt = expr.expr(globals(), locals(),["amt",">>","1"]) pow = pow + 1 if (amt <= 0): return expr.expr(globals(), locals(),["1","<<","pow"]) pass pass orgX = expr.expr(globals(), locals(),["lindex(imageIn.GetExecutive().GetWholeExtent(imageIn.GetOutputInformation(0)),1)","-","lindex(imageIn.GetExecutive().GetWholeExtent(imageIn.GetOutputInformation(0)),0)","+","1"]) orgY = expr.expr(globals(), locals(),["lindex(imageIn.GetExecutive().GetWholeExtent(imageIn.GetOutputInformation(0)),3)","-","lindex(imageIn.GetExecutive().GetWholeExtent(imageIn.GetOutputInformation(0)),2)","+","1"]) padX = PowerOfTwo(orgX) padY = PowerOfTwo(orgY) imagePowerOf2 = vtk.vtkImageConstantPad() imagePowerOf2.SetInputConnection(imageIn.GetOutputPort()) imagePowerOf2.SetOutputWholeExtent(0,expr.expr(globals(), locals(),["padX","-","1"]),0,expr.expr(globals(), locals(),["padY","-","1"]),0,0) toHSV = vtk.vtkImageRGBToHSV() toHSV.SetInputConnection(imageIn.GetOutputPort()) toHSV.GetExecutive().SetReleaseDataFlag(0,0) extractImage = vtk.vtkImageExtractComponents() extractImage.SetInputConnection(toHSV.GetOutputPort()) extractImage.SetComponents(2) extractImage.GetExecutive().SetReleaseDataFlag(0,0) threshold1 = vtk.vtkImageThreshold() threshold1.SetInputConnection(extractImage.GetOutputPort()) threshold1.ThresholdByUpper(230) threshold1.SetInValue(255) threshold1.SetOutValue(0) threshold1.Update()
def main(): # colors = vtk.vtkNamedColors() fileName1, fileName2, sliceNumber = get_program_parameters() sliceOrder = SliceOrder() # Now create the RenderWindow, Renderer and Interactor # ren1 = vtk.vtkRenderer() ren2 = vtk.vtkRenderer() ren3 = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren1) renWin.AddRenderer(ren2) renWin.AddRenderer(ren3) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) greyReader = vtk.vtkMetaImageReader() greyReader.SetFileName(fileName1) greyReader.Update() greyPadder = vtk.vtkImageConstantPad() greyPadder.SetInputConnection(greyReader.GetOutputPort()) greyPadder.SetOutputWholeExtent(0, 511, 0, 511, sliceNumber, sliceNumber) greyPadder.SetConstant(0) greyPlane = vtk.vtkPlaneSource() greyTransform = vtk.vtkTransformPolyDataFilter() greyTransform.SetTransform(sliceOrder["hfsi"]) greyTransform.SetInputConnection(greyPlane.GetOutputPort()) greyNormals = vtk.vtkPolyDataNormals() greyNormals.SetInputConnection(greyTransform.GetOutputPort()) greyNormals.FlipNormalsOff() wllut = vtk.vtkWindowLevelLookupTable() wllut.SetWindow(255) wllut.SetLevel(128) wllut.SetTableRange(0, 255) wllut.Build() greyMapper = vtk.vtkPolyDataMapper() greyMapper.SetInputConnection(greyPlane.GetOutputPort()) greyTexture = vtk.vtkTexture() greyTexture.SetInputConnection(greyPadder.GetOutputPort()) greyTexture.SetLookupTable(wllut) greyTexture.SetColorModeToMapScalars() greyTexture.InterpolateOn() greyActor = vtk.vtkActor() greyActor.SetMapper(greyMapper) greyActor.SetTexture(greyTexture) segmentReader = vtk.vtkMetaImageReader() segmentReader.SetFileName(fileName2) segmentReader.Update() segmentPadder = vtk.vtkImageConstantPad() segmentPadder.SetInputConnection(segmentReader.GetOutputPort()) segmentPadder.SetOutputWholeExtent(0, 511, 0, 511, sliceNumber, sliceNumber) segmentPadder.SetConstant(0) segmentPlane = vtk.vtkPlaneSource() segmentTransform = vtk.vtkTransformPolyDataFilter() segmentTransform.SetTransform(sliceOrder["hfsi"]) segmentTransform.SetInputConnection(segmentPlane.GetOutputPort()) segmentNormals = vtk.vtkPolyDataNormals() segmentNormals.SetInputConnection(segmentTransform.GetOutputPort()) segmentNormals.FlipNormalsOn() colorLut = CreateFrogLut() segmentMapper = vtk.vtkPolyDataMapper() segmentMapper.SetInputConnection(segmentPlane.GetOutputPort()) segmentTexture = vtk.vtkTexture() segmentTexture.SetInputConnection(segmentPadder.GetOutputPort()) segmentTexture.SetLookupTable(colorLut) segmentTexture.SetColorModeToMapScalars() segmentTexture.InterpolateOff() segmentActor = vtk.vtkActor() segmentActor.SetMapper(segmentMapper) segmentActor.SetTexture(segmentTexture) segmentOverlayActor = vtk.vtkActor() segmentOverlayActor.SetMapper(segmentMapper) segmentOverlayActor.SetTexture(segmentTexture) segmentOverlayActor.GetProperty().SetOpacity(.5) ren1.SetBackground(0, 0, 0) ren1.SetViewport(0, .5, .5, 1) renWin.SetSize(640, 480) ren1.AddActor(greyActor) ren2.SetBackground(0, 0, 0) ren2.SetViewport(.5, .5, 1, 1) ren2.AddActor(segmentActor) cam1 = vtk.vtkCamera() cam1.SetViewUp(0, -1, 0) cam1.SetPosition(0, 0, -1) ren1.SetActiveCamera(cam1) ren1.ResetCamera() cam1.SetViewUp(0, -1, 0) cam1.SetPosition(0.0554068, -0.0596001, -0.491383) cam1.SetFocalPoint(0.0554068, -0.0596001, 0) ren1.ResetCameraClippingRange() ren3.AddActor(greyActor) ren3.AddActor(segmentOverlayActor) segmentOverlayActor.SetPosition(0, 0, -.01) ren3.SetBackground(0, 0, 0) ren3.SetViewport(0, 0, 1, .5) ren2.SetActiveCamera(ren1.GetActiveCamera()) ren3.SetActiveCamera(ren1.GetActiveCamera()) renWin.Render() iren.Start()
def onApply(self): inputVolume = self.getInputVolume() segmentID = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() volumesLogic = slicer.modules.volumes.logic() scene = inputVolume.GetScene() padExtent = [ -self.pad.value, self.pad.value, -self.pad.value, self.pad.value, -self.pad.value, self.pad.value ] #iterate over segments for segmentIndex in range( segmentationNode.GetSegmentation().GetNumberOfSegments()): segmentID = segmentationNode.GetSegmentation().GetNthSegmentID( segmentIndex) segmentIDs = vtk.vtkStringArray() segmentIDs.InsertNextValue(segmentID) # create volume for output outputVolumeName = inputVolume.GetName() + '_' + segmentID outputVolume = volumesLogic.CloneVolumeGeneric( scene, inputVolume, outputVolumeName, False) # crop segment slicer.app.setOverrideCursor(qt.Qt.WaitCursor) import SegmentEditorMaskVolumeLib SegmentEditorMaskVolumeLib.SegmentEditorEffect.maskVolumeWithSegment( self, segmentationNode, segmentID, "FILL_OUTSIDE", [0], inputVolume, outputVolume) #calculate extent of masked image pt = [-16.87524999999998, 19.68725000000002, 16.80000000000001, 1] rasToIjk = vtk.vtkMatrix4x4() outputVolume.GetRASToIJKMatrix(rasToIjk) print(rasToIjk.MultiplyPoint(pt)) ijkToRas = vtk.vtkMatrix4x4() outputVolume.GetIJKToRASMatrix(ijkToRas) print(ijkToRas.MultiplyPoint(pt)) cropThreshold = 0 img = slicer.modules.segmentations.logic( ).CreateOrientedImageDataFromVolumeNode(outputVolume) img.UnRegister(None) extent = [0, 0, 0, 0, 0, 0] vtkSegmentationCore.vtkOrientedImageDataResample.CalculateEffectiveExtent( img, extent, cropThreshold) # pad and crop cropFilter = vtk.vtkImageConstantPad() cropFilter.SetInputData(outputVolume.GetImageData()) cropFilter.SetConstant(self.fillValue.value) cropFilter.SetOutputWholeExtent(extent) cropFilter.Update() padFilter = vtk.vtkImageConstantPad() padFilter.SetInputData(cropFilter.GetOutput()) padFilter.SetConstant(self.fillValue.value) for i in range(len(extent)): extent[i] = extent[i] + padExtent[i] padFilter.SetOutputWholeExtent(extent) padFilter.Update() outputVolume.SetAndObserveImageData(padFilter.GetOutput()) qt.QApplication.restoreOverrideCursor()
def computeVesselnessVolume(self, currentVolumeNode, currentOutputVolumeNode, previewRegionCenterRAS=None, previewRegionSizeVoxel=-1, minimumDiameterMm=0, maximumDiameterMm=25, alpha=0.3, beta=0.3, contrastMeasure=150): logging.debug("Vesselness filtering started: diameter min={0}, max={1}, alpha={2}, beta={3}, contrastMeasure={4}".format( minimumDiameterMm, maximumDiameterMm, alpha, beta, contrastMeasure)) if not currentVolumeNode: raise ValueError("Output volume node is invalid") # this image will later hold the inputImage inImage = vtk.vtkImageData() # if we are in previewMode, we have to cut the ROI first for speed if previewRegionSizeVoxel>0: # we extract the ROI of currentVolumeNode and save it to currentOutputVolumeNode # we work in RAS space imageclipper = vtk.vtkImageConstantPad() imageclipper.SetInputData(currentVolumeNode.GetImageData()) previewRegionCenterIJK = self.getIJKFromRAS(currentVolumeNode, previewRegionCenterRAS) previewRegionRadiusVoxel = int(round(previewRegionSizeVoxel/2+0.5)) imageclipper.SetOutputWholeExtent( previewRegionCenterIJK[0]-previewRegionRadiusVoxel, previewRegionCenterIJK[0]+previewRegionRadiusVoxel, previewRegionCenterIJK[1]-previewRegionRadiusVoxel, previewRegionCenterIJK[1]+previewRegionRadiusVoxel, previewRegionCenterIJK[2]-previewRegionRadiusVoxel, previewRegionCenterIJK[2]+previewRegionRadiusVoxel) imageclipper.Update() currentOutputVolumeNode.SetAndObserveImageData(imageclipper.GetOutput()) currentOutputVolumeNode.CopyOrientation(currentVolumeNode) currentOutputVolumeNode.ShiftImageDataExtentToZeroStart() inImage.DeepCopy(currentOutputVolumeNode.GetImageData()) else: # there was no ROI extraction, so just clone the inputImage inImage.DeepCopy(currentVolumeNode.GetImageData()) currentOutputVolumeNode.CopyOrientation(currentVolumeNode) # temporarily set spacing to allow vesselness computation performed in physical space inImage.SetSpacing(currentVolumeNode.GetSpacing()) # we now compute the vesselness in RAS space, inImage has spacing and origin attached, the diameters are converted to mm # we use RAS space to support anisotropic datasets import vtkvmtkSegmentationPython as vtkvmtkSegmentation cast = vtk.vtkImageCast() cast.SetInputData(inImage) cast.SetOutputScalarTypeToFloat() cast.Update() inImage = cast.GetOutput() discretizationSteps = 5 v = vtkvmtkSegmentation.vtkvmtkVesselnessMeasureImageFilter() v.SetInputData(inImage) v.SetSigmaMin(minimumDiameterMm) v.SetSigmaMax(maximumDiameterMm) v.SetNumberOfSigmaSteps(discretizationSteps) v.SetAlpha(alpha) v.SetBeta(beta) v.SetGamma(contrastMeasure) v.Update() outImage = vtk.vtkImageData() outImage.DeepCopy(v.GetOutput()) outImage.GetPointData().GetScalars().Modified() # restore Slicer-compliant image spacing outImage.SetSpacing(1, 1, 1) # we set the outImage which has spacing 1,1,1. The ijkToRas matrix of the node will take care of that currentOutputVolumeNode.SetAndObserveImageData(outImage) # save which volume node vesselness filterint result was saved to currentVolumeNode.SetAndObserveNodeReferenceID("Vesselness", currentOutputVolumeNode.GetID()) logging.debug("Vesselness filtering completed")
def main(): fileName = get_program_parameters() colors = vtk.vtkNamedColors() # Read the CT data of the human head. reader = vtk.vtkMetaImageReader() reader.SetFileName(fileName) reader.Update() cast = vtk.vtkImageCast() cast.SetInputConnection(reader.GetOutputPort()) cast.SetOutputScalarTypeToFloat() # Magnify the image. magnify = vtk.vtkImageMagnify() magnify.SetInputConnection(cast.GetOutputPort()) magnify.SetMagnificationFactors(2, 2, 1) magnify.InterpolateOn() # Smooth the data. # Remove high frequency artifacts due to linear interpolation. smooth = vtk.vtkImageGaussianSmooth() smooth.SetInputConnection(magnify.GetOutputPort()) smooth.SetDimensionality(2) smooth.SetStandardDeviations(1.5, 1.5, 0.0) smooth.SetRadiusFactors(2.01, 2.01, 0.0) # Compute the 2D gradient. gradient = vtk.vtkImageGradient() gradient.SetInputConnection(smooth.GetOutputPort()) gradient.SetDimensionality(2) # Convert the data to polar coordinates. # The image magnitude is mapped into saturation value, # whilst the gradient direction is mapped into hue value. polar = vtk.vtkImageEuclideanToPolar() polar.SetInputConnection(gradient.GetOutputPort()) polar.SetThetaMaximum(255.0) # Add a third component to the data. # This is needed since the gradient filter only generates two components, # and we need three components to represent color. pad = vtk.vtkImageConstantPad() pad.SetInputConnection(polar.GetOutputPort()) pad.SetOutputNumberOfScalarComponents(3) pad.SetConstant(200.0) # At this point we have Hue, Value, Saturation. # Permute components so saturation will be constant. # Re-arrange components into HSV order. permute = vtk.vtkImageExtractComponents() permute.SetInputConnection(pad.GetOutputPort()) permute.SetComponents(0, 2, 1) # Convert back into RGB values. rgb = vtk.vtkImageHSVToRGB() rgb.SetInputConnection(permute.GetOutputPort()) rgb.SetMaximum(255.0) # Set up a viewer for the image. # Note that vtkImageViewer and vtkImageViewer2 are convenience wrappers around # vtkActor2D, vtkImageMapper, vtkRenderer, and vtkRenderWindow. # So all that needs to be supplied is the interactor. viewer = vtk.vtkImageViewer() viewer.SetInputConnection(rgb.GetOutputPort()) viewer.SetZSlice(22) viewer.SetColorWindow(255.0) viewer.SetColorLevel(127.0) viewer.GetRenderWindow().SetSize(512, 512) viewer.GetRenderer().SetBackground(colors.GetColor3d("Silver")) # Create the RenderWindowInteractor. iren = vtk.vtkRenderWindowInteractor() viewer.SetupInteractor(iren) viewer.Render() iren.Initialize() iren.Start()
def main(): colors = vtk.vtkNamedColors() fileName = get_program_parameters() # Read the image. readerFactory = vtk.vtkImageReader2Factory() reader = readerFactory.CreateImageReader2(fileName) reader.SetFileName(fileName) reader.Update() # Pipelines constantPad = vtk.vtkImageConstantPad() constantPad.SetInputConnection(reader.GetOutputPort()) constantPad.SetConstant(800) constantPad.SetOutputWholeExtent(-127, 383, -127, 383, 22, 22) mirrorPad = vtk.vtkImageMirrorPad() mirrorPad.SetInputConnection(reader.GetOutputPort()) mirrorPad.SetOutputWholeExtent(constantPad.GetOutputWholeExtent()) # Create actors constantPadColor = vtk.vtkImageMapToWindowLevelColors() constantPadColor.SetWindow(2000) constantPadColor.SetLevel(1000) constantPadColor.SetInputConnection(constantPad.GetOutputPort()) constantPadActor = vtk.vtkImageActor() constantPadActor.GetMapper().SetInputConnection( constantPadColor.GetOutputPort()) constantPadActor.GetProperty().SetInterpolationTypeToNearest() mirrorPadColor = vtk.vtkImageMapToWindowLevelColors() mirrorPadColor.SetWindow(2000) mirrorPadColor.SetLevel(1000) mirrorPadColor.SetInputConnection(mirrorPad.GetOutputPort()) mirrorPadActor = vtk.vtkImageActor() mirrorPadActor.GetMapper().SetInputConnection( mirrorPadColor.GetOutputPort()) mirrorPadActor.GetProperty().SetInterpolationTypeToNearest() # Setup the renderers. constantPadRenderer = vtk.vtkRenderer() constantPadRenderer.SetViewport(0.0, 0.0, 0.5, 1.0) constantPadRenderer.AddActor(constantPadActor) constantPadRenderer.ResetCamera() constantPadRenderer.SetBackground(colors.GetColor3d("SlateGray")) mirrorPadRenderer = vtk.vtkRenderer() mirrorPadRenderer.SetViewport(0.5, 0.0, 1.0, 1.0) mirrorPadRenderer.AddActor(mirrorPadActor) mirrorPadRenderer.SetActiveCamera(constantPadRenderer.GetActiveCamera()) mirrorPadRenderer.SetBackground(colors.GetColor3d("LightSlateGray")) renderWindow = vtk.vtkRenderWindow() renderWindow.SetSize(600, 300) renderWindow.SetWindowName('Pad') renderWindow.AddRenderer(constantPadRenderer) renderWindow.AddRenderer(mirrorPadRenderer) renderWindowInteractor = vtk.vtkRenderWindowInteractor() style = vtk.vtkInteractorStyleImage() renderWindowInteractor.SetInteractorStyle(style) renderWindowInteractor.SetRenderWindow(renderWindow) constantPadRenderer.GetActiveCamera().Dolly(1.2) constantPadRenderer.ResetCameraClippingRange() renderWindowInteractor.Initialize() renderWindowInteractor.Start()
def apply(self, ijkPoints): kernelSizePixel = self.getKernelSizePixel() if kernelSizePixel[0]<=0 and kernelSizePixel[1]<=0 and kernelSizePixel[2]<=0: return qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) # Get parameter set node parameterSetNode = self.scriptedEffect.parameterSetNode() # Get parameters minimumThreshold = self.scriptedEffect.doubleParameter("MinimumThreshold") maximumThreshold = self.scriptedEffect.doubleParameter("MaximumThreshold") # Get modifier labelmap modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap() # Get master volume image data masterImageData = self.scriptedEffect.masterVolumeImageData() # Set intensity range oldMasterVolumeIntensityMask = parameterSetNode.GetMasterVolumeIntensityMask() parameterSetNode.MasterVolumeIntensityMaskOn() oldIntensityMaskRange = parameterSetNode.GetMasterVolumeIntensityMaskRange() intensityRange = [265.00, 1009.00] if oldMasterVolumeIntensityMask: intensityRange = [max(oldIntensityMaskRange[0], minimumThreshold), min(oldIntensityMaskRange[1], maximumThreshold)] parameterSetNode.SetMasterVolumeIntensityMaskRange(intensityRange) roiNode = lumbarSeed ##self.roiSelector.currentNode() clippedMasterImageData = masterImageData if roiNode is not None: worldToImageMatrix = vtk.vtkMatrix4x4() masterImageData.GetWorldToImageMatrix(worldToImageMatrix) bounds = [0,0,0,0,0,0] roiNode.GetRASBounds(bounds) corner1RAS = [bounds[0], bounds[2], bounds[4], 1] corner1IJK = [0, 0, 0, 0] worldToImageMatrix.MultiplyPoint(corner1RAS, corner1IJK) corner2RAS = [bounds[1], bounds[3], bounds[5], 1] corner2IJK = [0, 0, 0, 0] worldToImageMatrix.MultiplyPoint(corner2RAS, corner2IJK) extent = [0, -1, 0, -1, 0, -1] for i in range(3): lowerPoint = min(corner1IJK[i], corner2IJK[i]) upperPoint = max(corner1IJK[i], corner2IJK[i]) extent[2*i] = int(math.floor(lowerPoint)) extent[2*i+1] = int(math.ceil(upperPoint)) imageToWorldMatrix = vtk.vtkMatrix4x4() masterImageData.GetImageToWorldMatrix(imageToWorldMatrix) clippedMasterImageData = slicer.vtkOrientedImageData() self.padder = vtk.vtkImageConstantPad() self.padder.SetInputData(masterImageData) self.padder.SetOutputWholeExtent(extent) self.padder.Update() clippedMasterImageData.ShallowCopy(self.padder.GetOutput()) clippedMasterImageData.SetImageToWorldMatrix(imageToWorldMatrix) # Pipeline self.thresh = vtk.vtkImageThreshold() self.thresh.SetInValue(LABEL_VALUE) self.thresh.SetOutValue(BACKGROUND_VALUE) self.thresh.SetInputData(clippedMasterImageData) self.thresh.ThresholdBetween(minimumThreshold, maximumThreshold) self.thresh.SetOutputScalarTypeToUnsignedChar() self.thresh.Update() self.erode = vtk.vtkImageDilateErode3D() self.erode.SetInputConnection(self.thresh.GetOutputPort()) self.erode.SetDilateValue(BACKGROUND_VALUE) self.erode.SetErodeValue(LABEL_VALUE) self.erode.SetKernelSize( kernelSizePixel[0], kernelSizePixel[1], kernelSizePixel[2]) self.erodeCast = vtk.vtkImageCast() self.erodeCast.SetInputConnection(self.erode.GetOutputPort()) self.erodeCast.SetOutputScalarTypeToUnsignedInt() self.erodeCast.Update() # Remove small islands self.islandMath = vtkITK.vtkITKIslandMath() self.islandMath.SetInputConnection(self.erodeCast.GetOutputPort()) self.islandMath.SetFullyConnected(False) self.islandMath.SetMinimumSize(125) # remove regions smaller than 5x5x5 voxels self.islandThreshold = vtk.vtkImageThreshold() self.islandThreshold.SetInputConnection(self.islandMath.GetOutputPort()) self.islandThreshold.ThresholdByLower(BACKGROUND_VALUE) self.islandThreshold.SetInValue(BACKGROUND_VALUE) self.islandThreshold.SetOutValue(LABEL_VALUE) self.islandThreshold.SetOutputScalarTypeToUnsignedChar() self.islandThreshold.Update() # Points may be outside the region after it is eroded. # Snap the points to LABEL_VALUE voxels, snappedIJKPoints = self.snapIJKPointsToLabel(ijkPoints, self.islandThreshold.GetOutput()) if snappedIJKPoints.GetNumberOfPoints() == 0: qt.QApplication.restoreOverrideCursor() return # Convert points to real data coordinates. Required for vtkImageThresholdConnectivity. seedPoints = vtk.vtkPoints() origin = masterImageData.GetOrigin() spacing = masterImageData.GetSpacing() for i in range(snappedIJKPoints.GetNumberOfPoints()): ijkPoint = snappedIJKPoints.GetPoint(i) seedPoints.InsertNextPoint( origin[0]+ijkPoint[0]*spacing[0], origin[1]+ijkPoint[1]*spacing[1], origin[2]+ijkPoint[2]*spacing[2]) segmentationAlgorithm = self.scriptedEffect.parameter(SEGMENTATION_ALGORITHM_PARAMETER_NAME) if segmentationAlgorithm == SEGMENTATION_ALGORITHM_MASKING: self.runMasking(seedPoints, self.islandThreshold.GetOutput(), modifierLabelmap) else: self.floodFillingFilterIsland = vtk.vtkImageThresholdConnectivity() self.floodFillingFilterIsland.SetInputConnection(self.islandThreshold.GetOutputPort()) self.floodFillingFilterIsland.SetInValue(SELECTED_ISLAND_VALUE) self.floodFillingFilterIsland.ReplaceInOn() self.floodFillingFilterIsland.ReplaceOutOff() self.floodFillingFilterIsland.ThresholdBetween(265.00, 1009.00) self.floodFillingFilterIsland.SetSeedPoints(seedPoints) self.floodFillingFilterIsland.Update() self.maskCast = vtk.vtkImageCast() self.maskCast.SetInputData(self.thresh.GetOutput()) self.maskCast.SetOutputScalarTypeToUnsignedChar() self.maskCast.Update() self.imageMask = vtk.vtkImageMask() self.imageMask.SetInputConnection(self.floodFillingFilterIsland.GetOutputPort()) self.imageMask.SetMaskedOutputValue(OUTSIDE_THRESHOLD_VALUE) self.imageMask.SetMaskInputData(self.maskCast.GetOutput()) self.imageMask.Update() imageMaskOutput = slicer.vtkOrientedImageData() imageMaskOutput.ShallowCopy(self.imageMask.GetOutput()) imageMaskOutput.CopyDirections(clippedMasterImageData) imageToWorldMatrix = vtk.vtkMatrix4x4() imageMaskOutput.GetImageToWorldMatrix(imageToWorldMatrix) segmentOutputLabelmap = slicer.vtkOrientedImageData() if segmentationAlgorithm == SEGMENTATION_ALGORITHM_GROWCUT: self.runGrowCut(clippedMasterImageData, imageMaskOutput, segmentOutputLabelmap) elif segmentationAlgorithm == SEGMENTATION_ALGORITHM_WATERSHED: self.runWatershed(clippedMasterImageData, imageMaskOutput, segmentOutputLabelmap) else: logging.error("Unknown segmentation algorithm: \"" + segmentationAlgorithm + "\"") segmentOutputLabelmap.SetImageToWorldMatrix(imageToWorldMatrix) self.selectedSegmentThreshold = vtk.vtkImageThreshold() self.selectedSegmentThreshold.SetInputData(segmentOutputLabelmap) self.selectedSegmentThreshold.ThresholdBetween(SELECTED_ISLAND_VALUE, SELECTED_ISLAND_VALUE) self.selectedSegmentThreshold.SetInValue(LABEL_VALUE) self.selectedSegmentThreshold.SetOutValue(BACKGROUND_VALUE) self.selectedSegmentThreshold.SetOutputScalarType(modifierLabelmap.GetScalarType()) self.selectedSegmentThreshold.Update() modifierLabelmap.ShallowCopy(self.selectedSegmentThreshold.GetOutput()) self.scriptedEffect.saveStateForUndo() self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd) parameterSetNode.SetMasterVolumeIntensityMask(oldMasterVolumeIntensityMask) parameterSetNode.SetMasterVolumeIntensityMaskRange(oldIntensityMaskRange) qt.QApplication.restoreOverrideCursor()
arr0 = arr0.reshape(dims[1], dims[0], -1) offset0 = (nxy - dims[1]) // 2 offset1 = (nxy - dims[0]) // 2 arr[offset0:nxy - offset0, offset1:nxy - offset1, :] = arr0 colors = numpy_support.numpy_to_vtk( arr.ravel(), deep=False, array_type=vtk.VTK_UNSIGNED_CHAR) newImage = vtk.vtkImageData() newImage.SetDimensions(nxy, nxy, 1) colors.SetNumberOfComponents(4) colors.SetNumberOfTuples(newImage.GetNumberOfPoints()) newImage.GetPointData().SetScalars(colors) else: padFilter = vtk.vtkImageConstantPad() curExtent = textImage.GetExtent() curDims = textImage.GetDimensions() padExtent = np.r_[nxy, nxy, 1] - np.array(curDims) newExtent = (curExtent[0] - (padExtent[0] + 1) // 2, curExtent[1] + padExtent[0] // 2, curExtent[2] - (padExtent[1] + 1) // 2, curExtent[3] + padExtent[1] // 2, curExtent[4] - (padExtent[2] + 1) // 2, curExtent[5] + padExtent[2] // 2) padFilter.SetOutputWholeExtent(-((nxy - 1) // 2), nxy // 2, 0, nxy - 1, 0, 0) padFilter.SetOutputNumberOfScalarComponents(4) padFilter.SetInputData(textImage)
pow += 1 if (amt <= 0): return 1 << pow orgX = imageIn.GetExecutive().GetWholeExtent( imageIn.GetOutputInformation(0))[1]\ - imageIn.GetExecutive().GetWholeExtent( imageIn.GetOutputInformation(0))[0] + 1 orgY = imageIn.GetExecutive().GetWholeExtent( imageIn.GetOutputInformation(0))[3]\ - imageIn.GetExecutive().GetWholeExtent( imageIn.GetOutputInformation(0))[2] + 1 padX = PowerOfTwo(orgX) padY = PowerOfTwo(orgY) imagePowerOf2 = vtk.vtkImageConstantPad() imagePowerOf2.SetInputConnection(imageIn.GetOutputPort()) imagePowerOf2.SetOutputWholeExtent(0, padX - 1, 0, padY - 1, 0, 0) toHSV = vtk.vtkImageRGBToHSV() toHSV.SetInputConnection(imageIn.GetOutputPort()) toHSV.GetExecutive().SetReleaseDataFlag(0, 0) extractImage = vtk.vtkImageExtractComponents() extractImage.SetInputConnection(toHSV.GetOutputPort()) extractImage.SetComponents(2) extractImage.GetExecutive().SetReleaseDataFlag(0, 0) threshold1 = vtk.vtkImageThreshold() threshold1.SetInputConnection(extractImage.GetOutputPort()) threshold1.ThresholdByUpper(230)
def VTKImageTransform(x,dx,dy,numret=False,reverse=False,origsize=None, cubic=False,interp=True,scalex=1,scaley=1,constant=0,wrap=False, mirror=False): maxdx = max([int(max(abs(dx.ravel()))+1),(dx.shape[1]-x.shape[1])]) maxdy = max([int(max(abs(dy.ravel()))+1),(dx.shape[0]-x.shape[0])]) dx = dx.astype(np.float32) dy = dy.astype(np.float32) if scalex > 1: xx = np.arange(x.shape[1]) dx = (xx[np.newaxis,::]+dx).astype(np.float32) dy = VTKGrowN(dy,scalex,1,numret=True) dx = VTKGrowN(dx,scalex,1,numret=True) dx = (dx-np.arange(scalex*x.shape[1])[np.newaxis,::]).\ astype(np.float32) if scaley > 1: yy = np.arange(x.shape[0]) dy = (yy[::,np.newaxis]+dy).astype(np.float32) dy = VTKGrowN(dy,1,scaley,numret=True) dx = VTKGrowN(dx,1,scaley,numret=True) dy = (dy-np.arange(scaley*x.shape[0])[::,np.newaxis]).\ astype(np.float32) if type(x) == np.ndarray: i = NumToVTKImage(x) else: i = x if type(dx) == np.ndarray: tx = NumToVTKImage(dx) else: tx = dx if type(dy) == np.ndarray: ty = NumToVTKImage(dy) else: ty = dy dm = ty.GetDimensions() dz = np.zeros(dy.shape,dy.dtype) tz = NumToVTKImage(dz) a = vtk.vtkImageAppendComponents() a.AddInputData(tx) a.AddInputData(ty) a.AddInputData(tz) a.Update() t = a.GetOutput() r = vtk.vtkGridTransform() r.SetDisplacementGridData(t) r.Update() s = vtk.vtkImageReslice() s.WrapOff() s.MirrorOn() if interp: s.InterpolateOn() if cubic: s.SetInterpolationModeToCubic() else: s.SetInterpolationModeToLinear() s.SetOutputDimensionality(2) if reverse: r.SetInterpolationModeToLinear() r.SetInverseTolerance(0.001) r.SetInverseIterations(1000) r.DebugOff() ir = r.GetInverse() ir.SetInterpolationModeToLinear() ir.SetInverseTolerance(0.001) ir.SetInverseIterations(1000) ir.GlobalWarningDisplayOff() s.SetResliceTransform(ir) s.AutoCropOutputOff() if origsize: s.SetOutputExtent(0,origsize[1]-1,0,origsize[0]-1,0,0) else: s.SetOutputExtent(0,scalex*dm[0]-1,0,scaley*dm[1]-1,0,0) else: r.SetInterpolationModeToCubic() r.SetInverseTolerance(0.001) r.SetInverseIterations(1000) r.GlobalWarningDisplayOff() s.SetOutputExtent(0,scalex*dm[0]-1,0,scaley*dm[1]-1,0,0) s.AutoCropOutputOff() s.SetResliceTransform(r) if mirror: ip = vtk.vtkImageMirrorPad() elif wrap: ip = vtk.vtkImageWrapPad() else: ip = vtk.vtkImageConstantPad(); ip.SetConstant(constant) ip.SetOutputWholeExtent(0-maxdx,dm[0]-1+maxdx,0-maxdy,dm[1]-1+maxdy,0,0) ip.SetInputData(i) ip.Update() s.SetInputData(ip.GetOutput()) o=s.GetOutput() s.Update() if numret: ri = VTKImageToNum(o) else: ri = o return ri
def main(): # colors = vtk.vtkNamedColors() filename1 = "C:\\Users\\chenjiaxing\\Desktop\\Python\\Edge220\\" filename2 = "C:\\Users\\chenjiaxing\\Desktop\\Python\\JPEG220\\6\\" rows = 128 columns = 128 slicenumber = 19 start_slice = 1 end_slice = 51 pixel_size = 1 spacing = 1 endx = rows - 1 endy = columns - 1 endz = end_slice - 1 sliceOrder = SliceOrder() # Now create the RenderWindow, Renderer and Interactor # ren1 = vtk.vtkRenderer() ren2 = vtk.vtkRenderer() ren3 = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren1) renWin.AddRenderer(ren2) renWin.AddRenderer(ren3) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) greyReader = vtk.vtkJPEGReader() greyReader.SetFilePrefix(filename1) greyReader.SetFilePattern("%s%d.jpg") greyReader.SetDataSpacing(pixel_size, pixel_size, spacing) greyReader.SetDataExtent(0, endx, 0, endy, slicenumber, slicenumber) greyReader.DebugOn() greyPadder = vtk.vtkImageConstantPad() greyPadder.SetInputConnection(greyReader.GetOutputPort()) greyPadder.SetOutputWholeExtent(0, 127, 0, 127, slicenumber, slicenumber) greyPadder.SetConstant(0) greyPlane = vtk.vtkPlaneSource() greyTransform = vtk.vtkTransformPolyDataFilter() greyTransform.SetTransform(sliceOrder["hfsi"]) greyTransform.SetInputConnection(greyPlane.GetOutputPort()) greyNormals = vtk.vtkPolyDataNormals() greyNormals.SetInputConnection(greyTransform.GetOutputPort()) greyNormals.FlipNormalsOff() wllut = vtk.vtkWindowLevelLookupTable() wllut.SetWindow(255) wllut.SetLevel(128) wllut.SetTableRange(0, 255) wllut.Build() greyMapper = vtk.vtkPolyDataMapper() greyMapper.SetInputConnection(greyPlane.GetOutputPort()) greyTexture = vtk.vtkTexture() greyTexture.SetInputConnection(greyPadder.GetOutputPort()) greyTexture.SetLookupTable(wllut) greyTexture.SetColorModeToMapScalars() greyTexture.InterpolateOn() greyActor = vtk.vtkActor() greyActor.SetMapper(greyMapper) greyActor.SetTexture(greyTexture) segmentReader = vtk.vtkJPEGReader() segmentReader.SetFilePrefix(filename2) segmentReader.SetFilePattern("%s%d.jpg") segmentReader.SetDataSpacing(pixel_size, pixel_size, spacing) #segmentReader.SetDataVOI(0, endx, 0, endy, slicenumber, slicenumber) segmentReader.SetDataExtent(0, endx, 0, endy, slicenumber, slicenumber) segmentReader.Update() #imageThreshold filter LowThreshold = 1 UpperThreshold = 16 selectTissue = vtk.vtkImageThreshold() selectTissue.ThresholdBetween(LowThreshold, UpperThreshold) selectTissue.SetInValue(UpperThreshold) selectTissue.SetOutValue(0) selectTissue.SetInputConnection(segmentReader.GetOutputPort()) segmentPadder = vtk.vtkImageConstantPad() #segmentPadder.SetInputConnection(segmentReader.GetOutputPort()) segmentPadder.SetInputConnection(selectTissue.GetOutputPort()) segmentPadder.SetOutputWholeExtent(0, 127, 0, 127, slicenumber, slicenumber) segmentPadder.SetConstant(0) segmentPlane = vtk.vtkPlaneSource() segmentTransform = vtk.vtkTransformPolyDataFilter() segmentTransform.SetTransform(sliceOrder["hfsi"]) segmentTransform.SetInputConnection(segmentPlane.GetOutputPort()) segmentNormals = vtk.vtkPolyDataNormals() segmentNormals.SetInputConnection(segmentTransform.GetOutputPort()) segmentNormals.FlipNormalsOn() colorLut = CreateFrogLut() segmentMapper = vtk.vtkPolyDataMapper() segmentMapper.SetInputConnection(segmentPlane.GetOutputPort()) segmentTexture = vtk.vtkTexture() segmentTexture.SetInputConnection(segmentPadder.GetOutputPort()) segmentTexture.SetLookupTable(colorLut) segmentTexture.SetColorModeToMapScalars() segmentTexture.InterpolateOff() segmentActor = vtk.vtkActor() segmentActor.SetMapper(segmentMapper) segmentActor.SetTexture(segmentTexture) segmentOverlayActor = vtk.vtkActor() segmentOverlayActor.SetMapper(segmentMapper) segmentOverlayActor.SetTexture(segmentTexture) segmentOverlayActor.GetProperty().SetOpacity(.5) ren1.SetBackground(0, 0, 0) ren1.SetViewport(0, .5, .5, 1) renWin.SetSize(640, 480) ren1.AddActor(greyActor) ren2.SetBackground(0, 0, 0) ren2.SetViewport(.5, .5, 1, 1) ren2.AddActor(segmentActor) cam1 = vtk.vtkCamera() cam1.SetViewUp(0, -1, 0) cam1.SetPosition(0, 0, -1) ren1.SetActiveCamera(cam1) ren1.ResetCamera() cam1.SetViewUp(0, -1, 0) cam1.SetPosition(0.0554068, -0.0596001, -0.491383) cam1.SetFocalPoint(0.0554068, -0.0596001, 0) ren1.ResetCameraClippingRange() ren3.AddActor(greyActor) ren3.AddActor(segmentOverlayActor) segmentOverlayActor.SetPosition(0, 0, -.01) ren3.SetBackground(0, 0, 0) ren3.SetViewport(0, 0, 1, .5) ren2.SetActiveCamera(ren1.GetActiveCamera()) ren3.SetActiveCamera(ren1.GetActiveCamera()) renWin.Render() iren.Start()
def VTKConvolve(im,numret=0,k=5,clip=1,x=1,y=1,wrap=0,mirror=1,constant=None, kernel=None): if type(im) == np.ndarray: i = NumToVTKImage(im) else: i = im d = i.GetDimensions() e = i.GetExtent() dtest = np.sort(d) if sum(dtest[:2]) == 2: onedim=1 else: onedim = 0 if (d[0] == 1): oned = 1 elif (d[1] == 1): oned = 2 else: oned = 0 if x and not y: oned = 2 if y and not x: oned = 1 if onedim: oned = 1 if constant is not None: ip = vtk.vtkImageConstantPad() if d[0] > 1: x0,x1=-k,d[0]+k-1 else: x0,x1=0,0 if d[1] > 1: y0,y1=-k,d[1]+k-1 else: y0,y1=0,0 ip.SetOutputWholeExtent(x0,x1,y0,y1,0,0) ip.SetConstant(constant) ip.SetInputData(i) i = ip.GetOutput() ip.Update() elif mirror: ip = vtk.vtkImageMirrorPad() if d[0] > 1: x0,x1=-k,d[0]+k-1 else: x0,x1=0,0 if d[1] > 1: y0,y1=-k,d[1]+k-1 else: y0,y1=0,0 ip.SetOutputWholeExtent(x0,x1,y0,y1,0,0) ip.SetInputData(i) i = ip.GetOutput() ip.Update() elif wrap: ip = vtk.vtkImageWrapPad() if d[0] > 1: x0,x1=-k,d[0]+k-1 else: x0,x1=0,0 if d[1] > 1: y0,y1=-k,d[1]+k-1 else: y0,y1=0,0 ip.SetOutputWholeExtent(x0,x1,y0,y1,0,0) ip.SetInputData(i) i = ip.GetOutput() ip.Update() c = vtk.vtkImageConvolve() if kernel is None: if k == 3: k1 = np.asarray([0.25,0.5,0.25]) elif k == 5: k1 = np.asarray([0.0625,0.25,0.375,0.25,0.0625]) if onedim: ke = np.ones((k,k),np.float64) * k1 elif not oned: ke = k1[::,np.newaxis]*k1[np.newaxis,::] elif oned == 1: ke = np.zeros((k,k),np.float64); ke[::,2] = k1 elif oned == 2: ke = np.zeros((k,k),np.float64); ke[2] = k1 ke = np.ravel(ke) ke = ke / np.sum(ke) if onedim: ke = len(k1)*ke else: k = kernel.shape[0] ke = np.ravel(kernel) if k == 3: c.SetKernel3x3(ke) if k == 5: c.SetKernel5x5(ke) if k == 7: c.SetKernel7x7(ke) c.SetInputData(i) o = c.GetOutput() c.Update() if clip: ic = vtk.vtkImageClip() notx = -(not x) * 0 noty = -(not y) * 0 ic.SetOutputWholeExtent(notx,d[0]-1+notx,noty,d[1]-1+noty,0,0) ic.SetInputData(o) ic.ClipDataOn() o = ic.GetOutput() ic.Update() if numret: return VTKImageToNum(o) else: return o
def onApply(self): import SegmentEditorEffects if not hasattr(SegmentEditorEffects, 'SegmentEditorMaskVolumeEffect'): # Slicer 4.11 and earlier - Mask volume is in an extension import SegmentEditorMaskVolumeLib maskVolumeWithSegment = SegmentEditorMaskVolumeLib.SegmentEditorEffect.maskVolumeWithSegment else: maskVolumeWithSegment = SegmentEditorEffects.SegmentEditorMaskVolumeEffect.maskVolumeWithSegment inputVolume = self.getInputVolume() currentSegmentID = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() volumesLogic = slicer.modules.volumes.logic() scene = inputVolume.GetScene() padExtent = [ -self.padEdit.value, self.padEdit.value, -self.padEdit.value, self.padEdit.value, -self.padEdit.value, self.padEdit.value ] fillValue = self.fillValueEdit.value # Create a new folder in subject hierarchy where all the generated volumes will be placed into shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode( slicer.mrmlScene) inputVolumeParentItem = shNode.GetItemParent( shNode.GetItemByDataNode(inputVolume)) outputShFolder = shNode.CreateFolderItem( inputVolumeParentItem, inputVolume.GetName() + " split") # Filter out visible segments, or only the selected segment, irrespective of its visibility. slicer.app.setOverrideCursor(qt.Qt.WaitCursor) visibleSegmentIDs = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs( visibleSegmentIDs) if (self.scriptedEffect.integerParameter("ApplyToAllVisibleSegments") != 0): inputSegments = [] for segmentIndex in range(visibleSegmentIDs.GetNumberOfValues()): inputSegments.append(visibleSegmentIDs.GetValue(segmentIndex)) else: inputSegments = [currentSegmentID] # Iterate over targeted segments for segmentID in inputSegments: # Create volume for output outputVolumeName = inputVolume.GetName( ) + ' ' + segmentationNode.GetSegmentation().GetSegment( segmentID).GetName() outputVolume = volumesLogic.CloneVolumeGeneric( scene, inputVolume, outputVolumeName, False) # Crop segment maskExtent = [0] * 6 maskVolumeWithSegment(segmentationNode, segmentID, "FILL_OUTSIDE", [fillValue], inputVolume, outputVolume, maskExtent) # Calculate padded extent of segment extent = [0] * 6 for i in range(len(extent)): extent[i] = maskExtent[i] + padExtent[i] # Calculate the new origin ijkToRas = vtk.vtkMatrix4x4() outputVolume.GetIJKToRASMatrix(ijkToRas) origin_IJK = [extent[0], extent[2], extent[4], 1] origin_RAS = ijkToRas.MultiplyPoint(origin_IJK) # Pad and crop padFilter = vtk.vtkImageConstantPad() padFilter.SetInputData(outputVolume.GetImageData()) padFilter.SetConstant(fillValue) padFilter.SetOutputWholeExtent(extent) padFilter.Update() paddedImg = padFilter.GetOutput() # Normalize output image paddedImg.SetOrigin(0, 0, 0) paddedImg.SetSpacing(1.0, 1.0, 1.0) paddedImg.SetExtent(0, extent[1] - extent[0], 0, extent[3] - extent[2], 0, extent[5] - extent[4]) outputVolume.SetAndObserveImageData(paddedImg) outputVolume.SetOrigin(origin_RAS[0], origin_RAS[1], origin_RAS[2]) # Place output image in subject hierarchy folder shNode.SetItemParent(shNode.GetItemByDataNode(outputVolume), outputShFolder) qt.QApplication.restoreOverrideCursor()
def main(data_folder, slice_number): colors = vtk.vtkNamedColors() path = Path(data_folder) if path.is_dir(): s = '' fn_1 = path.joinpath('frog').with_suffix('.mhd') if not fn_1.is_file(): s += 'The file: {:s} does not exist.\n'.format(str(fn_1)) print(s) fn_2 = path.joinpath('frogtissue').with_suffix('.mhd') if not fn_2.is_file(): s += 'The file: {:s} does not exist.'.format(str(fn_2)) if s: print(s) return else: print('Expected a path to frog.mhs and frogtissue.mhd') return so = SliceOrder() # Now create the RenderWindow, Renderer and Interactor # ren1 = vtk.vtkRenderer() ren2 = vtk.vtkRenderer() ren3 = vtk.vtkRenderer() ren_win = vtk.vtkRenderWindow() ren_win.AddRenderer(ren1) ren_win.AddRenderer(ren2) ren_win.AddRenderer(ren3) ren_win.SetWindowName('FrogSlice') iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(ren_win) grey_reader = vtk.vtkMetaImageReader() grey_reader.SetFileName(str(fn_1)) grey_reader.Update() grey_padder = vtk.vtkImageConstantPad() grey_padder.SetInputConnection(grey_reader.GetOutputPort()) grey_padder.SetOutputWholeExtent(0, 511, 0, 511, slice_number, slice_number) grey_padder.SetConstant(0) grey_plane = vtk.vtkPlaneSource() grey_transform = vtk.vtkTransformPolyDataFilter() grey_transform.SetTransform(so.get('hfsi')) grey_transform.SetInputConnection(grey_plane.GetOutputPort()) grey_normals = vtk.vtkPolyDataNormals() grey_normals.SetInputConnection(grey_transform.GetOutputPort()) grey_normals.FlipNormalsOff() wllut = vtk.vtkWindowLevelLookupTable() wllut.SetWindow(255) wllut.SetLevel(128) wllut.SetTableRange(0, 255) wllut.Build() grey_mapper = vtk.vtkPolyDataMapper() grey_mapper.SetInputConnection(grey_plane.GetOutputPort()) grey_texture = vtk.vtkTexture() grey_texture.SetInputConnection(grey_padder.GetOutputPort()) grey_texture.SetLookupTable(wllut) grey_texture.SetColorModeToMapScalars() grey_texture.InterpolateOn() grey_actor = vtk.vtkActor() grey_actor.SetMapper(grey_mapper) grey_actor.SetTexture(grey_texture) segment_reader = vtk.vtkMetaImageReader() segment_reader.SetFileName(str(fn_2)) segment_reader.Update() segment_padder = vtk.vtkImageConstantPad() segment_padder.SetInputConnection(segment_reader.GetOutputPort()) segment_padder.SetOutputWholeExtent(0, 511, 0, 511, slice_number, slice_number) segment_padder.SetConstant(0) segment_plane = vtk.vtkPlaneSource() segment_transform = vtk.vtkTransformPolyDataFilter() segment_transform.SetTransform(so.get('hfsi')) segment_transform.SetInputConnection(segment_plane.GetOutputPort()) segment_normals = vtk.vtkPolyDataNormals() segment_normals.SetInputConnection(segment_transform.GetOutputPort()) segment_normals.FlipNormalsOn() lut = create_frog_lut(colors) segment_mapper = vtk.vtkPolyDataMapper() segment_mapper.SetInputConnection(segment_plane.GetOutputPort()) segment_texture = vtk.vtkTexture() segment_texture.SetInputConnection(segment_padder.GetOutputPort()) segment_texture.SetLookupTable(lut) segment_texture.SetColorModeToMapScalars() segment_texture.InterpolateOff() segment_actor = vtk.vtkActor() segment_actor.SetMapper(segment_mapper) segment_actor.SetTexture(segment_texture) segment_overlay_actor = vtk.vtkActor() segment_overlay_actor.SetMapper(segment_mapper) segment_overlay_actor.SetTexture(segment_texture) segment_overlay_actor.GetProperty().SetOpacity(.5) ren1.SetBackground(0, 0, 0) ren1.SetViewport(0, 0.5, 0.5, 1) ren_win.SetSize(640, 480) ren1.AddActor(grey_actor) ren2.SetBackground(0, 0, 0) ren2.SetViewport(0.5, 0.5, 1, 1) ren2.AddActor(segment_actor) cam1 = vtk.vtkCamera() cam1.SetViewUp(0, -1, 0) cam1.SetPosition(0, 0, -1) ren1.SetActiveCamera(cam1) ren1.ResetCamera() cam1.SetViewUp(0, -1, 0) cam1.SetPosition(0.0554068, -0.0596001, -0.491383) cam1.SetFocalPoint(0.0554068, -0.0596001, 0) ren1.ResetCameraClippingRange() ren3.AddActor(grey_actor) ren3.AddActor(segment_overlay_actor) segment_overlay_actor.SetPosition(0, 0, -0.01) ren1.SetBackground(colors.GetColor3d('SlateGray')) ren2.SetBackground(colors.GetColor3d('SlateGray')) ren3.SetBackground(colors.GetColor3d('SlateGray')) ren3.SetViewport(0, 0, 1, 0.5) ren2.SetActiveCamera(ren1.GetActiveCamera()) ren3.SetActiveCamera(ren1.GetActiveCamera()) ren_win.Render() iren.Start()
def preview(self): # Get master volume image data import vtkSegmentationCorePython as vtkSegmentationCore # Get segmentation segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() previewNode = self.getPreviewNode() previewOpacity = self.getPreviewOpacity() previewShow3D = self.getPreviewShow3D() # If the selectedSegmentIds have been specified, then they shouldn't be overwritten here currentSelectedSegmentIds = self.selectedSegmentIds if self.effectiveExtentChanged(): self.reset() # Restore the selectedSegmentIds self.selectedSegmentIds = currentSelectedSegmentIds if self.selectedSegmentIds is None: self.selectedSegmentIds = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs( self.selectedSegmentIds) if self.selectedSegmentIds.GetNumberOfValues( ) < self.minimumNumberOfSegments: logging.error( "Auto-complete operation skipped: at least {0} visible segments are required" .format(self.minimumNumberOfSegments)) self.selectedSegmentIds = None return # Compute merged labelmap extent (effective extent slightly expanded) if not self.mergedLabelmapGeometryImage: self.mergedLabelmapGeometryImage = slicer.vtkOrientedImageData( ) commonGeometryString = segmentationNode.GetSegmentation( ).DetermineCommonLabelmapGeometry( vtkSegmentationCore.vtkSegmentation. EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.selectedSegmentIds) if not commonGeometryString: logging.info( "Auto-complete operation skipped: all visible segments are empty" ) return vtkSegmentationCore.vtkSegmentationConverter.DeserializeImageGeometry( commonGeometryString, self.mergedLabelmapGeometryImage) masterImageData = self.scriptedEffect.masterVolumeImageData() masterImageExtent = masterImageData.GetExtent() labelsEffectiveExtent = self.mergedLabelmapGeometryImage.GetExtent( ) # Margin size is relative to combined seed region size, but minimum of 3 voxels print("self.extentGrowthRatio = {0}".format( self.extentGrowthRatio)) margin = [ int( max( 3, self.extentGrowthRatio * (labelsEffectiveExtent[1] - labelsEffectiveExtent[0]))), int( max( 3, self.extentGrowthRatio * (labelsEffectiveExtent[3] - labelsEffectiveExtent[2]))), int( max( 3, self.extentGrowthRatio * (labelsEffectiveExtent[5] - labelsEffectiveExtent[4]))) ] labelsExpandedExtent = [ max(masterImageExtent[0], labelsEffectiveExtent[0] - margin[0]), min(masterImageExtent[1], labelsEffectiveExtent[1] + margin[0]), max(masterImageExtent[2], labelsEffectiveExtent[2] - margin[1]), min(masterImageExtent[3], labelsEffectiveExtent[3] + margin[1]), max(masterImageExtent[4], labelsEffectiveExtent[4] - margin[2]), min(masterImageExtent[5], labelsEffectiveExtent[5] + margin[2]) ] print("masterImageExtent = " + repr(masterImageExtent)) print("labelsEffectiveExtent = " + repr(labelsEffectiveExtent)) print("labelsExpandedExtent = " + repr(labelsExpandedExtent)) self.mergedLabelmapGeometryImage.SetExtent(labelsExpandedExtent) # Create and setup preview node previewNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSegmentationNode") previewNode.CreateDefaultDisplayNodes() previewNode.GetDisplayNode().SetVisibility2DOutline(False) if segmentationNode.GetParentTransformNode(): previewNode.SetAndObserveTransformNodeID( segmentationNode.GetParentTransformNode().GetID()) self.scriptedEffect.parameterSetNode().SetNodeReferenceID( ResultPreviewNodeReferenceRole, previewNode.GetID()) self.scriptedEffect.setCommonParameter( "SegmentationResultPreviewOwnerEffect", self.scriptedEffect.name) self.setPreviewOpacity(0.6) # Disable smoothing for closed surface generation to make it fast previewNode.GetSegmentation().SetConversionParameter( slicer.vtkBinaryLabelmapToClosedSurfaceConversionRule. GetSmoothingFactorParameterName(), "-0.5") inputContainsClosedSurfaceRepresentation = segmentationNode.GetSegmentation( ).ContainsRepresentation( slicer.vtkSegmentationConverter. GetSegmentationClosedSurfaceRepresentationName()) self.setPreviewShow3D(inputContainsClosedSurfaceRepresentation) if self.clippedMasterImageDataRequired: self.clippedMasterImageData = slicer.vtkOrientedImageData() masterImageClipper = vtk.vtkImageConstantPad() masterImageClipper.SetInputData(masterImageData) masterImageClipper.SetOutputWholeExtent( self.mergedLabelmapGeometryImage.GetExtent()) masterImageClipper.Update() self.clippedMasterImageData.ShallowCopy( masterImageClipper.GetOutput()) self.clippedMasterImageData.CopyDirections( self.mergedLabelmapGeometryImage) self.clippedMaskImageData = None if self.clippedMaskImageDataRequired: self.clippedMaskImageData = slicer.vtkOrientedImageData() intensityBasedMasking = self.scriptedEffect.parameterSetNode( ).GetMasterVolumeIntensityMask() success = segmentationNode.GenerateEditMask( self.clippedMaskImageData, self.scriptedEffect.parameterSetNode().GetMaskMode(), self.clippedMasterImageData, # reference geometry "", # edited segment ID self.scriptedEffect.parameterSetNode().GetMaskSegmentID() if self.scriptedEffect.parameterSetNode().GetMaskSegmentID() else "", self.clippedMasterImageData if intensityBasedMasking else None, self.scriptedEffect.parameterSetNode( ).GetMasterVolumeIntensityMaskRange() if intensityBasedMasking else None) if not success: logging.error("Failed to create edit mask") self.clippedMaskImageData = None previewNode.SetName(segmentationNode.GetName() + " preview") mergedImage = slicer.vtkOrientedImageData() segmentationNode.GenerateMergedLabelmapForAllSegments( mergedImage, vtkSegmentationCore.vtkSegmentation. EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.mergedLabelmapGeometryImage, self.selectedSegmentIds) outputLabelmap = slicer.vtkOrientedImageData() self.computePreviewLabelmap(mergedImage, outputLabelmap) # Write output segmentation results in segments for index in range(self.selectedSegmentIds.GetNumberOfValues()): segmentID = self.selectedSegmentIds.GetValue(index) segment = segmentationNode.GetSegmentation().GetSegment(segmentID) # Disable save with scene? # Get only the label of the current segment from the output image thresh = vtk.vtkImageThreshold() thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.SetInValue(1) thresh.SetOutValue(0) labelValue = index + 1 # n-th segment label value = n + 1 (background label value is 0) thresh.ThresholdBetween(labelValue, labelValue) thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) thresh.SetInputData(outputLabelmap) thresh.Update() # Write label to segment newSegmentLabelmap = slicer.vtkOrientedImageData() newSegmentLabelmap.ShallowCopy(thresh.GetOutput()) newSegmentLabelmap.CopyDirections(mergedImage) newSegment = previewNode.GetSegmentation().GetSegment(segmentID) if not newSegment: newSegment = vtkSegmentationCore.vtkSegment() newSegment.SetName(segment.GetName()) color = segmentationNode.GetSegmentation().GetSegment( segmentID).GetColor() newSegment.SetColor(color) previewNode.GetSegmentation().AddSegment(newSegment, segmentID) self.scriptedEffect.modifySegmentByLabelmap( previewNode, segmentID, newSegmentLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet) # Automatically hide result segments that are background (all eight corners are non-zero) previewNode.GetDisplayNode().SetSegmentVisibility3D( segmentID, not self.isBackgroundLabelmap(newSegmentLabelmap)) # If the preview was reset, we need to restore the visibility options self.setPreviewOpacity(previewOpacity) self.setPreviewShow3D(previewShow3D) self.updateGUIFromMRML()
gs.SetInputConnection(ic.GetOutputPort()) gs.SetDimensionality(2) gs.SetRadiusFactors(1, 1, 0) # gradient the image imgGradient = vtk.vtkImageGradient() imgGradient.SetInputConnection(gs.GetOutputPort()) imgGradient.SetDimensionality(2) imgMagnitude = vtk.vtkImageMagnitude() imgMagnitude.SetInputConnection(imgGradient.GetOutputPort()) imgMagnitude.Update() # non maximum suppression nonMax = vtk.vtkImageNonMaximumSuppression() nonMax.SetMagnitudeInputData(imgMagnitude.GetOutput()) nonMax.SetVectorInputData(imgGradient.GetOutput()) nonMax.SetDimensionality(2) pad = vtk.vtkImageConstantPad() pad.SetInputConnection(imgGradient.GetOutputPort()) pad.SetOutputNumberOfScalarComponents(3) pad.SetConstant(0) pad.Update() i2sp1 = vtk.vtkImageToStructuredPoints() i2sp1.SetInputConnection(nonMax.GetOutputPort()) i2sp1.SetVectorInputData(pad.GetOutput()) # link edgles imgLink = vtk.vtkLinkEdgels() imgLink.SetInputConnection(i2sp1.GetOutputPort()) imgLink.SetGradientThreshold(2) # threshold links thresholdEdgels = vtk.vtkThreshold() thresholdEdgels.SetInputConnection(imgLink.GetOutputPort()) thresholdEdgels.SetThresholdFunction(vtk.vtkThreshold.THRESHOLD_UPPER)
## appender.AddInputConnection(alphacomponent.GetProducerPort()) ## imagewalpha = appender.GetOutput() ## imagewalpha.Update() ## # check that all the data is the same ## for i in xrange(216): ## v1 = imagewalpha.GetPointData().GetScalars().GetComponent(i,0) ## v2 = image.GetPointData().GetScalars().GetComponent(i,0) ## v3 = imagewalpha.GetPointData().GetScalars().GetComponent(i,1) ## if v1 != v2: ## print "NOT EQUAL" ## if v3 != 255: ## print "NOT OPAQUE" # try padding the image padder = vtk.vtkImageConstantPad() padder.SetInput(image) padder.SetOutputWholeExtent(0, 6, 0, 6, 0, 6) # pad one voxel layer to 3 of the sides? padder.SetConstant(255) # arbitrary imagepadded = padder.GetOutput() imagepadded.Update() # FixedPointVolumeRayCastMapper can handle more than one component but # also elimnates the need for a second component in this case. mapper = vtk.vtkFixedPointVolumeRayCastMapper() # must alter sample distance to be a fraction of a pixel for this # small volume, otherwise rendering is garbled when not viewing volume # head on. mapper.SetSampleDistance(.05) mapper.SetInteractiveSampleDistance(.2)
def setupPipeline(): #read file global reader reader = vtk.vtkOBJReader() reader.SetFileName(filename) #map 3d model global mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(reader.GetOutputPort()) #set actor global actor actor = vtk.vtkActor() actor.SetMapper(mapper) # Create a rendering window and renderer global ren ren = vtk.vtkRenderer() ren.SetBackground(0, 0, 0) ren.AddActor(actor) global intermediateWindow intermediateWindow = vtk.vtkRenderWindow() intermediateWindow.AddRenderer(ren) #render image global renImage renImage = vtk.vtkRenderLargeImage() renImage.SetInput(ren) renImage.SetMagnification(magnificationFactor) #Canny edge detector inspired by #https://vtk.org/Wiki/VTK/Examples/Cxx/Images/CannyEdgeDetector #to grayscale global lumImage lumImage = vtk.vtkImageLuminance() lumImage.SetInputConnection(renImage.GetOutputPort()) #to float global floatImage floatImage = vtk.vtkImageCast() floatImage.SetOutputScalarTypeToFloat() floatImage.SetInputConnection(lumImage.GetOutputPort()) #gaussian convolution global smoothImage smoothImage = vtk.vtkImageGaussianSmooth() smoothImage.SetInputConnection(floatImage.GetOutputPort()) smoothImage.SetDimensionality(2) smoothImage.SetRadiusFactors(1, 1, 0) #gradient global gradientImage gradientImage = vtk.vtkImageGradient() gradientImage.SetInputConnection(smoothImage.GetOutputPort()) gradientImage.SetDimensionality(2) #gradient magnitude global magnitudeImage magnitudeImage = vtk.vtkImageMagnitude() magnitudeImage.SetInputConnection(gradientImage.GetOutputPort()) #non max suppression global nonmaxSuppr nonmaxSuppr = vtk.vtkImageNonMaximumSuppression() nonmaxSuppr.SetDimensionality(2) #padding global padImage padImage = vtk.vtkImageConstantPad() padImage.SetInputConnection(gradientImage.GetOutputPort()) padImage.SetOutputNumberOfScalarComponents(3) padImage.SetConstant(0) #to structured points global i2sp1 i2sp1 = vtk.vtkImageToStructuredPoints() i2sp1.SetInputConnection(nonmaxSuppr.GetOutputPort()) #link edges global linkImage linkImage = vtk.vtkLinkEdgels() linkImage.SetInputConnection(i2sp1.GetOutputPort()) linkImage.SetGradientThreshold(2) #thresholds links global thresholdEdgels thresholdEdgels = vtk.vtkThreshold() thresholdEdgels.SetInputConnection(linkImage.GetOutputPort()) thresholdEdgels.ThresholdByUpper(10) thresholdEdgels.AllScalarsOff() #filter global gf gf = vtk.vtkGeometryFilter() gf.SetInputConnection(thresholdEdgels.GetOutputPort()) #to structured points global i2sp i2sp = vtk.vtkImageToStructuredPoints() i2sp.SetInputConnection(magnitudeImage.GetOutputPort()) #subpixel global spe spe = vtk.vtkSubPixelPositionEdgels() spe.SetInputConnection(gf.GetOutputPort()) #stripper global strip strip = vtk.vtkStripper() strip.SetInputConnection(spe.GetOutputPort()) global dsm dsm = vtk.vtkPolyDataMapper() dsm.SetInputConnection(strip.GetOutputPort()) dsm.ScalarVisibilityOff() global planeActor planeActor = vtk.vtkActor() planeActor.SetMapper(dsm) planeActor.GetProperty().SetAmbient(1.0) planeActor.GetProperty().SetDiffuse(0.0) global edgeRender edgeRender = vtk.vtkRenderer() edgeRender.AddActor(planeActor) global renderWindow renderWindow = vtk.vtkRenderWindow() renderWindow.AddRenderer(edgeRender) global finalImage finalImage = vtk.vtkRenderLargeImage() finalImage.SetMagnification(magnificationFactor) finalImage.SetInput(edgeRender) global revImage revImage = vtk.vtkImageThreshold() revImage.SetInputConnection(finalImage.GetOutputPort()) revImage.ThresholdByUpper(127) revImage.ReplaceInOn() revImage.ReplaceOutOn() revImage.SetOutValue(255) revImage.SetInValue(0) #write image global imgWriter imgWriter = vtk.vtkPNGWriter() imgWriter.SetInputConnection(revImage.GetOutputPort()) imgWriter.SetFileName("test.png")
def computeVesselnessVolume(self, currentVolumeNode, currentOutputVolumeNode, previewRegionCenterRAS=None, previewRegionSizeVoxel=-1, minimumDiameterMm=0, maximumDiameterMm=25, alpha=0.3, beta=0.3, contrastMeasure=150): logging.debug( "Vesselness filtering started: diameter min={0}, max={1}, alpha={2}, beta={3}, contrastMeasure={4}" .format(minimumDiameterMm, maximumDiameterMm, alpha, beta, contrastMeasure)) if not currentVolumeNode: raise ValueError("Output volume node is invalid") # this image will later hold the inputImage inImage = vtk.vtkImageData() # if we are in previewMode, we have to cut the ROI first for speed if previewRegionSizeVoxel > 0: # we extract the ROI of currentVolumeNode and save it to currentOutputVolumeNode # we work in RAS space imageclipper = vtk.vtkImageConstantPad() imageclipper.SetInputData(currentVolumeNode.GetImageData()) previewRegionCenterIJK = self.getIJKFromRAS( currentVolumeNode, previewRegionCenterRAS) previewRegionRadiusVoxel = int( round(previewRegionSizeVoxel / 2 + 0.5)) imageclipper.SetOutputWholeExtent( previewRegionCenterIJK[0] - previewRegionRadiusVoxel, previewRegionCenterIJK[0] + previewRegionRadiusVoxel, previewRegionCenterIJK[1] - previewRegionRadiusVoxel, previewRegionCenterIJK[1] + previewRegionRadiusVoxel, previewRegionCenterIJK[2] - previewRegionRadiusVoxel, previewRegionCenterIJK[2] + previewRegionRadiusVoxel) imageclipper.Update() currentOutputVolumeNode.SetAndObserveImageData( imageclipper.GetOutput()) currentOutputVolumeNode.CopyOrientation(currentVolumeNode) currentOutputVolumeNode.ShiftImageDataExtentToZeroStart() inImage.DeepCopy(currentOutputVolumeNode.GetImageData()) else: # there was no ROI extraction, so just clone the inputImage inImage.DeepCopy(currentVolumeNode.GetImageData()) currentOutputVolumeNode.CopyOrientation(currentVolumeNode) # temporarily set spacing to allow vesselness computation performed in physical space inImage.SetSpacing(currentVolumeNode.GetSpacing()) # we now compute the vesselness in RAS space, inImage has spacing and origin attached, the diameters are converted to mm # we use RAS space to support anisotropic datasets import vtkvmtkSegmentationPython as vtkvmtkSegmentation cast = vtk.vtkImageCast() cast.SetInputData(inImage) cast.SetOutputScalarTypeToFloat() cast.Update() inImage = cast.GetOutput() discretizationSteps = 5 v = vtkvmtkSegmentation.vtkvmtkVesselnessMeasureImageFilter() v.SetInputData(inImage) v.SetSigmaMin(minimumDiameterMm) v.SetSigmaMax(maximumDiameterMm) v.SetNumberOfSigmaSteps(discretizationSteps) v.SetAlpha(alpha) v.SetBeta(beta) v.SetGamma(contrastMeasure) v.Update() outImage = vtk.vtkImageData() outImage.DeepCopy(v.GetOutput()) outImage.GetPointData().GetScalars().Modified() # restore Slicer-compliant image spacing outImage.SetSpacing(1, 1, 1) # we set the outImage which has spacing 1,1,1. The ijkToRas matrix of the node will take care of that currentOutputVolumeNode.SetAndObserveImageData(outImage) # save which volume node vesselness filterint result was saved to currentVolumeNode.SetAndObserveNodeReferenceID( "Vesselness", currentOutputVolumeNode.GetID()) logging.debug("Vesselness filtering completed")
gs.SetInputConnection(ic.GetOutputPort()) gs.SetDimensionality(2) gs.SetRadiusFactors(1,1,0) # gradient the image imgGradient = vtk.vtkImageGradient() imgGradient.SetInputConnection(gs.GetOutputPort()) imgGradient.SetDimensionality(2) imgMagnitude = vtk.vtkImageMagnitude() imgMagnitude.SetInputConnection(imgGradient.GetOutputPort()) imgMagnitude.Update() # non maximum suppression nonMax = vtk.vtkImageNonMaximumSuppression() nonMax.SetMagnitudeInputData(imgMagnitude.GetOutput()) nonMax.SetVectorInputData(imgGradient.GetOutput()) nonMax.SetDimensionality(2) pad = vtk.vtkImageConstantPad() pad.SetInputConnection(imgGradient.GetOutputPort()) pad.SetOutputNumberOfScalarComponents(3) pad.SetConstant(0) pad.Update() i2sp1 = vtk.vtkImageToStructuredPoints() i2sp1.SetInputConnection(nonMax.GetOutputPort()) i2sp1.SetVectorInputData(pad.GetOutput()) # link edgles imgLink = vtk.vtkLinkEdgels() imgLink.SetInputConnection(i2sp1.GetOutputPort()) imgLink.SetGradientThreshold(2) # threshold links thresholdEdgels = vtk.vtkThreshold() thresholdEdgels.SetInputConnection(imgLink.GetOutputPort()) thresholdEdgels.ThresholdByUpper(10)
def preview(self): # Get master volume image data import vtkSegmentationCorePython as vtkSegmentationCore masterImageData = self.scriptedEffect.masterVolumeImageData() # Get segmentation segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode() previewNode = self.getPreviewNode() if not previewNode or not self.mergedLabelmapGeometryImage \ or (self.clippedMasterImageDataRequired and not self.clippedMasterImageData): self.reset() # Compute merged labelmap extent (effective extent slightly expanded) self.selectedSegmentIds = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(self.selectedSegmentIds) if self.selectedSegmentIds.GetNumberOfValues() < self.minimumNumberOfSegments: logging.error("Auto-complete operation skipped: at least {0} visible segments are required".format(self.minimumNumberOfSegments)) return if not self.mergedLabelmapGeometryImage: self.mergedLabelmapGeometryImage = vtkSegmentationCore.vtkOrientedImageData() commonGeometryString = segmentationNode.GetSegmentation().DetermineCommonLabelmapGeometry( vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.selectedSegmentIds) if not commonGeometryString: logging.info("Auto-complete operation skipped: all visible segments are empty") return vtkSegmentationCore.vtkSegmentationConverter.DeserializeImageGeometry(commonGeometryString, self.mergedLabelmapGeometryImage) masterImageExtent = masterImageData.GetExtent() labelsEffectiveExtent = self.mergedLabelmapGeometryImage.GetExtent() margin = [17, 17, 17] labelsExpandedExtent = [ max(masterImageExtent[0], labelsEffectiveExtent[0]-margin[0]), min(masterImageExtent[1], labelsEffectiveExtent[1]+margin[0]), max(masterImageExtent[2], labelsEffectiveExtent[2]-margin[1]), min(masterImageExtent[3], labelsEffectiveExtent[3]+margin[1]), max(masterImageExtent[4], labelsEffectiveExtent[4]-margin[2]), min(masterImageExtent[5], labelsEffectiveExtent[5]+margin[2]) ] self.mergedLabelmapGeometryImage.SetExtent(labelsExpandedExtent) previewNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLSegmentationNode') previewNode.UnRegister(None) previewNode = slicer.mrmlScene.AddNode(previewNode) previewNode.CreateDefaultDisplayNodes() previewNode.GetDisplayNode().SetVisibility2DOutline(False) if segmentationNode.GetParentTransformNode(): previewNode.SetAndObserveTransformNodeID(segmentationNode.GetParentTransformNode().GetID()) self.scriptedEffect.parameterSetNode().SetNodeReferenceID(ResultPreviewNodeReferenceRole, previewNode.GetID()) self.scriptedEffect.setCommonParameter("SegmentationResultPreviewOwnerEffect", self.scriptedEffect.name) self.setPreviewOpacity(0.6) if self.clippedMasterImageDataRequired: self.clippedMasterImageData = vtkSegmentationCore.vtkOrientedImageData() masterImageClipper = vtk.vtkImageConstantPad() masterImageClipper.SetInputData(masterImageData) masterImageClipper.SetOutputWholeExtent(self.mergedLabelmapGeometryImage.GetExtent()) masterImageClipper.Update() self.clippedMasterImageData.ShallowCopy(masterImageClipper.GetOutput()) self.clippedMasterImageData.CopyDirections(self.mergedLabelmapGeometryImage) previewNode.SetName(segmentationNode.GetName()+" preview") mergedImage = vtkSegmentationCore.vtkOrientedImageData() segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage, vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.mergedLabelmapGeometryImage, self.selectedSegmentIds) outputLabelmap = vtkSegmentationCore.vtkOrientedImageData() self.computePreviewLabelmap(mergedImage, outputLabelmap) # Write output segmentation results in segments for index in xrange(self.selectedSegmentIds.GetNumberOfValues()): segmentID = self.selectedSegmentIds.GetValue(index) segment = segmentationNode.GetSegmentation().GetSegment(segmentID) # Disable save with scene? # Get only the label of the current segment from the output image thresh = vtk.vtkImageThreshold() thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.SetInValue(1) thresh.SetOutValue(0) labelValue = index + 1 # n-th segment label value = n + 1 (background label value is 0) thresh.ThresholdBetween(labelValue, labelValue); thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) thresh.SetInputData(outputLabelmap) thresh.Update() # Write label to segment newSegmentLabelmap = vtkSegmentationCore.vtkOrientedImageData() newSegmentLabelmap.ShallowCopy(thresh.GetOutput()) newSegmentLabelmap.CopyDirections(mergedImage) newSegment = previewNode.GetSegmentation().GetSegment(segmentID) if not newSegment: newSegment = vtkSegmentationCore.vtkSegment() newSegment.SetName(segment.GetName()) color = segmentationNode.GetSegmentation().GetSegment(segmentID).GetColor() newSegment.SetColor(color) previewNode.GetSegmentation().AddSegment(newSegment, segmentID) slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(newSegmentLabelmap, previewNode, segmentID) self.updateGUIFromMRML()
def onApply(self): import SegmentEditorMaskVolumeLib inputVolume = self.getInputVolume() segmentID = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() volumesLogic = slicer.modules.volumes.logic() scene = inputVolume.GetScene() padExtent = [ -self.padEdit.value, self.padEdit.value, -self.padEdit.value, self.padEdit.value, -self.padEdit.value, self.padEdit.value ] # Create a new folder in subject hierarchy where all the generated volumes will be placed into shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode( slicer.mrmlScene) inputVolumeParentItem = shNode.GetItemParent( shNode.GetItemByDataNode(inputVolume)) outputShFolder = shNode.CreateFolderItem( inputVolumeParentItem, inputVolume.GetName() + " split") # Iterate over segments slicer.app.setOverrideCursor(qt.Qt.WaitCursor) for segmentIndex in range( segmentationNode.GetSegmentation().GetNumberOfSegments()): segmentID = segmentationNode.GetSegmentation().GetNthSegmentID( segmentIndex) segmentIDs = vtk.vtkStringArray() segmentIDs.InsertNextValue(segmentID) # Create volume for output outputVolumeName = inputVolume.GetName( ) + ' ' + segmentationNode.GetSegmentation().GetSegment( segmentID).GetName() outputVolume = volumesLogic.CloneVolumeGeneric( scene, inputVolume, outputVolumeName, False) # Crop segment maskExtent = [0] * 6 SegmentEditorMaskVolumeLib.SegmentEditorEffect.maskVolumeWithSegment( segmentationNode, segmentID, "FILL_OUTSIDE", [0], inputVolume, outputVolume, maskExtent) # Calculate padded extent of segment extent = [0] * 6 for i in range(len(extent)): extent[i] = maskExtent[i] + padExtent[i] # Calculate the new origin ijkToRas = vtk.vtkMatrix4x4() outputVolume.GetIJKToRASMatrix(ijkToRas) origin_IJK = [extent[0], extent[2], extent[4], 1] origin_RAS = ijkToRas.MultiplyPoint(origin_IJK) # Pad and crop padFilter = vtk.vtkImageConstantPad() padFilter.SetInputData(outputVolume.GetImageData()) padFilter.SetConstant(self.fillValueEdit.value) padFilter.SetOutputWholeExtent(extent) padFilter.Update() paddedImg = padFilter.GetOutput() # Normalize output image paddedImg.SetOrigin(0, 0, 0) paddedImg.SetSpacing(1.0, 1.0, 1.0) paddedImg.SetExtent(0, extent[1] - extent[0], 0, extent[3] - extent[2], 0, extent[5] - extent[4]) outputVolume.SetAndObserveImageData(paddedImg) outputVolume.SetOrigin(origin_RAS[0], origin_RAS[1], origin_RAS[2]) # Place output image in subject hierarchy folder shNode.SetItemParent(shNode.GetItemByDataNode(outputVolume), outputShFolder) qt.QApplication.restoreOverrideCursor()
def preview(self): # Get master volume image data import vtkSegmentationCorePython as vtkSegmentationCore masterImageData = self.scriptedEffect.masterVolumeImageData() # Get segmentation segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() previewNode = self.getPreviewNode() if not previewNode or not self.mergedLabelmapGeometryImage \ or (self.clippedMasterImageDataRequired and not self.clippedMasterImageData): self.reset() # Compute merged labelmap extent (effective extent slightly expanded) self.selectedSegmentIds = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs( self.selectedSegmentIds) if self.selectedSegmentIds.GetNumberOfValues( ) < self.minimumNumberOfSegments: logging.error( "Auto-complete operation skipped: at least {0} visible segments are required" .format(self.minimumNumberOfSegments)) return if not self.mergedLabelmapGeometryImage: self.mergedLabelmapGeometryImage = vtkSegmentationCore.vtkOrientedImageData( ) commonGeometryString = segmentationNode.GetSegmentation( ).DetermineCommonLabelmapGeometry( vtkSegmentationCore.vtkSegmentation. EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.selectedSegmentIds) if not commonGeometryString: logging.info( "Auto-complete operation skipped: all visible segments are empty" ) return vtkSegmentationCore.vtkSegmentationConverter.DeserializeImageGeometry( commonGeometryString, self.mergedLabelmapGeometryImage) masterImageExtent = masterImageData.GetExtent() labelsEffectiveExtent = self.mergedLabelmapGeometryImage.GetExtent( ) margin = [17, 17, 17] labelsExpandedExtent = [ max(masterImageExtent[0], labelsEffectiveExtent[0] - margin[0]), min(masterImageExtent[1], labelsEffectiveExtent[1] + margin[0]), max(masterImageExtent[2], labelsEffectiveExtent[2] - margin[1]), min(masterImageExtent[3], labelsEffectiveExtent[3] + margin[1]), max(masterImageExtent[4], labelsEffectiveExtent[4] - margin[2]), min(masterImageExtent[5], labelsEffectiveExtent[5] + margin[2]) ] self.mergedLabelmapGeometryImage.SetExtent(labelsExpandedExtent) previewNode = slicer.mrmlScene.CreateNodeByClass( 'vtkMRMLSegmentationNode') previewNode.UnRegister(None) previewNode = slicer.mrmlScene.AddNode(previewNode) previewNode.CreateDefaultDisplayNodes() previewNode.GetDisplayNode().SetVisibility2DOutline(False) if segmentationNode.GetParentTransformNode(): previewNode.SetAndObserveTransformNodeID( segmentationNode.GetParentTransformNode().GetID()) self.scriptedEffect.parameterSetNode().SetNodeReferenceID( ResultPreviewNodeReferenceRole, previewNode.GetID()) self.scriptedEffect.setCommonParameter( "SegmentationResultPreviewOwnerEffect", self.scriptedEffect.name) self.setPreviewOpacity(0.6) if self.clippedMasterImageDataRequired: self.clippedMasterImageData = vtkSegmentationCore.vtkOrientedImageData( ) masterImageClipper = vtk.vtkImageConstantPad() masterImageClipper.SetInputData(masterImageData) masterImageClipper.SetOutputWholeExtent( self.mergedLabelmapGeometryImage.GetExtent()) masterImageClipper.Update() self.clippedMasterImageData.ShallowCopy( masterImageClipper.GetOutput()) self.clippedMasterImageData.CopyDirections( self.mergedLabelmapGeometryImage) previewNode.SetName(segmentationNode.GetName() + " preview") mergedImage = vtkSegmentationCore.vtkOrientedImageData() segmentationNode.GenerateMergedLabelmapForAllSegments( mergedImage, vtkSegmentationCore.vtkSegmentation. EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.mergedLabelmapGeometryImage, self.selectedSegmentIds) outputLabelmap = vtkSegmentationCore.vtkOrientedImageData() self.computePreviewLabelmap(mergedImage, outputLabelmap) # Write output segmentation results in segments for index in xrange(self.selectedSegmentIds.GetNumberOfValues()): segmentID = self.selectedSegmentIds.GetValue(index) segment = segmentationNode.GetSegmentation().GetSegment(segmentID) # Disable save with scene? # Get only the label of the current segment from the output image thresh = vtk.vtkImageThreshold() thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.SetInValue(1) thresh.SetOutValue(0) labelValue = index + 1 # n-th segment label value = n + 1 (background label value is 0) thresh.ThresholdBetween(labelValue, labelValue) thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) thresh.SetInputData(outputLabelmap) thresh.Update() # Write label to segment newSegmentLabelmap = vtkSegmentationCore.vtkOrientedImageData() newSegmentLabelmap.ShallowCopy(thresh.GetOutput()) newSegmentLabelmap.CopyDirections(mergedImage) newSegment = previewNode.GetSegmentation().GetSegment(segmentID) if not newSegment: newSegment = vtkSegmentationCore.vtkSegment() newSegment.SetName(segment.GetName()) color = segmentationNode.GetSegmentation().GetSegment( segmentID).GetColor() newSegment.SetColor(color) previewNode.GetSegmentation().AddSegment(newSegment, segmentID) slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment( newSegmentLabelmap, previewNode, segmentID) self.updateGUIFromMRML()
def preview(self): # Get master volume image data import vtkSegmentationCorePython as vtkSegmentationCore masterImageData = self.scriptedEffect.masterVolumeImageData() # Get segmentation segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode() previewNode = self.getPreviewNode() if (not previewNode or not self.mergedLabelmapGeometryImage or (self.clippedMasterImageDataRequired and not self.clippedMasterImageData)): self.reset() # Compute merged labelmap extent (effective extent slightly expanded) self.selectedSegmentIds = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(self.selectedSegmentIds) if self.selectedSegmentIds.GetNumberOfValues() < self.minimumNumberOfSegments: logging.error("Auto-complete operation skipped: at least {0} visible segments are required".format(self.minimumNumberOfSegments)) return if not self.mergedLabelmapGeometryImage: self.mergedLabelmapGeometryImage = vtkSegmentationCore.vtkOrientedImageData() commonGeometryString = segmentationNode.GetSegmentation().DetermineCommonLabelmapGeometry( vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.selectedSegmentIds) if not commonGeometryString: logging.info("Auto-complete operation skipped: all visible segments are empty") return vtkSegmentationCore.vtkSegmentationConverter.DeserializeImageGeometry(commonGeometryString, self.mergedLabelmapGeometryImage) masterImageExtent = masterImageData.GetExtent() labelsEffectiveExtent = self.mergedLabelmapGeometryImage.GetExtent() # Margin size is relative to combined seed region size, but minimum of 3 voxels print("self.extentGrowthRatio = {0}".format(self.extentGrowthRatio)) margin = [ int(max(3, self.extentGrowthRatio * (labelsEffectiveExtent[1]-labelsEffectiveExtent[0]))), int(max(3, self.extentGrowthRatio * (labelsEffectiveExtent[3]-labelsEffectiveExtent[2]))), int(max(3, self.extentGrowthRatio * (labelsEffectiveExtent[5]-labelsEffectiveExtent[4]))) ] labelsExpandedExtent = [ max(masterImageExtent[0], labelsEffectiveExtent[0]-margin[0]), min(masterImageExtent[1], labelsEffectiveExtent[1]+margin[0]), max(masterImageExtent[2], labelsEffectiveExtent[2]-margin[1]), min(masterImageExtent[3], labelsEffectiveExtent[3]+margin[1]), max(masterImageExtent[4], labelsEffectiveExtent[4]-margin[2]), min(masterImageExtent[5], labelsEffectiveExtent[5]+margin[2]) ] print("masterImageExtent = "+repr(masterImageExtent)) print("labelsEffectiveExtent = "+repr(labelsEffectiveExtent)) print("labelsExpandedExtent = "+repr(labelsExpandedExtent)) self.mergedLabelmapGeometryImage.SetExtent(labelsExpandedExtent) # Create and setup preview node previewNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode") previewNode.CreateDefaultDisplayNodes() previewNode.GetDisplayNode().SetVisibility2DOutline(False) if segmentationNode.GetParentTransformNode(): previewNode.SetAndObserveTransformNodeID(segmentationNode.GetParentTransformNode().GetID()) self.scriptedEffect.parameterSetNode().SetNodeReferenceID(ResultPreviewNodeReferenceRole, previewNode.GetID()) self.scriptedEffect.setCommonParameter("SegmentationResultPreviewOwnerEffect", self.scriptedEffect.name) self.setPreviewOpacity(0.6) # Disable smoothing for closed surface generation to make it fast previewNode.GetSegmentation().SetConversionParameter( slicer.vtkBinaryLabelmapToClosedSurfaceConversionRule.GetSmoothingFactorParameterName(), "-0.5"); inputContainsClosedSurfaceRepresentation = segmentationNode.GetSegmentation().ContainsRepresentation( slicer.vtkSegmentationConverter.GetSegmentationClosedSurfaceRepresentationName()) self.setPreviewShow3D(inputContainsClosedSurfaceRepresentation) if self.clippedMasterImageDataRequired: self.clippedMasterImageData = vtkSegmentationCore.vtkOrientedImageData() masterImageClipper = vtk.vtkImageConstantPad() masterImageClipper.SetInputData(masterImageData) masterImageClipper.SetOutputWholeExtent(self.mergedLabelmapGeometryImage.GetExtent()) masterImageClipper.Update() self.clippedMasterImageData.ShallowCopy(masterImageClipper.GetOutput()) self.clippedMasterImageData.CopyDirections(self.mergedLabelmapGeometryImage) self.clippedMaskImageData = None if self.clippedMaskImageDataRequired: self.clippedMaskImageData = vtkSegmentationCore.vtkOrientedImageData() intensityBasedMasking = self.scriptedEffect.parameterSetNode().GetMasterVolumeIntensityMask() success = segmentationNode.GenerateEditMask(self.clippedMaskImageData, self.scriptedEffect.parameterSetNode().GetMaskMode(), self.clippedMasterImageData, # reference geometry "", # edited segment ID self.scriptedEffect.parameterSetNode().GetMaskSegmentID() if self.scriptedEffect.parameterSetNode().GetMaskSegmentID() else "", self.clippedMasterImageData if intensityBasedMasking else None, self.scriptedEffect.parameterSetNode().GetMasterVolumeIntensityMaskRange() if intensityBasedMasking else None) if not success: logging.error("Failed to create edit mask") self.clippedMaskImageData = None previewNode.SetName(segmentationNode.GetName()+" preview") mergedImage = vtkSegmentationCore.vtkOrientedImageData() segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage, vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.mergedLabelmapGeometryImage, self.selectedSegmentIds) outputLabelmap = vtkSegmentationCore.vtkOrientedImageData() self.computePreviewLabelmap(mergedImage, outputLabelmap) # Write output segmentation results in segments for index in xrange(self.selectedSegmentIds.GetNumberOfValues()): segmentID = self.selectedSegmentIds.GetValue(index) segment = segmentationNode.GetSegmentation().GetSegment(segmentID) # Disable save with scene? # Get only the label of the current segment from the output image thresh = vtk.vtkImageThreshold() thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.SetInValue(1) thresh.SetOutValue(0) labelValue = index + 1 # n-th segment label value = n + 1 (background label value is 0) thresh.ThresholdBetween(labelValue, labelValue); thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) thresh.SetInputData(outputLabelmap) thresh.Update() # Write label to segment newSegmentLabelmap = vtkSegmentationCore.vtkOrientedImageData() newSegmentLabelmap.ShallowCopy(thresh.GetOutput()) newSegmentLabelmap.CopyDirections(mergedImage) newSegment = previewNode.GetSegmentation().GetSegment(segmentID) if not newSegment: newSegment = vtkSegmentationCore.vtkSegment() newSegment.SetName(segment.GetName()) color = segmentationNode.GetSegmentation().GetSegment(segmentID).GetColor() newSegment.SetColor(color) previewNode.GetSegmentation().AddSegment(newSegment, segmentID) slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(newSegmentLabelmap, previewNode, segmentID) # Automatically hide result segments that are background (all eight corners are non-zero) previewNode.GetDisplayNode().SetSegmentVisibility3D(segmentID, not self.isBackgroundLabelmap(newSegmentLabelmap)) self.updateGUIFromMRML()