def calculateDistance(self): tipPoint = [0.0,0.0,0.0] targetPoint = [0.0, 0.0, 0.0] self.targetFiducial.GetNthFiducialPosition (0, targetPoint) targetPoint = targetPoint + [1.0] if self.targetCreatedTransformed: ssr = vtk.vtkMatrix4x4() self.patientToReference.GetMatrixTransformToWorld(ssr) self.targetPointTransformed = [0.0,0.0,0.0,1.0] ssr.MultiplyPoint(targetPoint, self.targetPointTransformed) self.targetPointTransformed = [self.targetPointTransformed[i] for i in (0,1,2)] tpoint = self.targetPointTransformed else: tpoint = [targetPoint[i] for i in (0,1,2)] m = vtk.vtkMatrix4x4() self.toolTipToTool.GetMatrixTransformToWorld(m) tipPoint[0] = m.GetElement(0, 3) tipPoint[1] = m.GetElement(1, 3) tipPoint[2] = m.GetElement(2, 3) # print(targetPoint) distance = math.sqrt(math.pow(tipPoint[0]-tpoint[0], 2) + math.pow(tipPoint[1]-tpoint[1], 2) + math.pow(tipPoint[2]-tpoint[2], 2)) self.outputDistanceLabel.setText('%.1f' % distance) self.drawLineBetweenPoints(tipPoint, tpoint)
def __init__(self): # Variable Definition self.m = vtk.vtkMatrix4x4() # 4x4 VTK matrix to save the transformation matrix sent through Plus. self.transform=numpy.zeros((3,3), dtype=numpy.float64) # Numpy matrix used as input for the transformation decomposition. self.observedNode = None self.outputObserverTag = -1 self.record = False self.timerActive=False self.recordingTime_mode1=10 # 5 seconds to record initial position self.recordingTime_mode2=10 # 5 seconds to record initial position self.mode=0 self.myTimer=Timer() self.recordedDataBuffer = [] self.processedRotation =[] self.name = '' # To save data self.prename = '' #To save data self.alarmCounter = 0 self.rotationMatrix=list() self.rotationMatrices=list() # Variables to control the repetition number of each movement. self.repIDflexoext=0 self.repIDflexlat=0 self.repIDrotation=0 # Arrays to save measured data. self.timeStamp=numpy.array([]) # Defines Alarm file path and mode self.sound = qt.QSound('G:/ModulesSlicer/src/AlgiaCervical/Resources/Alarm/alarm.wav') self.sound.setLoops(1) # Labels for Data Visualization self.outputROMLabel = None self.outputMaxVariabilityLabel = None self.outputMinVariabilityLabel = None import Viewpoint # Viewpoint Module must have been added to Slicer self.viewpointLogic = Viewpoint.ViewpointLogic() # Transform matrix of viewpoint in order to center head model in 3D view self.headCameraToHead = slicer.util.getNode('headCameraToHead') if not self.headCameraToHead: self.headCameraToHead=slicer.vtkMRMLLinearTransformNode() self.headCameraToHead.SetName("headCameraToHead") matrixHeadCamera = vtk.vtkMatrix4x4() matrixHeadCamera.SetElement( 0, 0, 1.0 ) # Row 1 matrixHeadCamera.SetElement( 0, 1, 0.05 ) matrixHeadCamera.SetElement( 0, 2, 0.01 ) matrixHeadCamera.SetElement( 0, 3, 9.42 ) matrixHeadCamera.SetElement( 1, 0, 0.0 ) # Row 2 matrixHeadCamera.SetElement( 1, 1, 0.28 ) matrixHeadCamera.SetElement( 1, 2, -0.96 ) matrixHeadCamera.SetElement( 1, 3, -252.69 ) matrixHeadCamera.SetElement( 2, 0, -0.05 ) # Row 3 matrixHeadCamera.SetElement( 2, 1, 0.96 ) matrixHeadCamera.SetElement( 2, 2, 0.28 ) matrixHeadCamera.SetElement( 2, 3, 122.39 ) self.headCameraToHead.SetMatrixTransformToParent(matrixHeadCamera) slicer.mrmlScene.AddNode(self.headCameraToHead)
def calculateAngle(self): baseConePoint = [0.0, 0.0, 0.0] self.targetFiducial.GetNthFiducialPosition (1, baseConePoint) baseConePoint = baseConePoint + [1.0] if self.targetCreatedTransformed: ssr = vtk.vtkMatrix4x4() self.patientToReference.GetMatrixTransformToWorld(ssr) self.baseConePointTransformed = [0.0,0.0,0.0,1.0] ssr.MultiplyPoint(baseConePoint, self.baseConePointTransformed) self.baseConePointTransformed = [self.baseConePointTransformed[i] for i in (0,1,2)] baseConePoint = self.baseConePointTransformed tipPoint = [0.0,0.0,0.0] m = vtk.vtkMatrix4x4() self.toolTipToTool.GetMatrixTransformToWorld(m) tipPoint[0] = m.GetElement(0, 3) tipPoint[1] = m.GetElement(1, 3) tipPoint[2] = m.GetElement(2, 3) tipPoint pos1Pos = np.subtract(baseConePoint, self.targetPointTransformed) # Normaliza los vectores pos1Pos2 = np.subtract(tipPoint, self.targetPointTransformed) # Normaliza los vectores cosine_angle = np.dot(pos1Pos, pos1Pos2) / (np.linalg.norm(pos1Pos) * np.linalg.norm(pos1Pos2)) angle = np.arccos(cosine_angle) return np.degrees(angle)
def WriteVTSXMLVolumeFile(self): if (self.OutputFileName == ''): self.PrintError('Error: no OutputFileName.') self.PrintLog('Writing VTS XML grid file.') if self.ApplyTransform == 0: origin = self.Image.GetOrigin() spacing = self.Image.GetSpacing() matrix = vtk.vtkMatrix4x4() matrix.DeepCopy((1/spacing[0], 0, 0, - origin[0]/spacing[0], 0, 1/spacing[1], 0, - origin[1]/spacing[1], 0, 0, 1/spacing[2], - origin[2]/spacing[2], 0, 0, 0, 1)) #LPI convention with correct origin and spacing else: if self.RasToIjkMatrixCoefficients == None: self.PrintError('Error: no RasToIjkMatrixCoefficients.') matrix = vtk.vtkMatrix4x4() matrix.DeepCopy(self.RasToIjkMatrixCoefficients) trans = vtk.vtkTransform() trans.SetMatrix(matrix) trans_filt = vtk.vtkTransformFilter() trans_filt.SetTransform(trans) trans_filt.SetInputData(self.Image) trans_filt.Update() writer = vtk.vtkXMLStructuredGridWriter() writer.SetInputConnection(trans_filt.GetOutputPort()) writer.SetFileName(self.OutputFileName) writer.Write()
def calculateNeedleVector(self): needle = slicer.util.getNode('NeedleModel') polydataNeedle = needle.GetPolyData() center = polydataNeedle.GetCenter() center = [center[i] for i in (0,1,2)] center = center + [1.0] ssr = vtk.vtkMatrix4x4() transform= slicer.util.getNode('needleModelToNeedleTip') transform.GetMatrixTransformToWorld(ssr) centerTransformed = [0.0,0.0,0.0,1.0] ssr.MultiplyPoint(center, centerTransformed) centerTransformed = [centerTransformed[i] for i in (0,1,2)] m = vtk.vtkMatrix4x4() nttn = slicer.util.getNode('needleModelToNeedleTip') nttn.GetMatrixTransformToWorld(m) tipPoint = [0.0,0.0,0.0] tipPoint[0] = m.GetElement(0, 3) tipPoint[1] = m.GetElement(1, 3) tipPoint[2] = m.GetElement(2, 3) needleVector = np.subtract(centerTransformed,tipPoint) return needleVector
def calculateDistance(self): tipPoint = [0.0,0.0,0.0] targetPoint = [0.0, 0.0, 0.0] m = vtk.vtkMatrix4x4() self.toolTipToTool.GetMatrixTransformToWorld(m) tipPoint[0] = m.GetElement(0, 3) tipPoint[1] = m.GetElement(1, 3) tipPoint[2] = m.GetElement(2, 3) self.targetFiducial.GetNthFiducialPosition (1, targetPoint) # print(targetPoint) # Prueba David needlePoint = [0.0, 0.0, 0.0] v = vtk.vtkMatrix4x4() self.toolToReference.GetMatrixTransformToWorld(v) needlePoint[0] = v.GetElement(0, 3) needlePoint[1] = v.GetElement(1, 3) needlePoint[2] = v.GetElement(2, 3) # print(needlePoint) distance = math.sqrt(math.pow(tipPoint[0]-targetPoint[0], 2) + math.pow(tipPoint[1]-targetPoint[1], 2) + math.pow(tipPoint[2]-targetPoint[2], 2)) self.outputDistanceLabel.setText('%.1f' % distance) self.drawLineBetweenPoints(tipPoint, targetPoint)
def _update_camera_params(self): P = vtk.vtkMatrix4x4() # projection matrix with clipping planes P.Zero() P.SetElement(0, 0, self._fx) P.SetElement(1, 1, self._fy) P.SetElement(0, 2, self._cx) P.SetElement(1, 2, self._cy) P.SetElement(2, 2, -self.near_clipping - self.far_clipping) P.SetElement(2, 3, -self.near_clipping * self.far_clipping) P.SetElement(3, 2, -1.) # first, reset the user transformation matrix cameraTransform = vtk.vtkPerspectiveTransform() self._camera.SetUserTransform(cameraTransform) # current projection matrix for the VTK camera Minv = self._camera.GetProjectionTransformMatrix( self.width / self.height, self.near_clipping, self.far_clipping) Minv.Invert() # desired user transform matrix U: UM = P U = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(P, Minv, U) # and finally update the transform cameraTransform.SetMatrix(U) self._camera.SetUserTransform(cameraTransform) self.render_window.SetSize(self.width, self.height) self.update()
def __init__(self): ''' Constructor ''' self.__OrientationMatrix = vtk.vtkMatrix4x4() self.__OrientationMatrix.Identity() self.__InvertedOrientationMatrix = vtk.vtkMatrix4x4() self.__InvertedOrientationMatrix.Identity()
def convert_transform_to_vtk(transform, scaled=False, mode=[1,1,1,1]): """ Produce an output vtkTransform corresponding to the registration results. Input is a 15-component transform vector.""" if scaled: # transform_scaling (must be same as defined above in class) #transform = numpy.divide(transform, numpy.array([1, 1, 1, .5, .5, .5, 300, 300, 300, 1, 1, 1, 1, 1, 1])) transform = numpy.divide(transform, numpy.array([1, 1, 1, .5, .5, .5, 200, 200, 200, 1, 1, 1, 1, 1, 1])) vtktrans = vtk.vtkTransform() if mode[0]: # translate first so optimizer starts there vtktrans.Translate(transform[0], transform[1], transform[2]) if mode[1]: # degrees vtktrans.RotateX(transform[3]) vtktrans.RotateY(transform[4]) vtktrans.RotateZ(transform[5]) if mode[2]: vtktrans.Scale(transform[6], transform[7], transform[8]) if mode[3]: #// Update affine transformation: Add shearing #vtkMatrix4x4 *skewx= vtkMatrix4x4::New(); skewx->Identity(); #skewx->SetElement(2, 1,tan(_szy*(pi/180.0))); skewx->SetElement(1, 2,tan(_syz*(pi/180.0))); #vtkMatrix4x4 *skewy= vtkMatrix4x4::New(); skewy->Identity(); #skewy->SetElement(2, 0,tan(_szx*(pi/180.0))); skewy->SetElement(0, 2,tan(_sxz*(pi/180.0))); #vtkMatrix4x4 *skewz= vtkMatrix4x4::New(); skewz->Identity(); #skewz->SetElement(1, 0,tan(_sxy*(pi/180.0))); skewz->SetElement(0, 1,tan(_syx*(pi/180.0))); #tr->Concatenate(skewx); tr->Concatenate(skewy); tr->Concatenate(skewz); sxy = transform[9] * numpy.pi/180.0 sxz = transform[10] * numpy.pi/180.0 syx = transform[11] * numpy.pi/180.0 syz = transform[12] * numpy.pi/180.0 szx = transform[13] * numpy.pi/180.0 szy = transform[14] * numpy.pi/180.0 skewx = vtk.vtkMatrix4x4() skewy = vtk.vtkMatrix4x4() skewz = vtk.vtkMatrix4x4() skewx.SetElement(2, 1, numpy.tan(szy)) skewx.SetElement(1, 2, numpy.tan(syz)) skewy.SetElement(2, 0, numpy.tan(szx)) skewy.SetElement(0, 2, numpy.tan(sxz)) skewz.SetElement(1, 0, numpy.tan(sxy)) skewz.SetElement(0, 1, numpy.tan(syx)) vtktrans.Concatenate(skewx) vtktrans.Concatenate(skewy) vtktrans.Concatenate(skewz) return vtktrans
def convert_transform_to_vtk(self, transform=None): """ Produce an output vtkTransform corresponding to the registration results. Optionally can input a 9-component transform vector.""" if transform is None: transform = self.transform vtktrans = vtk.vtkTransform() vtktrans.RotateX(transform[0] * (180 / numpy.pi)) vtktrans.RotateY(transform[1] * (180 / numpy.pi)) vtktrans.RotateZ(transform[2] * (180 / numpy.pi)) vtktrans.Translate(transform[3], transform[4], transform[5]) vtktrans.Scale(transform[6], transform[7], transform[8]) #// Update affine transformation: Add shearing #vtkMatrix4x4 *skewx= vtkMatrix4x4::New(); skewx->Identity(); #skewx->SetElement(2, 1,tan(_szy*(pi/180.0))); skewx->SetElement(1, 2,tan(_syz*(pi/180.0))); #vtkMatrix4x4 *skewy= vtkMatrix4x4::New(); skewy->Identity(); #skewy->SetElement(2, 0,tan(_szx*(pi/180.0))); skewy->SetElement(0, 2,tan(_sxz*(pi/180.0))); #vtkMatrix4x4 *skewz= vtkMatrix4x4::New(); skewz->Identity(); #skewz->SetElement(1, 0,tan(_sxy*(pi/180.0))); skewz->SetElement(0, 1,tan(_syx*(pi/180.0))); #tr->Concatenate(skewx); tr->Concatenate(skewy); tr->Concatenate(skewz); sxy = transform[9] sxz = transform[10] syx = transform[11] syz = transform[12] szx = transform[13] szy = transform[14] skewx = vtk.vtkMatrix4x4() skewy = vtk.vtkMatrix4x4() skewz = vtk.vtkMatrix4x4() skewx.SetElement(2, 1, numpy.tan(szy)) skewx.SetElement(1, 2, numpy.tan(syz)) skewy.SetElement(2, 0, numpy.tan(szx)) skewy.SetElement(0, 2, numpy.tan(sxz)) skewz.SetElement(1, 0, numpy.tan(sxy)) skewz.SetElement(0, 1, numpy.tan(syx)) vtktrans.Concatenate(skewx) vtktrans.Concatenate(skewy) vtktrans.Concatenate(skewz) #del skewx #del skewy #del skewz return vtktrans
def probeVolume(self, volumeNode, rulerNode): # get ruler ednpoints coordinates in RAS p0ras = rulerNode.GetPolyData().GetPoint(0) + (1,) p1ras = rulerNode.GetPolyData().GetPoint(1) + (1,) # RAS --> IJK ras2ijk = vtk.vtkMatrix4x4() volumeNode.GetRASToIJKMatrix(ras2ijk) p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]] p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]] # Create VTK line that will be used for sampling line = vtk.vtkLineSource() line.SetResolution(100) line.SetPoint1(p0ijk) line.SetPoint2(p1ijk) # Create VTK probe filter and sample the image probe = vtk.vtkProbeFilter() probe .SetInputConnection(line.GetOutputPort()) probe.SetSourceData(volumeNode.GetImageData()) probe.Update() # Return VTK array return probe.GetOutput().GetPointData().GetArray('ImageScalars')
def GetImageCoordinatesFromWorldCoordinates(self, position): ''' Convert a world coordinate point into an image indices coordinate point @param position: double[3] @return: int[3] ''' if not self.GetInput(): return [0.0, 0.0, 0.0] # Get information unorientedposition = [position[0], position[1], position[2], 1] spacing = list(self.GetInput().GetSpacing())+[0.0] origin = list(self.GetInput().GetOrigin())+[0.0] # apply inverted orientation matrix to the world-coordinate position inverse = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Invert(self.getOrientationMatrix(), inverse) inverse.MultiplyPoint(unorientedposition, unorientedposition) indices = [0]*3 for i in range(3): if math.fabs(spacing[i]) > 1e-5: indices[i] = vtk.vtkMath.Round((unorientedposition[i]-origin[i])/spacing[i]) else: indices[i] = 0 del inverse return indices
def save(self): # writer to new file logger.log('Exporting temp STL of model %s...' % self.name) # Extract transformations done to the actor matrix = vtk.vtkMatrix4x4() self.getActor().GetMatrix(matrix) # Apply transformation transform = vtk.vtkTransform() transform.SetMatrix(matrix) # T t_filter = vtk.vtkTransformPolyDataFilter() t_filter.SetInput(self.getPolyData()) t_filter.SetTransform(transform) # Triangle filter #vtkTriangleFilter # Clean Polydata #vtkcleanpolydata # Simplify the model #vtk.vtkDecimate # Save data to a STL file writer = vtk.vtkSTLWriter() writer.SetFileName('temp.stl') writer.SetInputConnection(t_filter.GetOutputPort()) writer.SetFileTypeToBinary() writer.Write() logger.log('End exporting')
def onApply(self): try: # Get master volume image data import vtkSegmentationCorePython as vtkSegmentationCore masterImageData = self.scriptedEffect.masterVolumeImageData() # Get modifier labelmap modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap() originalImageToWorldMatrix = vtk.vtkMatrix4x4() modifierLabelmap.GetImageToWorldMatrix(originalImageToWorldMatrix) # Get parameters min = self.scriptedEffect.doubleParameter("MinimumThreshold") max = self.scriptedEffect.doubleParameter("MaximumThreshold") self.scriptedEffect.saveStateForUndo() # Perform thresholding thresh = vtk.vtkImageThreshold() thresh.SetInputData(masterImageData) thresh.ThresholdBetween(min, max) thresh.SetInValue(1) thresh.SetOutValue(0) thresh.SetOutputScalarType(modifierLabelmap.GetScalarType()) thresh.Update() modifierLabelmap.DeepCopy(thresh.GetOutput()) except IndexError: logging.error('apply: Failed to threshold master volume!') pass # Apply changes self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet) # De-select effect self.scriptedEffect.selectEffect("")
def onApply(self): inputVolume = self.inputSelector.currentNode() outputVolume = self.outputSelector.currentNode() # check for input data if not (inputVolume and outputVolume): slicer.util.errorDisplay('Input and output volumes are required for conversion', windowTitle='Luminance') return # check that data has enough components inputImage = inputVolume.GetImageData() if not inputImage or inputImage.GetNumberOfScalarComponents() < 3: slicer.util.errorDisplay('Input does not have enough components for conversion', windowTitle='Vector to Scalar Volume') return # run the filter # - extract the RGB portions extract = vtk.vtkImageExtractComponents() extract.SetComponents(0,1,2) luminance = vtk.vtkImageLuminance() extract.SetInputConnection(inputVolume.GetImageDataConnection()) luminance.SetInputConnection(extract.GetOutputPort()) luminance.Update() ijkToRAS = vtk.vtkMatrix4x4() inputVolume.GetIJKToRASMatrix(ijkToRAS) outputVolume.SetIJKToRASMatrix(ijkToRAS) outputVolume.SetImageDataConnection(luminance.GetOutputPort()) # make the output volume appear in all the slice views selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveVolumeID(outputVolume.GetID()) slicer.app.applicationLogic().PropagateVolumeSelection(0)
def transform_polydata_from_disk(in_filename, transform_filename, out_filename): # Read it in. print "<io.py> Transforming ", in_filename, "->", out_filename, "..." # Read the transform from disk because we cannot pickle it (root, ext) = os.path.splitext(transform_filename) print root, ext if ext == '.xfm': reader = vtk.vtkMNITransformReader() reader.SetFileName(transform_filename) reader.Update() transform = reader.GetTransform() elif ext == '.img': reader = vtk.vtkImageReader() reader.SetFileName(transform_filename) reader.Update() coeffs = reader.GetOutput() transform = vtk.vtkBSplineTransform() transform.SetCoefficients(coeffs) print coeffs print transform else: f = open(transform_filename, 'r') transform = vtk.vtkTransform() matrix = vtk.vtkMatrix4x4() for i in range(0,4): for j in range(0,4): matrix_val = float(f.readline()) matrix.SetElement(i,j, matrix_val) transform.SetMatrix(matrix) del matrix start_time = time.time() pd = read_polydata(in_filename) elapsed_time = time.time() - start_time print "READ:", elapsed_time # Transform it. start_time = time.time() transformer = vtk.vtkTransformPolyDataFilter() if (vtk.vtkVersion().GetVTKMajorVersion() >= 6.0): transformer.SetInputData(pd) else: transformer.SetInput(pd) transformer.SetTransform(transform) transformer.Update() elapsed_time = time.time() - start_time print "TXFORM:", elapsed_time # Write it out. start_time = time.time() pd2 = transformer.GetOutput() write_polydata(pd2, out_filename) elapsed_time = time.time() - start_time print "WRITE:", elapsed_time # Clean up. del transformer del pd2 del pd del transform
def calculateDistance(self): pointerTipPoint = [0.0,0.0,0.0] m = vtk.vtkMatrix4x4() self.pointerTipToPointer.GetMatrixTransformToWorld(m) pointerTipPoint[0] = m.GetElement(0, 3) pointerTipPoint[1] = m.GetElement(1, 3) pointerTipPoint[2] = m.GetElement(2, 3) distance = math.sqrt(math.pow(pointerTipPoint[0]-self.pos[0], 2) + math.pow(pointerTipPoint[1]-self.pos[1], 2) + math.pow(pointerTipPoint[2]-self.pos[2], 2)) # La distancia se da en mm ----> 50mm = 5cm # Voy a normalizar con un tope de 20cm normalizedDistance = [(distance - 0)/200] if self.OSC_active: #print ("HOLAAA") c.send("/dumpOSC/0/0", 0) self.outputDistanceLabel.setText('%.1f' % distance) self.pos = [self.pos[i] for i in (0,1,2)] self.drawLineBetweenPoints(pointerTipPoint, self.pos) if self.sendDataOK: self.sendData(normalizedDistance)
def flyTo(self, f): """ Apply the fth step in the path to the global camera""" if self.path: f = int(f) p = self.path[f] self.camera.SetPosition(*p) foc = self.path[f+1] self.camera.SetFocalPoint(*foc) toParent = vtk.vtkMatrix4x4() self.transform.GetMatrixTransformToParent(toParent) toParent.SetElement(0 ,3, p[0]) toParent.SetElement(1, 3, p[1]) toParent.SetElement(2, 3, p[2]) # Set up transform orientation component so that # Z axis is aligned with view direction and # Y vector is aligned with the curve's plane normal. # This can be used for example to show a reformatted slice # using with SlicerIGT extension's VolumeResliceDriver module. import numpy as np zVec = (foc-p)/np.linalg.norm(foc-p) yVec = self.pathPlaneNormal xVec = np.cross(yVec, zVec) toParent.SetElement(0, 0, xVec[0]) toParent.SetElement(1, 0, xVec[1]) toParent.SetElement(2, 0, xVec[2]) toParent.SetElement(0, 1, yVec[0]) toParent.SetElement(1, 1, yVec[1]) toParent.SetElement(2, 1, yVec[2]) toParent.SetElement(0, 2, zVec[0]) toParent.SetElement(1, 2, zVec[1]) toParent.SetElement(2, 2, zVec[2]) self.transform.SetMatrixTransformToParent(toParent)
def dicom_to_vti(imagedata, filename): logging.debug("In data.dicom_to_vti()") extent = imagedata.GetWholeExtent() spacing = imagedata.GetSpacing() origin = imagedata.GetOrigin() center = ( origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]), origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]), origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]), ) resliceAxes = vtk.vtkMatrix4x4() vtkMatrix = (1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) resliceAxes.DeepCopy(vtkMatrix) resliceAxes.SetElement(0, 3, center[0]) resliceAxes.SetElement(1, 3, center[1]) resliceAxes.SetElement(2, 3, center[2]) reslice = vtk.vtkImageReslice() reslice.SetInput(imagedata) reslice.SetInformationInput(imagedata) reslice.SetResliceAxes(resliceAxes) reslice.SetOutputDimensionality(3) reslice.Update() imagedata = reslice.GetOutput() writer = vtk.vtkXMLImageDataWriter() writer.SetInput(imagedata) writer.SetFileName(filename) writer.Write()
def AddTimestamp( self, time, matrix, point, role ): for i in range( self.targets.GetNumberOfFiducials() ): # Find the centre of the fiducial currTargetPosition = [ 0, 0, 0 ] self.targets.GetNthFiducialPosition( i, currTargetPosition ) currTargetPosition_RAS = [ currTargetPosition[ 0 ], currTargetPosition[ 1 ], currTargetPosition[ 2 ], 1 ] # Assume the matrix is ImageToRAS # We know the center of mass of the structure in the RAS coordinate system # Transform the center of mass into the image coordinate system RASToImageMatrix = vtk.vtkMatrix4x4() RASToImageMatrix.DeepCopy( matrix ) RASToImageMatrix.Invert() currTargetPosition_Image = [ 0, 0, 0, 1 ] RASToImageMatrix.MultiplyPoint( currTargetPosition_RAS, currTargetPosition_Image ) # Assumption is the imaging plane is in the Image coordinate system's XY plane if ( currTargetPosition_Image[0] < self.imageMinX or currTargetPosition_Image[0] > self.imageMaxX ): return if ( currTargetPosition_Image[1] < self.imageMinY or currTargetPosition_Image[1] > self.imageMaxY ): return # Note: This only works for similarity matrix (i.e. uniform scale factor) scaleFactor = math.pow( matrix.Determinant(), 1.0 / 3.0 ) # Now check if the z-coordinate of the point in the image coordinate system is below some threshold value (i.e. 2mm) if ( abs( currTargetPosition_Image[2] ) < TargetsScanned.IMAGE_PLANE_THRESHOLD / scaleFactor ): self.hitTargets[ i ] = 1
def loadTCGAData(self): slicer.util.openAddVolumeDialog() red_logic = slicer.app.layoutManager().sliceWidget("Red").sliceLogic() red_cn = red_logic.GetSliceCompositeNode() fgrdVolID = red_cn.GetBackgroundVolumeID() fgrdNode = slicer.util.getNode(fgrdVolID) fMat=vtk.vtkMatrix4x4() fgrdNode.GetIJKToRASDirectionMatrix(fMat) bgrdName = fgrdNode.GetName() + '_gray' self.tilename = fgrdNode.GetName() + '_gray' self.parameterNode.SetParameter("SlicerPathology,tilename", self.tilename) # Create dummy grayscale image magnitude = vtk.vtkImageMagnitude() magnitude.SetInputData(fgrdNode.GetImageData()) magnitude.Update() bgrdNode = slicer.vtkMRMLScalarVolumeNode() bgrdNode.SetImageDataConnection(magnitude.GetOutputPort()) bgrdNode.SetName(bgrdName) bgrdNode.SetIJKToRASDirectionMatrix(fMat) slicer.mrmlScene.AddNode(bgrdNode) bgrdVolID = bgrdNode.GetID() red_cn.SetForegroundVolumeID(fgrdVolID) red_cn.SetBackgroundVolumeID(bgrdVolID) red_cn.SetForegroundOpacity(1) self.checkAndSetLUT() print bgrdName cv = slicer.util.getNode(bgrdName) self.volumesLogic = slicer.modules.volumes.logic() labelName = bgrdName+'-label' refLabel = self.volumesLogic.CreateAndAddLabelVolume(slicer.mrmlScene,cv,labelName) refLabel.GetDisplayNode().SetAndObserveColorNodeID(self.SlicerPathologyColorNode.GetID()) self.editorWidget.helper.setMasterVolume(cv)
def rotpos_to_vtkMatrix4x4(r,p): m = vtk.vtkMatrix4x4() m.DeepCopy((r[0], r[1], r[2], p[0],\ r[3], r[4], r[5], p[1],\ r[6], r[7], r[8], p[2],\ 0.0, 0.0, 0.0, 1.0)) return m
def GetIntensities(self,selector): probe = vtk.vtkProbeFilter() volume = Globals.imagePipeline.volume m = vtk.vtkMatrix4x4() # populate the matrix m.DeepCopy( selector.GetDirectionCosines() ) axesOrigin = selector.GetAxesOrigin() m.SetElement(0,3, axesOrigin[0]) m.SetElement(1,3, axesOrigin[1]) m.SetElement(2,3, axesOrigin[2]) # use the selector to project points in the right spatial position volSpline = PlaneSpline() for pt in self.points: wpt = m.MultiplyPoint( [pt[0],pt[1],0,1] ) volSpline.AddPoint(wpt[0:3]) polyData = volSpline.GetVtkPolyData() probe.SetInput(polyData) probe.SetSource(volume) probe.Update() lstValues = [] vtkValues = probe.GetOutput().GetPointData().GetScalars() for i in range(vtkValues.GetNumberOfTuples()): lstValues.append( vtkValues.GetComponent(i,0) ) return str(lstValues)[1:-1]
def pasteFromMainToCroppedLabelVolume(mainLblVolume, croppedLblVolume, colorID): pasted = False if (mainLblVolume is not None) & (croppedLblVolume is not None): mainImageData = mainLblVolume.GetImageData() croppedImgData = croppedLblVolume.GetImageData() if (mainImageData is not None) & (croppedImgData is not None): rastoijk = vtk.vtkMatrix4x4() mainLblVolume.GetRASToIJKMatrix(rastoijk) croppedLblRASOrigin = croppedLblVolume.GetOrigin() croppedLblRASOrigin = [croppedLblRASOrigin[0],croppedLblRASOrigin[1],croppedLblRASOrigin[2],1.0] croppedLblIJKShiftedOrigin = rastoijk.MultiplyDoublePoint(croppedLblRASOrigin) croppedLblIJKShiftedOrigin = [ int(croppedLblIJKShiftedOrigin[0] + 0.5), int(croppedLblIJKShiftedOrigin[1] + 0.5), int(croppedLblIJKShiftedOrigin[2] + 0.5)] dims = croppedImgData.GetDimensions() for x in range(0,dims[0],1): for y in range(0,dims[1],1): for z in range(0,dims[2],1): p = mainImageData.GetScalarComponentAsDouble(x+croppedLblIJKShiftedOrigin[0],y+croppedLblIJKShiftedOrigin[1],z+croppedLblIJKShiftedOrigin[2],0) if p == colorID: croppedImgData.SetScalarComponentFromDouble(x,y,z,0,p) if not pasted: pasted = True return pasted
def OnLeftButtonUp(self, obj, event): print ("released left mouse button") m = vtk.vtkMatrix4x4() print "matrix is :" for i in range(0, 2): for j in range(0, 2): print (m.GetElement(i, j))
def __init__(self, module_manager): # initialise our base class ModuleBase.__init__(self, module_manager) self._input_mmd = None self._output_mmd = MedicalMetaData() self._output_mmd.medical_image_properties = \ vtk.vtkMedicalImageProperties() self._output_mmd.direction_cosines = \ vtk.vtkMatrix4x4() # if the value (as it appears in mk.vtk_kit.constants.mipk) # appears in the dict, its value refers to the user supplied # value. when the user resets a field, that key is removed # from the dict self._config.new_value_dict = {} # this is the list of relevant properties self.mip_attr_l = \ module_kits.vtk_kit.constants.medical_image_properties_keywords # this will be used to keep track of changes made to the prop # grid before they are applied to the config self._grid_value_dict = {} self._view_frame = None self.sync_module_logic_with_config()
def AddTimestamp( self, time, matrix, point, role ): if ( self.trajectory is None ): return # Build up the matrix newRow = [ 0 ] * self.trajectory.GetNumberOfDataNodes() self.distanceMatrix.append( newRow ) i = len( self.distanceMatrix ) - 1 # Use dynamic programming to compute the next row for j in range( self.trajectory.GetNumberOfDataNodes() ): currTrajectoryNode = self.trajectory.GetNthDataNode( j ) currTrajectoryMatrix = vtk.vtkMatrix4x4() currTrajectoryNode.GetMatrixTransformToWorld( currTrajectoryMatrix ) currTrajectoryPoint = [ currTrajectoryMatrix.GetElement( 0, 3 ), currTrajectoryMatrix.GetElement( 1, 3 ), currTrajectoryMatrix.GetElement( 2, 3 ) ] currDistance = vtk.vtkMath.Distance2BetweenPoints( point[ 0:3 ], currTrajectoryPoint ) if ( i == 0 ): if ( j == 0 ): self.distanceMatrix[ i ][ j ] = currDistance else: self.distanceMatrix[ i ][ j ] = max( self.distanceMatrix[ i ][ j - 1 ], currDistance ) else: if ( j == 0 ): self.distanceMatrix[ i ][ j ] = max( self.distanceMatrix[ i - 1 ][ j ], currDistance ) else: self.distanceMatrix[ i ][ j ] = max( min( self.distanceMatrix[ i ][ j - 1 ], self.distanceMatrix[ i - 1 ][ j ], self.distanceMatrix[ i - 1 ][ j - 1 ] ), currDistance ) self.frechetDistance = math.sqrt( self.distanceMatrix[ i ][ self.trajectory.GetNumberOfDataNodes() - 1 ] )
def __init__(self, sliceWidget): super(PaintEffectTool,self).__init__(sliceWidget) # create a logic instance to do the non-gui work self.logic = PaintEffectLogic(self.sliceWidget.sliceLogic()) # configuration variables self.delayedPaint = True self.parameterNode = EditUtil.getParameterNode() self.sphere = not (0 == int(self.parameterNode.GetParameter("PaintEffect,sphere"))) self.smudge = not (0 == int(self.parameterNode.GetParameter("PaintEffect,smudge"))) self.pixelMode = not (0 == int(self.parameterNode.GetParameter("PaintEffect,pixelMode"))) self.radius = float(self.parameterNode.GetParameter("PaintEffect,radius")) # interaction state variables self.position = [0, 0, 0] self.paintCoordinates = [] self.feedbackActors = [] self.lastRadius = 0 # scratch variables self.rasToXY = vtk.vtkMatrix4x4() # initialization self.brush = vtk.vtkPolyData() self.createGlyph(self.brush) self.mapper = vtk.vtkPolyDataMapper2D() self.actor = vtk.vtkActor2D() self.mapper.SetInputData(self.brush) self.actor.SetMapper(self.mapper) self.actor.VisibilityOff() self.renderer.AddActor2D(self.actor) self.actors.append(self.actor) self.processEvent()
def AddTimestamp( self, time, matrix, point, role ): if ( self.trajectory is None ): return # Build up the matrix newRow = [ 0 ] * self.trajectory.GetNumberOfDataNodes() self.distanceMatrix.append( newRow ) i = len( self.distanceMatrix ) - 1 # Use dynamic programming to compute the next row for j in range( self.trajectory.GetNumberOfDataNodes() ): currTrajectoryNode = self.trajectory.GetNthDataNode( j ) currTrajectoryMatrix = vtk.vtkMatrix4x4() currTrajectoryNode.GetMatrixTransformToWorld( currTrajectoryMatrix ) currTrajectoryPoint = [ currTrajectoryMatrix.GetElement( 0, 3 ), currTrajectoryMatrix.GetElement( 1, 3 ), currTrajectoryMatrix.GetElement( 2, 3 ) ] currDistance = math.sqrt( vtk.vtkMath.Distance2BetweenPoints( point[ 0:3 ], currTrajectoryPoint ) ) if ( i == 0 ): if ( j == 0 ): self.distanceMatrix[ i ][ j ] = currDistance else: self.distanceMatrix[ i ][ j ] = currDistance + self.distanceMatrix[ i ][ j - 1 ] else: if ( j == 0 ): self.distanceMatrix[ i ][ j ] = currDistance + self.distanceMatrix[ i - 1 ][ j ] else: self.distanceMatrix[ i ][ j ] = currDistance + min( self.distanceMatrix[ i ][ j - 1 ], self.distanceMatrix[ i - 1 ][ j ], self.distanceMatrix[ i - 1 ][ j - 1 ] ) self.dtwDistance = self.distanceMatrix[ i ][ self.trajectory.GetNumberOfDataNodes() - 1 ] # Assume the dtw path length is the sum of the number of points in each sequence minus 1 # Note: this counts diagonal jumps as 2 self.dtwPathLength = len( self.distanceMatrix ) + len( self.distanceMatrix[ i ] ) - 1
def Execute(self): if (self.Mesh == None): self.PrintError('Error: no Mesh.') if not self.Matrix4x4: self.Matrix4x4 = vtk.vtkMatrix4x4() if self.MatrixCoefficients != []: self.PrintLog('Setting up transform matrix using specified coefficients') self.Matrix4x4.DeepCopy(self.MatrixCoefficients) elif self.Translation != [0.0,0.0,0.0] or self.Rotation != [0.0,0.0,0.0] or self.Scaling != [1.0,1.0,1.0]: self.PrintLog('Setting up transform matrix using specified translation, rotation and/or scaling') transform = vtk.vtkTransform() transform.RotateX(self.Rotation[0]) transform.RotateY(self.Rotation[1]) transform.RotateZ(self.Rotation[2]) transform.Translate(self.Translation[0], self.Translation[1], self.Translation[2]) transform.Scale(self.Scaling[0], self.Scaling[1], self.Scaling[2]) self.Matrix4x4.DeepCopy(transform.GetMatrix()) if self.InvertMatrix: self.Matrix4x4.Invert() transform = vtk.vtkMatrixToLinearTransform() transform.SetInput(self.Matrix4x4) transformFilter = vtk.vtkTransformFilter() transformFilter.SetInputData(self.Mesh) transformFilter.SetTransform(transform) transformFilter.Update() self.Mesh = transformFilter.GetOutput()
def runZoneDetection(self, fids, inputAtlas, colorLut): #[TODO] CHE FA QUI nFids = fids.GetNumberOfFiducials() atlas = slicer.util.array(inputAtlas.GetName()) ras2vox_atlas = vtk.vtkMatrix4x4() inputAtlas.GetRASToIJKMatrix(ras2vox_atlas) #[TODO] CHE FA QUI???? FSLUT = {} with open(colorLut, 'r') as f: for line in f: if not re.match('^#', line) and len(line) > 10: lineTok = re.split('\s+', line) FSLUT[int(lineTok[0])] = lineTok[1] # Initialize the progress bar pb self.pb.setRange(0, nFids) self.pb.show() self.pb.setValue(0) # Update the app process events, i.e. show the progress of the # progress bar slicer.app.processEvents() for i in xrange(nFids): # update progress bar self.pb.setValue(i + 1) slicer.app.processEvents() # Only for Active Fiducial points the GMPI is computed if fids.GetNthFiducialSelected(i) == True: # istantiate the variable which holds the point currContactCentroid = [0, 0, 0] # copy current position from FiducialList fids.GetNthFiducialPosition(i, currContactCentroid) # append 1 at the end of array before applying transform currContactCentroid.append(1) # transform from RAS to IJK voxIdx = ras2vox_atlas.MultiplyFloatPoint(currContactCentroid) voxIdx = numpy.round(numpy.array(voxIdx[:3])).astype(int) # build a -3:3 linear mask mask = numpy.arange(-3, 4) # get Patch Values from loaded Atlas in a 7x7x7 region around # contact centroid and extract the frequency for each unique # patch Value present in the region patchValues = atlas[numpy.ix_(mask+voxIdx[2],\ mask+voxIdx[1],\ mask+voxIdx[0])] # Find the unique values on the matrix above uniqueValues = numpy.unique(patchValues) # Flatten the patch value and create a tuple patchValues = tuple(patchValues.flatten(1)) # Create an array of frequency for each unique value itemfreq = [patchValues.count(x) for x in uniqueValues] # Compute the max frequency totPercentage = numpy.sum(itemfreq) # Recover the real patch names patchNames = [FSLUT[pValues] for pValues in uniqueValues] # Create the zones parcels = dict(zip(itemfreq, patchNames)) #print parcels #[TODO] COSA FA QUI??? anatomicalPositionsString = [','.join([v,str( round( float(k) / totPercentage * 100 ))])\ for k,v in parcels.iteritems()] # Preserve if some old description was already there fids.SetNthMarkupDescription(i,fids.GetNthMarkupDescription(i) + \ " " + ','.join(anatomicalPositionsString))
def onMarkupAdded(self, fiducialNodeCaller, event): # Set the location and index to zero because its needs to be initialized centroid=[0,0,0] # This checks if there is not a display node if self.fiducialNode.GetDisplayNode() is None: # then creates one if that is the case self.fiducialNode.CreateDefaultDisplayNodes() # This sets a variable as the display node displayNode = self.fiducialNode.GetDisplayNode() # This sets the type to be a cross hair displayNode.SetGlyphType(3) # This sets the size displayNode.SetGlyphScale(2.5) # This says that you dont want text displayNode.SetTextScale(0) # This sets the color displayNode.SetSelectedColor(0, 0, 1) # This saves the location the markup is place # Collect the point in image space self.fiducialNode.GetMarkupPoint(self.fiducialNode.GetNumberOfMarkups()-1, 0, centroid) tipToProbeTransform = vtk.vtkMatrix4x4() self.TransformSelector.currentNode().GetMatrixTransformToWorld(tipToProbeTransform) origin = [tipToProbeTransform.GetElement(0, 3), tipToProbeTransform.GetElement(1,3), tipToProbeTransform.GetElement(2,3)] dir = [tipToProbeTransform.GetElement(0, 2), tipToProbeTransform.GetElement(1,2), tipToProbeTransform.GetElement(2,2)] if self.fidCount == 0: self.logic.AddPointAndLineMan([centroid[0],centroid[1],0], origin, dir) if self.fidCount == 1: self.logic.AddPointAndLineMan([0,centroid[1],centroid[2]], origin, dir) self.ImageToProbe = self.logic.manualRegLogic.CalculateRegistration() self.transformTable.setItem(0,0, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(0,0)))) self.transformTable.setItem(0,1, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(0,1)))) self.transformTable.setItem(0,2, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(0,2)))) self.transformTable.setItem(0,3, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(0,3)))) self.transformTable.setItem(1,0, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(1,0)))) self.transformTable.setItem(1,1, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(1,1)))) self.transformTable.setItem(1,2, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(1,2)))) self.transformTable.setItem(1,3, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(1,3)))) self.transformTable.setItem(2,0, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(2,0)))) self.transformTable.setItem(2,1, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(2,1)))) self.transformTable.setItem(2,2, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(2,2)))) self.transformTable.setItem(2,3, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(2,3)))) self.transformTable.setItem(3,0, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(3,0)))) self.transformTable.setItem(3,1, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(3,1)))) self.transformTable.setItem(3,2, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(3,2)))) self.transformTable.setItem(3,3, qt.QTableWidgetItem(str(self.ImageToProbe.GetElement(3,3)))) self.transformTable.resizeColumnToContents(0) self.transformTable.resizeColumnToContents(1) self.transformTable.resizeColumnToContents(2) self.transformTable.resizeColumnToContents(3) self.fiducialNode.RemoveAllMarkups() self.fiducialNode.RemoveObserver(self.markupAddedObserverTag) slicer.mrmlScene.RemoveNode(self.fiducialNode) self.fiducialNode = None if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0: if self.fidCount == 0: slicer.modules.markups.logic().StartPlaceMode(0) self.redWidget.setCursor(qt.QCursor(2)) self.yellowWidget.setCursor(qt.QCursor(2)) if self.fidCount == 1: self.connectorNode.Start() self.connectorNode2.Start() self.connectButton.text = "Disconnect" self.freezeButton.text = "Freeze"
def dicomTransform(self, image, image_pos_pat, image_ori_pat): """ dicomTransform: transforms an image to a DICOM coordinate frame INPUTS: ======= image: (vtkImageData) Input image to Transform image_pos_pat: (list(dicomInfo[0x0020,0x0032].value))) Image position patient Dicom Tag image_ori_pat: (list(dicomInfo[0x0020,0x0037].value)) Image oreintation patient Dicom Tag OUTPUTS: ======= transformed_image (vtkImageData) Transformed imaged mapped to dicom coords frame transform (vtkTransform) Transform used """ # If one considers the localizer plane as a "viewport" onto the DICOM 3D coordinate space, then that viewport is described by its origin, its row unit vector, column unit vector and a normal unit vector (derived from the row and column vectors by taking the cross product). Now if one moves the origin to 0,0,0 and rotates this viewing plane such that the row vector is in the +X direction, the column vector the +Y direction, and the normal in the +Z direction, then one has a situation where the X coordinate now represents a column offset in mm from the localizer's top left hand corner, and the Y coordinate now represents a row offset in mm from the localizer's top left hand corner, and the Z coordinate can be ignored. One can then convert the X and Y mm offsets into pixel offsets using the pixel spacing of the localizer imag # Initialize Image orienation "Image Orientation Patient Matrix" IO = matrix( [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]]) # Assign the 6-Image orientation patient coordinates (from Dicomtags) IO[0,0] = image_ori_pat[0]; IO[0,1] = image_ori_pat[1]; IO[0,2] = image_ori_pat[2]; IO[1,0] = image_ori_pat[3]; IO[1,1] = image_ori_pat[4]; IO[1,2] = image_ori_pat[5]; # obtain thrid column as the cross product of column 1 y 2 IO_col1 = [image_ori_pat[0], image_ori_pat[1], image_ori_pat[2]] IO_col2 = [image_ori_pat[3], image_ori_pat[4], image_ori_pat[5]] IO_col3 = cross(IO_col1, IO_col2) # assign column 3 IO[2,0] = IO_col3[0]; IO[2,1] = IO_col3[1]; IO[2,2] = IO_col3[2]; IP = array([0, 0, 0, 1]) # Initialization Image Position IP[0] = image_pos_pat[0]; IP[1] = image_pos_pat[1]; IP[2] = image_pos_pat[2]; IO[0,3] = image_pos_pat[0]; IO[1,3] = image_pos_pat[1]; IO[2,3] = image_pos_pat[2] print "Compute: Position, Orientation, matrix, & Volume Origin" print image_pos_pat print image_ori_pat print IO origin = IP*IO.I print origin[0,0], origin[0,1], origin[0,2] # Create matrix 4x4 DICOM_mat = vtk.vtkMatrix4x4(); DICOM_mat.SetElement(0, 0, IO[0,0]) DICOM_mat.SetElement(0, 1, IO[0,1]) DICOM_mat.SetElement(0, 2, IO[0,2]) DICOM_mat.SetElement(0, 3, IO[0,3]) DICOM_mat.SetElement(1, 0, IO[1,0]) DICOM_mat.SetElement(1, 1, IO[1,1]) DICOM_mat.SetElement(1, 2, IO[1,2]) DICOM_mat.SetElement(1, 3, IO[1,3]) DICOM_mat.SetElement(2, 0, IO[2,0]) DICOM_mat.SetElement(2, 1, IO[2,1]) DICOM_mat.SetElement(2, 2, IO[2,2]) DICOM_mat.SetElement(2, 3, IO[2,3]) DICOM_mat.SetElement(3, 0, IO[3,0]) DICOM_mat.SetElement(3, 1, IO[3,1]) DICOM_mat.SetElement(3, 2, IO[3,2]) DICOM_mat.SetElement(3, 3, IO[3,3]) #DICOM_mat.Invert() # Set up the axes transform = vtk.vtkTransform() transform.Concatenate(DICOM_mat) transform.Update() # Set up the cube (set up the translation back to zero DICOM_mat_cube = vtk.vtkMatrix4x4(); DICOM_mat_cube.DeepCopy(DICOM_mat) DICOM_mat_cube.SetElement(0, 3, 0) DICOM_mat_cube.SetElement(1, 3, 0) DICOM_mat_cube.SetElement(2, 3, 0) transform_cube = vtk.vtkTransform() transform_cube.Concatenate(DICOM_mat_cube) transform_cube.Update() # Change info # Flip along Y-Z-axis: VTK uses computer graphics convention where the first pixel in memory is shown # in the lower left of the displayed image. flipZ_image = vtk.vtkImageFlip() flipZ_image.SetInputData(image) flipZ_image.SetFilteredAxis(2) flipZ_image.Update() flipY_image = vtk.vtkImageFlip() flipY_image.SetInputData(flipZ_image.GetOutput()) flipY_image.SetFilteredAxis(1) flipY_image.Update() # Change info origin flipY_origin_image = vtk.vtkImageChangeInformation() flipY_origin_image.SetInputData( flipY_image.GetOutput() ); flipY_origin_image.SetOutputOrigin(origin[0,0], origin[0,1], origin[0,2]) flipY_origin_image.Update() transformed_image = flipY_origin_image.GetOutput() self.dims = transformed_image.GetDimensions() print "Image Dimensions" print self.dims (xMin, xMax, yMin, yMax, zMin, zMax) = transformed_image.GetExtent() print "Image Extension" print xMin, xMax, yMin, yMax, zMin, zMax self.spacing = transformed_image.GetSpacing() print "Image Spacing" print self.spacing self.origin = transformed_image.GetOrigin() print "Image Origin" print self.origin return transformed_image, transform_cube
def instrumentNodeUpdated(self, instrumentIndex): parameterNode = self.getParameterNode() address = self.instrumentOscAddress[instrumentIndex] NeedleNode = parameterNode.GetNodeReference("InstrumentSource0") ProbeNode = parameterNode.GetNodeReference("InstrumentSource1") PlaneNode = parameterNode.GetNodeReference("InstrumentSource2") NeedleToReference = vtk.vtkTransform() ProbeToReference = vtk.vtkTransform() PlaneToReference = vtk.vtkTransform() NeedleToReferenceMatrix = vtk.vtkMatrix4x4() slicer.vtkMRMLTransformNode.GetMatrixTransformBetweenNodes( NeedleNode, parameterNode.GetNodeReference("InstrumentReference0"), NeedleToReferenceMatrix) ProbeToReferenceMatrix = vtk.vtkMatrix4x4() slicer.vtkMRMLTransformNode.GetMatrixTransformBetweenNodes( ProbeNode, parameterNode.GetNodeReference("InstrumentReference1"), ProbeToReferenceMatrix) PlaneToReferenceMatrix = vtk.vtkMatrix4x4() slicer.vtkMRMLTransformNode.GetMatrixTransformBetweenNodes( PlaneNode, parameterNode.GetNodeReference("InstrumentReference2"), PlaneToReferenceMatrix) NeedleToReference.SetMatrix(NeedleToReferenceMatrix) Nx = NeedleToReferenceMatrix.GetElement(0, 3) Ny = NeedleToReferenceMatrix.GetElement(1, 3) Nz = NeedleToReferenceMatrix.GetElement(2, 3) Nox = NeedleToReferenceMatrix.GetElement(0, 2) Noy = NeedleToReferenceMatrix.GetElement(1, 2) Noz = NeedleToReferenceMatrix.GetElement(2, 2) ProbeToReference.SetMatrix(ProbeToReferenceMatrix) z0 = ProbeToReferenceMatrix.GetElement(0, 2) z1 = ProbeToReferenceMatrix.GetElement(1, 2) z2 = ProbeToReferenceMatrix.GetElement(2, 2) Cx = PlaneToReferenceMatrix.GetElement(0, 3) Cy = PlaneToReferenceMatrix.GetElement(1, 3) Cz = PlaneToReferenceMatrix.GetElement(2, 3) iCom = z0 jCom = z1 kCom = z2 dCom = (-z0 * Cx) + (-z1 * Cy) + (-z2 * Cz) numerador = abs(Nx * iCom + Ny * jCom + Nz * kCom + dCom) denominador = math.sqrt(pow(iCom, 2) + pow(jCom, 2) + pow(kCom, 2)) div = numerador / denominador posicion = iCom * Nx + jCom * Ny + kCom * Nz + dCom grados = ( math.asin(iCom * Nox + jCom * Noy + kCom * Noz / (math.sqrt(pow(iCom, 2) + pow(jCom, 2) + pow(kCom, 2)) * math.sqrt(pow(Nox, 2) + pow(Noy, 2) + pow(Noz, 2)))) * 180) / (4 * math.atan(1)) logging.info("Grados: " + str(grados)) if denominador != 0: self.oscLogic.oscSendMessage("/SoundNav/Distance", div) self.oscLogic.oscSendMessage("/SoundNav/Position", posicion) self.oscLogic.oscSendMessage("/SoundNav/Degrees", grados)
def cutSurfaceWithModel(self, segmentMarkupNode, segmentModel): import vtkSegmentationCorePython as vtkSegmentationCore if not segmentMarkupNode: raise AttributeError("{}: segment markup node not set.".format( self.__class__.__name__)) if not segmentModel: raise AttributeError("{}: segment model not set.".format( self.__class__.__name__)) if segmentMarkupNode and segmentModel.GetPolyData().GetNumberOfPolys( ) > 0: operationName = self.scriptedEffect.parameter("Operation") segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() if not segmentationNode: raise AttributeError("{}: Segmentation node not set.".format( self.__class__.__name__)) modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap() if not modifierLabelmap: raise AttributeError( "{}: ModifierLabelmap not set. This can happen for various reasons:\n" "No master volume set for segmentation,\n" "No existing segments for segmentation, or\n" "No referenceImageGeometry is specified in the segmentation" .format(self.__class__.__name__)) WorldToModifierLabelmapIjkTransform = vtk.vtkTransform() WorldToModifierLabelmapIjkTransformer = vtk.vtkTransformPolyDataFilter( ) WorldToModifierLabelmapIjkTransformer.SetTransform( WorldToModifierLabelmapIjkTransform) WorldToModifierLabelmapIjkTransformer.SetInputConnection( segmentModel.GetPolyDataConnection()) segmentationToSegmentationIjkTransformMatrix = vtk.vtkMatrix4x4() modifierLabelmap.GetImageToWorldMatrix( segmentationToSegmentationIjkTransformMatrix) segmentationToSegmentationIjkTransformMatrix.Invert() WorldToModifierLabelmapIjkTransform.Concatenate( segmentationToSegmentationIjkTransformMatrix) worldToSegmentationTransformMatrix = vtk.vtkMatrix4x4() slicer.vtkMRMLTransformNode.GetMatrixTransformBetweenNodes( None, segmentationNode.GetParentTransformNode(), worldToSegmentationTransformMatrix) WorldToModifierLabelmapIjkTransform.Concatenate( worldToSegmentationTransformMatrix) WorldToModifierLabelmapIjkTransformer.Update() polyToStencil = vtk.vtkPolyDataToImageStencil() polyToStencil.SetOutputSpacing(1.0, 1.0, 1.0) polyToStencil.SetInputConnection( WorldToModifierLabelmapIjkTransformer.GetOutputPort()) boundsIjk = WorldToModifierLabelmapIjkTransformer.GetOutput( ).GetBounds() modifierLabelmapExtent = self.scriptedEffect.modifierLabelmap( ).GetExtent() polyToStencil.SetOutputWholeExtent(modifierLabelmapExtent[0], modifierLabelmapExtent[1], modifierLabelmapExtent[2], modifierLabelmapExtent[3], int(round(boundsIjk[4])), int(round(boundsIjk[5]))) polyToStencil.Update() stencilData = polyToStencil.GetOutput() stencilExtent = [0, -1, 0, -1, 0, -1] stencilData.SetExtent(stencilExtent) stencilToImage = vtk.vtkImageStencilToImage() stencilToImage.SetInputConnection(polyToStencil.GetOutputPort()) if operationName in ("FILL_INSIDE", "ERASE_INSIDE", "SET"): stencilToImage.SetInsideValue(1.0) stencilToImage.SetOutsideValue(0.0) else: stencilToImage.SetInsideValue(0.0) stencilToImage.SetOutsideValue(1.0) stencilToImage.SetOutputScalarType( modifierLabelmap.GetScalarType()) stencilPositioner = vtk.vtkImageChangeInformation() stencilPositioner.SetInputConnection( stencilToImage.GetOutputPort()) stencilPositioner.SetOutputSpacing(modifierLabelmap.GetSpacing()) stencilPositioner.SetOutputOrigin(modifierLabelmap.GetOrigin()) stencilPositioner.Update() orientedStencilPositionerOutput = vtkSegmentationCore.vtkOrientedImageData( ) orientedStencilPositionerOutput.ShallowCopy( stencilToImage.GetOutput()) imageToWorld = vtk.vtkMatrix4x4() modifierLabelmap.GetImageToWorldMatrix(imageToWorld) orientedStencilPositionerOutput.SetImageToWorldMatrix(imageToWorld) vtkSegmentationCore.vtkOrientedImageDataResample.ModifyImage( modifierLabelmap, orientedStencilPositionerOutput, vtkSegmentationCore.vtkOrientedImageDataResample. OPERATION_MAXIMUM) modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd if operationName == "ERASE_INSIDE" or operationName == "ERASE_OUTSIDE": modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeRemove elif operationName == "SET": modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet self.scriptedEffect.modifySelectedSegmentByLabelmap( modifierLabelmap, modMode) # get fiducial positions as space-separated list import numpy n = segmentMarkupNode.GetNumberOfFiducials() fPos = [] for i in range(n): coord = [0.0, 0.0, 0.0] segmentMarkupNode.GetNthFiducialPosition(i, coord) fPos.extend(coord) fPosString = ' '.join(map(str, fPos)) segmentID = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() segment = segmentationNode.GetSegmentation().GetSegment(segmentID) segment.SetTag("SurfaceCutEffectMarkupPositions", fPosString)
def start(self, preview=False): logging.debug("Starting Level Set Segmentation..") # first we need the nodes currentVolumeNode = self.inputVolumeNodeSelector.currentNode() currentSeedsNode = self.seedFiducialsNodeSelector.currentNode() currentVesselnessNode = self.vesselnessVolumeNodeSelector.currentNode() currentStoppersNode = self.stopperFiducialsNodeSelector.currentNode() currentLabelMapNode = self.outputVolumeNodeSelector.currentNode() currentModelNode = self.outputModelNodeSelector.currentNode() if not currentVolumeNode: # we need a input volume node return False if not currentSeedsNode: # we need a seeds node return False if not currentStoppersNode or currentStoppersNode.GetID() == currentSeedsNode.GetID(): # we need a current stopper node # self.stopperFiducialsNodeSelector.addNode() pass if not currentLabelMapNode or currentLabelMapNode.GetID() == currentVolumeNode.GetID(): newLabelMapNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLLabelMapVolumeNode") newLabelMapNode.UnRegister(None) newLabelMapNode.CopyOrientation(currentVolumeNode) newLabelMapNode.SetName(slicer.mrmlScene.GetUniqueNameByString(self.outputVolumeNodeSelector.baseName)) currentLabelMapNode = slicer.mrmlScene.AddNode(newLabelMapNode) currentLabelMapNode.CreateDefaultDisplayNodes() self.outputVolumeNodeSelector.setCurrentNode(currentLabelMapNode) if not currentModelNode: # we need a current model node, the display node is created later newModelNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLModelNode") newModelNode.UnRegister(None) newModelNode.SetName(slicer.mrmlScene.GetUniqueNameByString(self.outputModelNodeSelector.baseName)) currentModelNode = slicer.mrmlScene.AddNode(newModelNode) currentModelNode.CreateDefaultDisplayNodes() self.outputModelNodeSelector.setCurrentNode(currentModelNode) # now we need to convert the fiducials to vtkIdLists seeds = LevelSetSegmentationWidget.convertFiducialHierarchyToVtkIdList(currentSeedsNode, currentVolumeNode) if currentStoppersNode: stoppers = LevelSetSegmentationWidget.convertFiducialHierarchyToVtkIdList(currentStoppersNode, currentVolumeNode) else: stoppers = vtk.vtkIdList() # the input image for the initialization inputImage = vtk.vtkImageData() # check if we have a vesselnessNode - this will be our input for the initialization then if currentVesselnessNode: # yes, there is one inputImage.DeepCopy(currentVesselnessNode.GetImageData()) else: # no, there is none - we use the original image inputImage.DeepCopy(currentVolumeNode.GetImageData()) # initialization initImageData = vtk.vtkImageData() # evolution evolImageData = vtk.vtkImageData() # perform the initialization initImageData.DeepCopy(self.logic.performInitialization(inputImage, self.thresholdSlider.minimumValue, self.thresholdSlider.maximumValue, seeds, stoppers, 'collidingfronts')) if not initImageData.GetPointData().GetScalars(): # something went wrong, the image is empty logging.error("Segmentation failed - the output was empty..") return False # check if it is a preview call if preview: # if this is a preview call, we want to skip the evolution evolImageData.DeepCopy(initImageData) else: # no preview, run the whole thing! we never use the vesselness node here, just the original one evolImageData.DeepCopy(self.logic.performEvolution(currentVolumeNode.GetImageData(), initImageData, self.iterationSpinBox.value, self.inflationSlider.value, self.curvatureSlider.value, self.attractionSlider.value, 'geodesic')) # create segmentation labelMap labelMap = vtk.vtkImageData() labelMap.DeepCopy(self.logic.buildSimpleLabelMap(evolImageData, 5, 0)) currentLabelMapNode.CopyOrientation(currentVolumeNode) # propagate the label map to the node currentLabelMapNode.SetAndObserveImageData(labelMap) # deactivate the threshold in the GUI self.resetThresholdOnDisplayNode() # self.onInputVolumeChanged() # show the segmentation results in the GUI selectionNode = slicer.app.applicationLogic().GetSelectionNode() # preview # currentVesselnessNode slicer.util.setSliceViewerLayers(background=currentVolumeNode, foreground=currentVesselnessNode, label=currentLabelMapNode, foregroundOpacity = 0.6 if preview else 0.1) # generate 3D model model = vtk.vtkPolyData() # we need the ijkToRas transform for the marching cubes call ijkToRasMatrix = vtk.vtkMatrix4x4() currentLabelMapNode.GetIJKToRASMatrix(ijkToRasMatrix) # call marching cubes model.DeepCopy(self.logic.marchingCubes(evolImageData, ijkToRasMatrix, 0.0)) # propagate model to nodes currentModelNode.SetAndObservePolyData(model) currentModelNode.CreateDefaultDisplayNodes() currentModelDisplayNode = currentModelNode.GetDisplayNode() # always configure the displayNode to show the model currentModelDisplayNode.SetColor(1.0, 0.55, 0.4) # red currentModelDisplayNode.SetBackfaceCulling(0) currentModelDisplayNode.SetSliceIntersectionVisibility(0) currentModelDisplayNode.SetVisibility(1) currentModelDisplayNode.SetOpacity(1.0) # fit slice to all sliceviewers slicer.app.applicationLogic().FitSliceToAll() # jump all sliceViewers to the first fiducial point, if one was used if currentSeedsNode: currentCoordinatesRAS = [0, 0, 0] if isinstance(currentSeedsNode, slicer.vtkMRMLMarkupsFiducialNode): # let's get the first children currentSeedsNode.GetNthFiducialPosition(0,currentCoordinatesRAS) numberOfSliceNodes = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLSliceNode') for n in xrange(numberOfSliceNodes): sliceNode = slicer.mrmlScene.GetNthNodeByClass(n, "vtkMRMLSliceNode") if sliceNode: sliceNode.JumpSliceByOffsetting(currentCoordinatesRAS[0], currentCoordinatesRAS[1], currentCoordinatesRAS[2]) # center 3D view(s) on the new model if currentCoordinatesRAS: for d in range(slicer.app.layoutManager().threeDViewCount): threeDView = slicer.app.layoutManager().threeDWidget(d).threeDView() # reset the focal point threeDView.resetFocalPoint() # and fly to our seed point interactor = threeDView.interactor() renderer = threeDView.renderWindow().GetRenderers().GetItemAsObject(0) interactor.FlyTo(renderer, currentCoordinatesRAS[0], currentCoordinatesRAS[1], currentCoordinatesRAS[2]) logging.debug("End of Level Set Segmentation..") return True
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()
def computeStatistics(self, segmentID): import vtkSegmentationCorePython as vtkSegmentationCore requestedKeys = self.getRequestedKeys() segmentationNode = slicer.mrmlScene.GetNodeByID( self.getParameterNode().GetParameter("Segmentation")) if len(requestedKeys) == 0: return {} containsLabelmapRepresentation = segmentationNode.GetSegmentation( ).ContainsRepresentation( vtkSegmentationCore.vtkSegmentationConverter. GetSegmentationBinaryLabelmapRepresentationName()) if not containsLabelmapRepresentation: return {} segmentLabelmap = slicer.vtkOrientedImageData() segmentationNode.GetBinaryLabelmapRepresentation( segmentID, segmentLabelmap) if (not segmentLabelmap or not segmentLabelmap.GetPointData() or not segmentLabelmap.GetPointData().GetScalars()): # No input label data return {} # We need to know exactly the value of the segment voxels, apply threshold to make force the selected label value labelValue = 1 backgroundValue = 0 thresh = vtk.vtkImageThreshold() thresh.SetInputData(segmentLabelmap) thresh.ThresholdByLower(0) thresh.SetInValue(backgroundValue) thresh.SetOutValue(labelValue) thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) thresh.Update() # Use binary labelmap as a stencil stencil = vtk.vtkImageToImageStencil() stencil.SetInputData(thresh.GetOutput()) stencil.ThresholdByUpper(labelValue) stencil.Update() stat = vtk.vtkImageAccumulate() stat.SetInputData(thresh.GetOutput()) stat.SetStencilData(stencil.GetOutput()) stat.Update() # Add data to statistics list cubicMMPerVoxel = reduce(lambda x, y: x * y, segmentLabelmap.GetSpacing()) ccPerCubicMM = 0.001 stats = {} if "voxel_count" in requestedKeys: stats["voxel_count"] = stat.GetVoxelCount() if "volume_mm3" in requestedKeys: stats["volume_mm3"] = stat.GetVoxelCount() * cubicMMPerVoxel if "volume_cm3" in requestedKeys: stats["volume_cm3"] = stat.GetVoxelCount( ) * cubicMMPerVoxel * ccPerCubicMM calculateShapeStats = False for shapeKey in self.shapeKeys: if shapeKey in requestedKeys: calculateShapeStats = True break if calculateShapeStats: directions = vtk.vtkMatrix4x4() segmentLabelmap.GetDirectionMatrix(directions) # Remove oriented bounding box from requested keys and replace with individual keys requestedOptions = requestedKeys statFilterOptions = self.shapeKeys calculateOBB = ("obb_diameter_mm" in requestedKeys or "obb_origin_ras" in requestedKeys or "obb_direction_ras_x" in requestedKeys or "obb_direction_ras_y" in requestedKeys or "obb_direction_ras_z" in requestedKeys) if calculateOBB: temp = statFilterOptions statFilterOptions = [] for option in temp: if not option in self.obbKeys: statFilterOptions.append(option) statFilterOptions.append("oriented_bounding_box") temp = requestedOptions requestedOptions = [] for option in temp: if not option in self.obbKeys: requestedOptions.append(option) requestedOptions.append("oriented_bounding_box") shapeStat = vtkITK.vtkITKLabelShapeStatistics() shapeStat.SetInputData(thresh.GetOutput()) shapeStat.SetDirections(directions) for shapeKey in statFilterOptions: shapeStat.SetComputeShapeStatistic( self.keyToShapeStatisticNames[shapeKey], shapeKey in requestedOptions) shapeStat.Update() # If segmentation node is transformed, apply that transform to get RAS coordinates transformSegmentToRas = vtk.vtkGeneralTransform() slicer.vtkMRMLTransformNode.GetTransformBetweenNodes( segmentationNode.GetParentTransformNode(), None, transformSegmentToRas) statTable = shapeStat.GetOutput() if "centroid_ras" in requestedKeys: centroidRAS = [0, 0, 0] centroidArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["centroid_ras"]) centroid = centroidArray.GetTuple(0) transformSegmentToRas.TransformPoint(centroid, centroidRAS) stats["centroid_ras"] = centroidRAS if "roundness" in requestedKeys: roundnessArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["roundness"]) roundness = roundnessArray.GetTuple(0)[0] stats["roundness"] = roundness if "flatness" in requestedKeys: flatnessArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["flatness"]) flatness = flatnessArray.GetTuple(0)[0] stats["flatness"] = flatness if "feret_diameter_mm" in requestedKeys: feretDiameterArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["feret_diameter_mm"]) feretDiameter = feretDiameterArray.GetTuple(0)[0] stats["feret_diameter_mm"] = feretDiameter if "surface_area_mm2" in requestedKeys: perimeterArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["surface_area_mm2"]) perimeter = perimeterArray.GetTuple(0)[0] stats["surface_area_mm2"] = perimeter if "obb_origin_ras" in requestedKeys: obbOriginRAS = [0, 0, 0] obbOriginArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_origin_ras"]) obbOrigin = obbOriginArray.GetTuple(0) transformSegmentToRas.TransformPoint(obbOrigin, obbOriginRAS) stats["obb_origin_ras"] = obbOriginRAS if "obb_diameter_mm" in requestedKeys: obbDiameterArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_diameter_mm"]) obbDiameterMM = list(obbDiameterArray.GetTuple(0)) stats["obb_diameter_mm"] = obbDiameterMM if "obb_direction_ras_x" in requestedKeys: obbOriginArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_origin_ras"]) obbOrigin = obbOriginArray.GetTuple(0) obbDirectionXArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_direction_ras_x"]) obbDirectionX = list(obbDirectionXArray.GetTuple(0)) transformSegmentToRas.TransformVectorAtPoint( obbOrigin, obbDirectionX, obbDirectionX) stats["obb_direction_ras_x"] = obbDirectionX if "obb_direction_ras_y" in requestedKeys: obbOriginArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_origin_ras"]) obbOrigin = obbOriginArray.GetTuple(0) obbDirectionYArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_direction_ras_y"]) obbDirectionY = list(obbDirectionYArray.GetTuple(0)) transformSegmentToRas.TransformVectorAtPoint( obbOrigin, obbDirectionY, obbDirectionY) stats["obb_direction_ras_y"] = obbDirectionY if "obb_direction_ras_z" in requestedKeys: obbOriginArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_origin_ras"]) obbOrigin = obbOriginArray.GetTuple(0) obbDirectionZArray = statTable.GetColumnByName( self.keyToShapeStatisticNames["obb_direction_ras_z"]) obbDirectionZ = list(obbDirectionZArray.GetTuple(0)) transformSegmentToRas.TransformVectorAtPoint( obbOrigin, obbDirectionZ, obbDirectionZ) stats["obb_direction_ras_z"] = obbDirectionZ return stats
def main(): colors = vtk.vtkNamedColors() # dir = "/home/vishnusanjay/cmpt764/Final project/last_examples/objs" # onlyfiles = [f for f in listdir(dir) if isfile(join(dir, f))] # print(onlyfiles) counterrr = 0 onlyfiles = [] mtl_files = [] with open('/home/vishnusanjay/cmpt764/Final project/04256520.csv', 'rt', encoding="utf8") as f: reader = csv.reader(f) your_list = list(reader) list_arr = np.asarray(your_list) print(len(your_list)) print(list_arr[:, 2]) folder_list = [] for i in range(len(your_list)): if list_arr[i, 2].find("chair") != -1: print(list_arr[i, 0].split('.')[1]) folder_list.append(list_arr[i, 0].split('.')[1]) print(counterrr) print(onlyfiles) print(mtl_files) # exit(1) for i in range(len(onlyfiles)): global position position = -5 print(onlyfiles[i]) print(mtl_files[i]) # if onlyfiles[i].find("1a38407b3036795d19fb4103277a6b93") ==-1: # continue # file_name = join(dir,onlyfiles[i]) reader = vtk.vtkOBJReader() reader.SetFileName(onlyfiles[i]) # reader.SetFileNameMTL(mtl_files[i]) reader.Update() counter = 0 while (counter < 2): counter = counter + 1 print(position) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(reader.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(colors.GetColor3d("red")) # # Visualize camera = vtk.vtkCamera() camera.SetFocalPoint(0, 0, 0) camera.SetPosition(10, 0, 0) camera.SetViewUp(0, 1, 0) camera.SetPosition(20, 2, position) position = position + 10 leftVP = [0.0, 0.0, 0.5, 1.0] rightVP = [0.5, 0.0, 1.0, 1.0] renderer = vtk.vtkRenderer() # renderer.SetViewport(leftVP) renderer.SetActiveCamera(camera) renderWindow = vtk.vtkRenderWindow() renderWindow.SetWindowName("Polygon") renderWindow.AddRenderer(renderer) renderWindow.SetSize(512, 512) renderWindowInteractor = vtk.vtkRenderWindowInteractor() renderWindowInteractor.SetRenderWindow(renderWindow) renderer.AddActor(actor) renderer.SetBackground(255, 255, 255) renderWindow.Render() filter.SetInput(renderWindow) # filter.SetViewport(leftVP) filter.SetInputBufferTypeToZBuffer() # filter.Update() # filter.Modified() scale = vtk.vtkImageShiftScale() scale.SetOutputScalarTypeToUnsignedChar() scale.SetInputConnection(filter.GetOutputPort()) scale.SetShift(0) scale.SetScale(-255) scale2 = vtk.vtkImageShiftScale() scale2.SetOutputScalarTypeToUnsignedChar() scale2.SetInputConnection(scale.GetOutputPort()) scale2.SetShift(255) # depthMapper = vtk.vtkImageMapper() # depthMapper.SetInputConnection(scale.GetOutputPort()) # # depthMapper.SetColorLevel(1) # depthActor = vtk.vtkActor2D() # depthActor.SetMapper(depthMapper) # depthRenderer = vtk.vtkRenderer() # depthRenderer.SetViewport(rightVP) # depthRenderer.AddActor2D(depthActor) # depthRenderer.SetBackground(255,255,255) # renderWindow.AddRenderer(depthRenderer) # filter.Modified() # i=0 # while i <2 : # i = i+1 # filter.Modified() modelviewMatrix = renderWindow.GetRenderers().GetFirstRenderer( ).GetActiveCamera().GetModelViewTransformMatrix() projectionMatrix = vtk.vtkCamera().GetProjectionTransformMatrix( renderWindow.GetRenderers().GetFirstRenderer()) mvp = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(projectionMatrix, modelviewMatrix, mvp) temp = [0] * 16 # the matrix is 4x4 mvp.DeepCopy(temp, mvp) global matrix_iter matrix_iter = matrix_iter + 1 save_file = file_name = "/home/vishnusanjay/cmpt764/Final project/last_examples/depthimages/chair_" + str( matrix_iter) + ".p" pickle.dump(temp, open(save_file, "wb")) # imageWriter = vtk.vtkBMPWriter() # imageWriter.SetFileName("/home/vishnusanjay/cmpt764/Final project/last_examples/ChairBasic2/shortChair01.bmp") # imageWriter.SetInputConnection(scale.GetOutputPort()) # imageWriter.Write() # time.sleep(1) keyboard.press('r') keyboard.press('s') time.sleep(1) keyboard.press('q') # renderWindowInteractor.AddObserver('LeftButtonPressEvent', UpdateFilter) # renderWindowInteractor.AddObserver('RightButtonPressEvent', saveimg) renderWindowInteractor.AddObserver('KeyPressEvent', keypressCallback) # renderWindowInteractor.AddObserver("LeftButtonReleaseEvent", UpdateFilter) renderWindowInteractor.Initialize() renderWindowInteractor.Start()
arr = vtk.vtkDoubleArray() arr.SetNumberOfValues(16) arr.SetVoidArray(dummyT.GetMatrix().GetData(), 16, 4) npArr = vtk_to_numpy(arr) npArr = npArr.reshape((4, 4)) rot = npArr[:3, :3] mat = np.zeros((4, 4), dtype=np.float) mat[:3, :3] = rot mat[3, 3] = 1.0 tmp = vtk.vtkVector3d() vtk.vtkMath.Multiply3x3(rot, axes.GetOrigin(), tmp) mat[:3, 3] = np.array(planeWidget.GetCenter()) - np.array(tmp) # Construct 4x4 matrix tfm = vtk.vtkMatrix4x4() tfm.DeepCopy(mat.flatten().tolist()) tfm.Modified() tf = vtk.vtkTransform() tf.SetMatrix(tfm) tf.PostMultiply() tf.Update() # Apply the initial movement as a user transform axes.SetUserTransform(tf) axes.SetOrigin(planeWidget.GetCenter()) axes.Modified() renderer.AddActor(axes) renderWindow.Render()
def splitSegments(self, minimumSize=0, maxNumberOfSegments=0, split=True): """ minimumSize: if 0 then it means that all islands are kept, regardless of size maxNumberOfSegments: if 0 then it means that all islands are kept, regardless of how many """ # This can be a long operation - indicate it to the user qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) self.scriptedEffect.saveStateForUndo() # Get modifier labelmap selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap() castIn = vtk.vtkImageCast() castIn.SetInputData(selectedSegmentLabelmap) castIn.SetOutputScalarTypeToUnsignedInt() # Identify the islands in the inverted volume and # find the pixel that corresponds to the background islandMath = vtkITK.vtkITKIslandMath() islandMath.SetInputConnection(castIn.GetOutputPort()) islandMath.SetFullyConnected(False) islandMath.SetMinimumSize(minimumSize) islandMath.Update() # Create a separate image for the first (largest) island labelValue = 1 backgroundValue = 0 thresh = vtk.vtkImageThreshold() if split: thresh.ThresholdBetween(1, 1) else: if maxNumberOfSegments != 0: thresh.ThresholdBetween(1, maxNumberOfSegments) else: thresh.ThresholdByUpper(1) thresh.SetInputData(islandMath.GetOutput()) thresh.SetOutValue(backgroundValue) thresh.SetInValue(labelValue) thresh.SetOutputScalarType(selectedSegmentLabelmap.GetScalarType()) thresh.Update() # Create oriented image data from output import vtkSegmentationCorePython as vtkSegmentationCore largestIslandImage = slicer.vtkOrientedImageData() largestIslandImage.ShallowCopy(thresh.GetOutput()) selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4() selectedSegmentLabelmap.GetImageToWorldMatrix( selectedSegmentLabelmapImageToWorldMatrix) largestIslandImage.SetImageToWorldMatrix( selectedSegmentLabelmapImageToWorldMatrix) if split and (maxNumberOfSegments != 1): thresh2 = vtk.vtkImageThreshold() # 0 is background, 1 is largest island; we need label 2 and higher if maxNumberOfSegments != 0: thresh2.ThresholdBetween(2, maxNumberOfSegments) else: thresh2.ThresholdByUpper(2) thresh2.SetInputData(islandMath.GetOutput()) thresh2.SetOutValue(backgroundValue) thresh2.ReplaceInOff() thresh2.Update() islandCount = islandMath.GetNumberOfIslands() islandOrigCount = islandMath.GetOriginalNumberOfIslands() ignoredIslands = islandOrigCount - islandCount logging.info("%d islands created (%d ignored)" % (islandCount, ignoredIslands)) # Create oriented image data from output import vtkSegmentationCorePython as vtkSegmentationCore multiLabelImage = slicer.vtkOrientedImageData() multiLabelImage.DeepCopy(thresh2.GetOutput()) selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4() selectedSegmentLabelmap.GetImageToWorldMatrix( selectedSegmentLabelmapImageToWorldMatrix) multiLabelImage.SetGeometryFromImageToWorldMatrix( selectedSegmentLabelmapImageToWorldMatrix) # Import multi-label labelmap to segmentation segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() selectedSegmentID = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() selectedSegmentIndex = segmentationNode.GetSegmentation( ).GetSegmentIndex(selectedSegmentID) insertBeforeSegmentID = segmentationNode.GetSegmentation( ).GetNthSegmentID(selectedSegmentIndex + 1) selectedSegmentName = segmentationNode.GetSegmentation( ).GetSegment(selectedSegmentID).GetName() slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode( multiLabelImage, segmentationNode, selectedSegmentName + " -", insertBeforeSegmentID) self.scriptedEffect.modifySelectedSegmentByLabelmap( largestIslandImage, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet) qt.QApplication.restoreOverrideCursor()
def load(self, loadable): """Load the selection as a MultiVolume, if multivolume attribute is present """ mvNode = '' try: mvNode = loadable.multivolume except AttributeError: return None nFrames = int(mvNode.GetAttribute('MultiVolume.NumberOfFrames')) files = string.split(mvNode.GetAttribute('MultiVolume.FrameFileList'), ',') nFiles = len(files) filesPerFrame = nFiles / nFrames frames = [] baseName = loadable.name loadAsVolumeSequence = hasattr( loadable, 'loadAsVolumeSequence') and loadable.loadAsVolumeSequence if loadAsVolumeSequence: volumeSequenceNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSequenceNode", slicer.mrmlScene.GenerateUniqueName(baseName)) volumeSequenceNode.SetIndexName("") volumeSequenceNode.SetIndexUnit("") else: mvImage = vtk.vtkImageData() mvImageArray = None scalarVolumePlugin = slicer.modules.dicomPlugins[ 'DICOMScalarVolumePlugin']() instanceUIDs = "" for file in files: uid = slicer.dicomDatabase.fileValue(file, self.tags['instanceUID']) if uid == "": uid = "Unknown" instanceUIDs += uid + " " instanceUIDs = instanceUIDs[:-1] mvNode.SetAttribute("DICOM.instanceUIDs", instanceUIDs) progressbar = slicer.util.createProgressDialog( labelText="Loading " + baseName, value=0, maximum=nFrames, windowModality=qt.Qt.WindowModal) try: # read each frame into scalar volume for frameNumber in range(nFrames): progressbar.value = frameNumber slicer.app.processEvents() if progressbar.wasCanceled: break sNode = slicer.vtkMRMLVolumeArchetypeStorageNode() sNode.ResetFileNameList() frameFileList = files[frameNumber * filesPerFrame:(frameNumber + 1) * filesPerFrame] # sv plugin will sort the filenames by geometric order svLoadables = scalarVolumePlugin.examine([frameFileList]) if len(svLoadables) == 0: raise IOError("volume frame %d is invalid" % frameNumber) frame = scalarVolumePlugin.load(svLoadables[0]) if frame.GetImageData() == None: raise IOError("volume frame %d is invalid" % frameNumber) if loadAsVolumeSequence: # Load into volume sequence # volumeSequenceNode.SetDataNodeAtValue would deep-copy the volume frame. # To avoid memory reallocation, add an empty node and shallow-copy the contents # of the volume frame. # Create an empty volume node in the sequence node proxyVolume = slicer.mrmlScene.AddNewNodeByClass( frame.GetClassName()) indexValue = str(frameNumber) volumeSequenceNode.SetDataNodeAtValue( proxyVolume, indexValue) slicer.mrmlScene.RemoveNode(proxyVolume) # Update the data node shallowCopy = True volumeSequenceNode.UpdateDataNodeAtValue( frame, indexValue, shallowCopy) else: # Load into multi-volume if frameNumber == 0: frameImage = frame.GetImageData() frameExtent = frameImage.GetExtent() frameSize = frameExtent[1] * frameExtent[ 3] * frameExtent[5] mvImage.SetExtent(frameExtent) if vtk.VTK_MAJOR_VERSION <= 5: mvImage.SetNumberOfScalarComponents(nFrames) mvImage.SetScalarType( frame.GetImageData().GetScalarType()) mvImage.AllocateScalars() else: mvImage.AllocateScalars( frame.GetImageData().GetScalarType(), nFrames) mvImageArray = vtk.util.numpy_support.vtk_to_numpy( mvImage.GetPointData().GetScalars()) mvNode.SetScene(slicer.mrmlScene) mat = vtk.vtkMatrix4x4() frame.GetRASToIJKMatrix(mat) mvNode.SetRASToIJKMatrix(mat) frame.GetIJKToRASMatrix(mat) mvNode.SetIJKToRASMatrix(mat) frameImage = frame.GetImageData() frameImageArray = vtk.util.numpy_support.vtk_to_numpy( frameImage.GetPointData().GetScalars()) mvImageArray.T[frameNumber] = frameImageArray # Remove temporary volume node if frame.GetDisplayNode(): slicer.mrmlScene.RemoveNode(frame.GetDisplayNode()) if frame.GetStorageNode(): slicer.mrmlScene.RemoveNode(frame.GetStorageNode()) slicer.mrmlScene.RemoveNode(frame) if loadAsVolumeSequence: # Finalize volume sequence import # For user convenience, add a browser node and show the volume in the slice viewer. # Add browser node sequenceBrowserNode = slicer.mrmlScene.AddNewNodeByClass( 'vtkMRMLSequenceBrowserNode', slicer.mrmlScene.GenerateUniqueName(baseName + " browser")) sequenceBrowserNode.SetAndObserveMasterSequenceNodeID( volumeSequenceNode.GetID()) # If save changes are allowed then proxy nodes are updated using shallow copy, which is much # faster for images. Images are usually not modified, so the risk of accidentally modifying # data in the sequence is low. sequenceBrowserNode.SetSaveChanges(volumeSequenceNode, True) # Show frame number in proxy volume node name sequenceBrowserNode.SetOverwriteProxyName( volumeSequenceNode, True) # Automatically select the volume to display imageProxyVolumeNode = sequenceBrowserNode.GetProxyNode( volumeSequenceNode) appLogic = slicer.app.applicationLogic() selNode = appLogic.GetSelectionNode() selNode.SetReferenceActiveVolumeID( imageProxyVolumeNode.GetID()) appLogic.PropagateVolumeSelection() # Show sequence browser toolbar sequenceBrowserModule = slicer.modules.sequencebrowser if sequenceBrowserModule.autoShowToolBar: sequenceBrowserModule.setToolBarActiveBrowserNode( sequenceBrowserNode) sequenceBrowserModule.setToolBarVisible(True) else: # Finalize multi-volume import mvDisplayNode = slicer.mrmlScene.AddNewNodeByClass( 'vtkMRMLMultiVolumeDisplayNode') mvDisplayNode.SetDefaultColorMap() mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID()) mvNode.SetAndObserveImageData(mvImage) mvNode.SetNumberOfFrames(nFrames) mvNode.SetName(loadable.name) slicer.mrmlScene.AddNode(mvNode) # # automatically select the volume to display # appLogic = slicer.app.applicationLogic() selNode = appLogic.GetSelectionNode() selNode.SetReferenceActiveVolumeID(mvNode.GetID()) appLogic.PropagateVolumeSelection() # file list is no longer needed - remove the attribute mvNode.RemoveAttribute('MultiVolume.FrameFileList') except Exception as e: logging.error("Failed to read a multivolume: {0}".format( e.message)) import traceback traceback.print_exc() mvNode = None finally: progressbar.close() return mvNode
def main(): nx, ny, nz = get_program_parameters() colors = vtk.vtkNamedColors() angle = 0 r1 = 50 r2 = 30 centerX = 10.0 centerY = 5.0 points = vtk.vtkPoints() idx = 0 while angle <= 2.0 * vtk.vtkMath.Pi() + (vtk.vtkMath.Pi() / 60.0): points.InsertNextPoint(r1 * math.cos(angle) + centerX, r2 * math.sin(angle) + centerY, 0.0) angle = angle + (vtk.vtkMath.Pi() / 60.0) idx += 1 line = vtk.vtkPolyLine() line.GetPointIds().SetNumberOfIds(idx) for i in range(0, idx): line.GetPointIds().SetId(i, i) lines = vtk.vtkCellArray() lines.InsertNextCell(line) polyData = vtk.vtkPolyData() polyData.SetPoints(points) polyData.SetLines(lines) extrude = vtk.vtkLinearExtrusionFilter() extrude.SetInputData(polyData) extrude.SetExtrusionTypeToNormalExtrusion() extrude.SetVector(nx, ny, nz) extrude.Update() # Create an oriented arrow startPoint = [0.0] * 3 endPoint = [0.0] * 3 startPoint[0] = centerX startPoint[1] = centerY startPoint[2] = 0.0 endPoint[0] = startPoint[0] + extrude.GetVector()[0] endPoint[1] = startPoint[1] + extrude.GetVector()[1] endPoint[2] = startPoint[2] + extrude.GetVector()[2] # Compute a basis normalizedX = [0.0] * 3 normalizedY = [0.0] * 3 normalizedZ = [0.0] * 3 # The X axis is a vector from start to end vtk.vtkMath.Subtract(endPoint, startPoint, normalizedX) length = vtk.vtkMath.Norm(normalizedX) vtk.vtkMath.Normalize(normalizedX) # The Z axis is an arbitrary vector cross X arbitrary = [0.0] * 3 arbitrary[0] = vtk.vtkMath.Random(-10, 10) arbitrary[1] = vtk.vtkMath.Random(-10, 10) arbitrary[2] = vtk.vtkMath.Random(-10, 10) vtk.vtkMath.Cross(normalizedX, arbitrary, normalizedZ) vtk.vtkMath.Normalize(normalizedZ) # The Y axis is Z cross X vtk.vtkMath.Cross(normalizedZ, normalizedX, normalizedY) matrix = vtk.vtkMatrix4x4() # Create the direction cosine matrix matrix.Identity() for i in range(0, 3): matrix.SetElement(i, 0, normalizedX[i]) matrix.SetElement(i, 1, normalizedY[i]) matrix.SetElement(i, 2, normalizedZ[i]) # Apply the transforms transform = vtk.vtkTransform() transform.Translate(startPoint) transform.Concatenate(matrix) transform.Scale(length, length, length) arrowSource = vtk.vtkArrowSource() arrowSource.SetTipResolution(31) arrowSource.SetShaftResolution(21) # Transform the polydata transformPD = vtk.vtkTransformPolyDataFilter() transformPD.SetTransform(transform) transformPD.SetInputConnection(arrowSource.GetOutputPort()) # Create a mapper and actor for the arrow arrowMapper = vtk.vtkPolyDataMapper() arrowMapper.SetInputConnection(transformPD.GetOutputPort()) arrowActor = vtk.vtkActor() arrowActor.SetMapper(arrowMapper) arrowActor.GetProperty().SetColor(colors.GetColor3d("Tomato")) tubes = vtk.vtkTubeFilter() tubes.SetInputData(polyData) tubes.SetRadius(2.0) tubes.SetNumberOfSides(21) lineMapper = vtk.vtkPolyDataMapper() lineMapper.SetInputConnection(tubes.GetOutputPort()) lineActor = vtk.vtkActor() lineActor.SetMapper(lineMapper) lineActor.GetProperty().SetColor(colors.GetColor3d("Peacock")) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(extrude.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(colors.GetColor3d("Banana")) actor.GetProperty().SetOpacity(.7) ren = vtk.vtkRenderer() ren.SetBackground(colors.GetColor3d("SlateGray")) ren.AddActor(actor) ren.AddActor(lineActor) ren.AddActor(arrowActor) renWin = vtk.vtkRenderWindow() renWin.SetWindowName("Elliptical Cylinder Demo") renWin.AddRenderer(ren) renWin.SetSize(600, 600) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) style = vtk.vtkInteractorStyleTrackballCamera() iren.SetInteractorStyle(style) camera = vtk.vtkCamera() camera.SetPosition(0, 1, 0) camera.SetFocalPoint(0, 0, 0) camera.SetViewUp(0, 0, 1) camera.Azimuth(30) camera.Elevation(30) ren.SetActiveCamera(camera) ren.ResetCamera() ren.ResetCameraClippingRange() renWin.Render() iren.Start()
def createModels(self): self.deleteModels() self.labelScores = [] self.selectedLableList = [] if self.calcinationType == 0 and self.volumeNode and self.roiNode: #print 'in Heart Create Models' slicer.vtkSlicerCropVolumeLogic().CropVoxelBased(self.roiNode, self.volumeNode, self.croppedNode) croppedImage = sitk.ReadImage( sitkUtils.GetSlicerITKReadWriteAddress(self.croppedNode.GetName())) thresholdImage = sitk.BinaryThreshold(croppedImage,self.ThresholdMin, self.ThresholdMax, 1, 0) connectedCompImage =sitk.ConnectedComponent(thresholdImage, True) relabelImage =sitk.RelabelComponent(connectedCompImage) labelStatFilter =sitk.LabelStatisticsImageFilter() labelStatFilter.Execute(croppedImage, relabelImage) if relabelImage.GetPixelID() != sitk.sitkInt16: relabelImage = sitk.Cast( relabelImage, sitk.sitkInt16 ) sitk.WriteImage( relabelImage, sitkUtils.GetSlicerITKReadWriteAddress(self.labelsNode.GetName())) nLabels = labelStatFilter.GetNumberOfLabels() #print "Number of labels = ", nLabels self.totalScore = 0 count = 0 for n in range(0,nLabels): max = labelStatFilter.GetMaximum(n); size = labelStatFilter.GetCount(n) score = self.computeScore(max) if size*self.voxelVolume > self.MaximumLesionSize: continue if size*self.voxelVolume < self.MinimumLesionSize: nLabels = n+1 break #print "label = ", n, " max = ", max, " score = ", score, " voxels = ", size self.labelScores.append(score) self.selectedLableList.append(0) self.marchingCubes.SetInputData(self.labelsNode.GetImageData()) self.marchingCubes.SetValue(0, n) self.marchingCubes.Update() self.transformPolyData.SetInputData(self.marchingCubes.GetOutput()) mat = vtk.vtkMatrix4x4() self.labelsNode.GetIJKToRASMatrix(mat) trans = vtk.vtkTransform() trans.SetMatrix(mat) self.transformPolyData.SetTransform(trans) self.transformPolyData.Update() poly = vtk.vtkPolyData() poly.DeepCopy(self.transformPolyData.GetOutput()) modelNode = slicer.vtkMRMLModelNode() slicer.mrmlScene.AddNode(modelNode) dnode = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(dnode) modelNode.AddAndObserveDisplayNodeID(dnode.GetID()) modelNode.SetAndObservePolyData(poly) ct=slicer.mrmlScene.GetNodeByID('vtkMRMLColorTableNodeLabels') rgb = [0,0,0] ct.GetLookupTable().GetColor(count+1,rgb) dnode.SetColor(rgb) self.addLabel(count, rgb, score) self.modelNodes.append(modelNode) self.selectedLables[poly] = n count = count+1 #a = slicer.util.array(tn.GetID()) #sa = sitk.GetImageFromArray(a) self.scoreField.setText(self.totalScore) else: print "not implemented"
def addGrayscaleVolumeStatistics(self): import vtkSegmentationCorePython as vtkSegmentationCore containsLabelmapRepresentation = self.segmentationNode.GetSegmentation( ).ContainsRepresentation( vtkSegmentationCore.vtkSegmentationConverter. GetSegmentationBinaryLabelmapRepresentationName()) if not containsLabelmapRepresentation: return if self.grayscaleNode is None or self.grayscaleNode.GetImageData( ) is None: return # Get geometry of grayscale volume node as oriented image data referenceGeometry_Reference = vtkSegmentationCore.vtkOrientedImageData( ) # reference geometry in reference node coordinate system referenceGeometry_Reference.SetExtent( self.grayscaleNode.GetImageData().GetExtent()) ijkToRasMatrix = vtk.vtkMatrix4x4() self.grayscaleNode.GetIJKToRASMatrix(ijkToRasMatrix) referenceGeometry_Reference.SetGeometryFromImageToWorldMatrix( ijkToRasMatrix) # Get transform between grayscale volume and segmentation segmentationToReferenceGeometryTransform = vtk.vtkGeneralTransform() slicer.vtkMRMLTransformNode.GetTransformBetweenNodes( self.segmentationNode.GetParentTransformNode(), self.grayscaleNode.GetParentTransformNode(), segmentationToReferenceGeometryTransform) cubicMMPerVoxel = reduce(lambda x, y: x * y, referenceGeometry_Reference.GetSpacing()) ccPerCubicMM = 0.001 for segmentID in self.statistics["SegmentIDs"]: segment = self.segmentationNode.GetSegmentation().GetSegment( segmentID) segmentLabelmap = segment.GetRepresentation( vtkSegmentationCore.vtkSegmentationConverter. GetSegmentationBinaryLabelmapRepresentationName()) segmentLabelmap_Reference = vtkSegmentationCore.vtkOrientedImageData( ) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentLabelmap, referenceGeometry_Reference, segmentLabelmap_Reference, False, # nearest neighbor interpolation False, # no padding segmentationToReferenceGeometryTransform) # We need to know exactly the value of the segment voxels, apply threshold to make force the selected label value labelValue = 1 backgroundValue = 0 thresh = vtk.vtkImageThreshold() thresh.SetInputData(segmentLabelmap_Reference) thresh.ThresholdByLower(0) thresh.SetInValue(backgroundValue) thresh.SetOutValue(labelValue) thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) thresh.Update() # Use binary labelmap as a stencil stencil = vtk.vtkImageToImageStencil() stencil.SetInputData(thresh.GetOutput()) stencil.ThresholdByUpper(labelValue) stencil.Update() stat = vtk.vtkImageAccumulate() stat.SetInputData(self.grayscaleNode.GetImageData()) stat.SetStencilData(stencil.GetOutput()) stat.Update() # Add data to statistics list self.statistics[segmentID, "GS voxel count"] = stat.GetVoxelCount() self.statistics[ segmentID, "GS volume mm3"] = stat.GetVoxelCount() * cubicMMPerVoxel self.statistics[segmentID, "GS volume cc"] = stat.GetVoxelCount( ) * cubicMMPerVoxel * ccPerCubicMM if stat.GetVoxelCount() > 0: self.statistics[segmentID, "GS min"] = stat.GetMin()[0] self.statistics[segmentID, "GS max"] = stat.GetMax()[0] self.statistics[segmentID, "GS mean"] = stat.GetMean()[0] self.statistics[segmentID, "GS stdev"] = stat.GetStandardDeviation()[0]
def createMeshFromSegmentationCleaver(self, inputSegmentation, outputMeshNode, additionalParameters = None, removeBackgroundMesh = False, paddingRatio = 0.10): if additionalParameters is None: additionalParameters="--scale 0.2 --multiplier 2 --grading 5" self.abortRequested = False tempDir = self.createTempDirectory() self.addLog('Mesh generation using Cleaver is started in working directory: '+tempDir) inputParamsCleaver = [] # Write inputs qt.QDir().mkpath(tempDir) # Create temporary labelmap node. It will be used both for storing reference geometry # and resulting merged labelmap. labelmapVolumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode') parentTransformNode = inputSegmentation.GetParentTransformNode() labelmapVolumeNode.SetAndObserveTransformNodeID(parentTransformNode.GetID() if parentTransformNode else None) # Create binary labelmap representation using default parameters if not inputSegmentation.GetSegmentation().CreateRepresentation(slicer.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName()): self.addLog('Failed to create binary labelmap representation') return # Set reference geometry in labelmapVolumeNode referenceGeometry_Segmentation = slicer.vtkOrientedImageData() inputSegmentation.GetSegmentation().SetImageGeometryFromCommonLabelmapGeometry(referenceGeometry_Segmentation, None, slicer.vtkSegmentation.EXTENT_REFERENCE_GEOMETRY) slicer.modules.segmentations.logic().CopyOrientedImageDataToVolumeNode(referenceGeometry_Segmentation, labelmapVolumeNode) # Add margin extent = labelmapVolumeNode.GetImageData().GetExtent() paddedExtent = [0, -1, 0, -1, 0, -1] for axisIndex in range(3): paddingSizeVoxels = int((extent[axisIndex * 2 + 1] - extent[axisIndex * 2]) * paddingRatio) paddedExtent[axisIndex * 2] = extent[axisIndex * 2] - paddingSizeVoxels paddedExtent[axisIndex * 2 + 1] = extent[axisIndex * 2 + 1] + paddingSizeVoxels labelmapVolumeNode.GetImageData().SetExtent(paddedExtent) labelmapVolumeNode.ShiftImageDataExtentToZeroStart() # Get merged labelmap segmentIdList = vtk.vtkStringArray() slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode(inputSegmentation, segmentIdList, labelmapVolumeNode, labelmapVolumeNode) inputLabelmapVolumeFilePath = os.path.join(tempDir, "inputLabelmap.nrrd") slicer.util.saveNode(labelmapVolumeNode, inputLabelmapVolumeFilePath, {"useCompression": False}) inputParamsCleaver.extend(["--input_files", inputLabelmapVolumeFilePath]) inputParamsCleaver.append("--segmentation") # Keep IJK to RAS matrix, we'll need it later unscaledIjkToRasMatrix = vtk.vtkMatrix4x4() labelmapVolumeNode.GetIJKToRASDirectionMatrix(unscaledIjkToRasMatrix) origin = labelmapVolumeNode.GetOrigin() for i in range(3): unscaledIjkToRasMatrix.SetElement(i,3, origin[i]) # Keep color node, we'll need it later colorTableNode = labelmapVolumeNode.GetDisplayNode().GetColorNode() # Background color is transparent by default which is not ideal for 3D display colorTableNode.SetColor(0,0.6,0.6,0.6,1.0) slicer.mrmlScene.RemoveNode(labelmapVolumeNode) slicer.mrmlScene.RemoveNode(colorTableNode) # Set up output format inputParamsCleaver.extend(["--output_path", tempDir+"/"]) inputParamsCleaver.extend(["--output_format", "vtkUSG"]) # VTK unstructed grid inputParamsCleaver.append("--fix_tet_windup") # prevent inside-out tets inputParamsCleaver.append("--strip_exterior") # remove temporary elements that are added to make the volume cubic inputParamsCleaver.append("--verbose") # Quality inputParamsCleaver.extend(slicer.util.toVTKString(additionalParameters).split(' ')) # Run Cleaver ep = self.startMesher(inputParamsCleaver, self.getCleaverPath()) self.logProcessOutput(ep, self.cleaverFilename) # Read results if not self.abortRequested: outputVolumetricMeshPath = os.path.join(tempDir, "output.vtk") outputReader = vtk.vtkUnstructuredGridReader() outputReader.SetFileName(outputVolumetricMeshPath) outputReader.ReadAllScalarsOn() outputReader.ReadAllVectorsOn() outputReader.ReadAllNormalsOn() outputReader.ReadAllTensorsOn() outputReader.ReadAllColorScalarsOn() outputReader.ReadAllTCoordsOn() outputReader.ReadAllFieldsOn() outputReader.Update() # Cleaver returns the mesh in voxel coordinates, need to transform to RAS space transformer = vtk.vtkTransformFilter() transformer.SetInputData(outputReader.GetOutput()) ijkToRasTransform = vtk.vtkTransform() ijkToRasTransform.SetMatrix(unscaledIjkToRasMatrix) transformer.SetTransform(ijkToRasTransform) if removeBackgroundMesh: transformer.Update() mesh = transformer.GetOutput() cellData = mesh.GetCellData() cellData.SetActiveScalars("labels") backgroundMeshRemover = vtk.vtkThreshold() backgroundMeshRemover.SetInputData(mesh) backgroundMeshRemover.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, vtk.vtkDataSetAttributes.SCALARS) backgroundMeshRemover.ThresholdByUpper(1) outputMeshNode.SetUnstructuredGridConnection(backgroundMeshRemover.GetOutputPort()) else: outputMeshNode.SetUnstructuredGridConnection(transformer.GetOutputPort()) outputMeshDisplayNode = outputMeshNode.GetDisplayNode() if not outputMeshDisplayNode: # Initial setup of display node outputMeshNode.CreateDefaultDisplayNodes() outputMeshDisplayNode = outputMeshNode.GetDisplayNode() outputMeshDisplayNode.SetEdgeVisibility(True) outputMeshDisplayNode.SetClipping(True) colorTableNode = slicer.mrmlScene.AddNode(colorTableNode) outputMeshDisplayNode.SetAndObserveColorNodeID(colorTableNode.GetID()) outputMeshDisplayNode.ScalarVisibilityOn() outputMeshDisplayNode.SetActiveScalarName('labels') outputMeshDisplayNode.SetActiveAttributeLocation(vtk.vtkAssignAttribute.CELL_DATA) outputMeshDisplayNode.SetSliceIntersectionVisibility(True) outputMeshDisplayNode.SetSliceIntersectionOpacity(0.5) outputMeshDisplayNode.SetScalarRangeFlag(slicer.vtkMRMLDisplayNode.UseColorNodeScalarRange) else: currentColorNode = outputMeshDisplayNode.GetColorNode() if currentColorNode is not None and currentColorNode.GetType() == currentColorNode.User and currentColorNode.IsA("vtkMRMLColorTableNode"): # current color table node can be overwritten currentColorNode.Copy(colorTableNode) else: colorTableNode = slicer.mrmlScene.AddNode(colorTableNode) outputMeshDisplayNode.SetAndObserveColorNodeID(colorTableNode.GetID()) # Flip clipping setting twice, this workaround forces update of the display pipeline # when switching between surface and volumetric mesh outputMeshDisplayNode.SetClipping(not outputMeshDisplayNode.GetClipping()) outputMeshDisplayNode.SetClipping(not outputMeshDisplayNode.GetClipping()) # Clean up if self.deleteTemporaryFiles: import shutil shutil.rmtree(tempDir) self.addLog("Model generation is completed")
def test_arrayFromTransformMatrix(self): # Test arrayFromTransformMatrix and updateTransformMatrixFromArray import numpy as np self.delayDisplay('Test arrayFromTransformMatrix') transformNode = slicer.mrmlScene.AddNewNodeByClass( 'vtkMRMLTransformNode') transformMatrix = vtk.vtkMatrix4x4() transformMatrix.SetElement(0, 0, 5.0) transformMatrix.SetElement(0, 1, 3.0) transformMatrix.SetElement(1, 1, 2.3) transformMatrix.SetElement(2, 2, 1.3) transformMatrix.SetElement(0, 3, 11.0) transformMatrix.SetElement(1, 3, 22.0) transformMatrix.SetElement(2, 3, 44.0) transformNode.SetMatrixTransformToParent(transformMatrix) narray = slicer.util.arrayFromTransformMatrix(transformNode) self.assertEqual(narray.shape, (4, 4)) self.assertEqual(narray[0, 0], 5.0) self.assertEqual(narray[0, 1], 3.0) self.assertEqual(narray[0, 3], 11.0) self.assertEqual(narray[2, 3], 44.0) self.delayDisplay('Test arrayFromTransformMatrix with toWorld=True') parentTransformNode = slicer.mrmlScene.AddNewNodeByClass( 'vtkMRMLTransformNode') parentTransformMatrix = vtk.vtkMatrix4x4() parentTransformMatrix.SetElement(1, 1, 0.3) parentTransformMatrix.SetElement(0, 3, 30.0) parentTransformMatrix.SetElement(1, 3, 20.0) parentTransformMatrix.SetElement(2, 3, 10.0) parentTransformNode.SetMatrixTransformToParent(parentTransformMatrix) narrayParent = slicer.util.arrayFromTransformMatrix( parentTransformNode) transformNode.SetAndObserveTransformNodeID(parentTransformNode.GetID()) narrayToWorld = slicer.util.arrayFromTransformMatrix(transformNode, toWorld=True) narrayToWorldExpected = np.dot(narrayParent, narray) np.testing.assert_array_equal(narrayToWorld, narrayToWorldExpected) self.delayDisplay('Test updateTransformMatrixFromArray') narrayUpdated = np.array([[1.5, 0.5, 0, 4], [0, 2.0, 0, 11], [0, 0, 2.5, 6], [0, 0, 0, 1]]) slicer.util.updateTransformMatrixFromArray(transformNode, narrayUpdated) transformMatrixUpdated = vtk.vtkMatrix4x4() transformNode.GetMatrixTransformToParent(transformMatrixUpdated) for r in range(4): for c in range(4): self.assertEqual(narrayUpdated[r, c], transformMatrixUpdated.GetElement(r, c)) self.delayDisplay( 'Test updateTransformMatrixFromArray with toWorld=True') narrayUpdated = np.array([[2.5, 1.5, 0, 2], [0, 2.0, 0, 15], [0, 1, 3.5, 6], [0, 0, 0, 1]]) slicer.util.updateTransformMatrixFromArray(transformNode, narrayUpdated, toWorld=True) transformMatrixUpdated = vtk.vtkMatrix4x4() transformNode.GetMatrixTransformToWorld(transformMatrixUpdated) for r in range(4): for c in range(4): self.assertEqual(narrayUpdated[r, c], transformMatrixUpdated.GetElement(r, c))
def main(): colors = vtk.vtkNamedColors() # Set the background color. colors.SetColor('BkgColor', [26, 51, 77, 255]) # Create an arrow. arrowSource = vtk.vtkArrowSource() # Generate a random start and end point startPoint = [0] * 3 endPoint = [0] * 3 rng = vtk.vtkMinimalStandardRandomSequence() rng.SetSeed(8775070) # For testing. for i in range(0, 3): rng.Next() startPoint[i] = rng.GetRangeValue(-10, 10) rng.Next() endPoint[i] = rng.GetRangeValue(-10, 10) # Compute a basis normalizedX = [0] * 3 normalizedY = [0] * 3 normalizedZ = [0] * 3 # The X axis is a vector from start to end vtk.vtkMath.Subtract(endPoint, startPoint, normalizedX) length = vtk.vtkMath.Norm(normalizedX) vtk.vtkMath.Normalize(normalizedX) # The Z axis is an arbitrary vector cross X arbitrary = [0] * 3 for i in range(0, 3): rng.Next() arbitrary[i] = rng.GetRangeValue(-10, 10) vtk.vtkMath.Cross(normalizedX, arbitrary, normalizedZ) vtk.vtkMath.Normalize(normalizedZ) # The Y axis is Z cross X vtk.vtkMath.Cross(normalizedZ, normalizedX, normalizedY) matrix = vtk.vtkMatrix4x4() # Create the direction cosine matrix matrix.Identity() for i in range(0, 3): matrix.SetElement(i, 0, normalizedX[i]) matrix.SetElement(i, 1, normalizedY[i]) matrix.SetElement(i, 2, normalizedZ[i]) # Apply the transforms transform = vtk.vtkTransform() transform.Translate(startPoint) transform.Concatenate(matrix) transform.Scale(length, length, length) # Transform the polydata transformPD = vtk.vtkTransformPolyDataFilter() transformPD.SetTransform(transform) transformPD.SetInputConnection(arrowSource.GetOutputPort()) # Create a mapper and actor for the arrow mapper = vtk.vtkPolyDataMapper() actor = vtk.vtkActor() if USER_MATRIX: mapper.SetInputConnection(arrowSource.GetOutputPort()) actor.SetUserMatrix(transform.GetMatrix()) else: mapper.SetInputConnection(transformPD.GetOutputPort()) actor.SetMapper(mapper) actor.GetProperty().SetColor(colors.GetColor3d('Cyan')) # Create spheres for start and end point sphereStartSource = vtk.vtkSphereSource() sphereStartSource.SetCenter(startPoint) sphereStartSource.SetRadius(0.8) sphereStartMapper = vtk.vtkPolyDataMapper() sphereStartMapper.SetInputConnection(sphereStartSource.GetOutputPort()) sphereStart = vtk.vtkActor() sphereStart.SetMapper(sphereStartMapper) sphereStart.GetProperty().SetColor(colors.GetColor3d('Yellow')) sphereEndSource = vtk.vtkSphereSource() sphereEndSource.SetCenter(endPoint) sphereEndSource.SetRadius(0.8) sphereEndMapper = vtk.vtkPolyDataMapper() sphereEndMapper.SetInputConnection(sphereEndSource.GetOutputPort()) sphereEnd = vtk.vtkActor() sphereEnd.SetMapper(sphereEndMapper) sphereEnd.GetProperty().SetColor(colors.GetColor3d('Magenta')) # Create a renderer, render window, and interactor renderer = vtk.vtkRenderer() renderWindow = vtk.vtkRenderWindow() renderWindow.SetWindowName('OrientedArrow') renderWindow.AddRenderer(renderer) renderWindowInteractor = vtk.vtkRenderWindowInteractor() renderWindowInteractor.SetRenderWindow(renderWindow) # Add the actor to the scene renderer.AddActor(actor) renderer.AddActor(sphereStart) renderer.AddActor(sphereEnd) renderer.SetBackground(colors.GetColor3d('BkgColor')) # Render and interact renderWindow.Render() renderWindowInteractor.Start()
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 readFilesToDicomArray(path, listOfSeries): listOfDicomArrays = [] listOfPixelDims = [] listOfPixelSpacings = [] listOfPlaneShapes = [] listOfMaxCounts = [] listOfMatrices = [] dictFilesDCM = {} for series in listOfSeries: # für jeden Ordner for dirName, subdirList, fileList in os.walk(path + series): for filename in fileList: if ".dcm" in filename.lower(): actDs = dicom.read_file(os.path.join(dirName, filename)) pos = "{}{}".format(actDs.ImagePositionPatient, actDs.ImageOrientationPatient) if (pos not in dictFilesDCM): dictFilesDCM[pos] = {} dictFilesDCM[pos][actDs.InstanceNumber] = os.path.join(dirName, filename) minDiffAtPos = -1 minDiff = float('Inf') timeVectors = [] for actPos, actDict in dictFilesDCM.items(): # für jede Slice sortEntries = sorted(actDict) actTimeVector = [] timeVectors.append(actTimeVector) first = True actIndex = 0 for actFile in sortEntries: # für jedes einzelne Bild actDicom = dicom.read_file(actDict[actFile]) if first: # organisiere Metadaten + ArrayDicom anlegen first = False winCen = actDicom.WindowCenter winWidth = actDicom.WindowWidth resIntercept = actDicom.RescaleIntercept resSlope = actDicom.RescaleSlope ConstPixelDims = (len(sortEntries), int(actDicom.Rows), int(actDicom.Columns)) planeShape = (int(actDicom.Rows), int(actDicom.Columns), 1) ConstPixelSpacing = (float(actDicom.PixelSpacing[0]), float(actDicom.PixelSpacing[1]), float(actDicom.SliceThickness)) position = actDicom.ImagePositionPatient orientation = actDicom.ImageOrientationPatient xdir = orientation[0:3] ydir = orientation[3:6] zdir = [0.0, 0.0, 0.0] vtk.vtkMath.Cross(xdir, ydir, zdir) matrix = vtk.vtkMatrix4x4() for i in range(3): matrix.SetElement(i, 0, xdir[i]) matrix.SetElement(i, 1, ydir[i]) matrix.SetElement(i, 2, zdir[i]) matrix.SetElement(i, 3, position[i]) ArrayDicom = np.zeros(ConstPixelDims, dtype = float) actTimeVector.append(int(actDicom.TriggerTime)) ArrayDicom[actIndex, :, :] = actDicom.pixel_array actIndex += 1 np.clip(resSlope * diffValGr / (winWidth - 1) * ArrayDicom + ((resIntercept - winCen) / (winWidth - 1) + 0.5) * diffValGr + minValGr, minValGr, maxValGr, out = ArrayDicom) listOfMaxCounts.append(len(sortEntries)) listOfDicomArrays.append(ArrayDicom) listOfPixelDims.append(ConstPixelDims) listOfPixelSpacings.append(ConstPixelSpacing) listOfPlaneShapes.append(planeShape) listOfMatrices.append(matrix) for i in range(len(timeVectors)): actTimeVector = timeVectors[i] factor = 800.0 / actTimeVector[-1] for j in range(len(actTimeVector)): actTimeVector[j] = int(factor * actTimeVector[j]) if len(actTimeVector) > 0: tempDiff = actTimeVector[1] - actTimeVector[0] if tempDiff < minDiff: minDiff = tempDiff minDiffAtPos = i return (listOfDicomArrays, listOfPixelDims, listOfPixelSpacings, listOfPlaneShapes, listOfMaxCounts, listOfMatrices, minDiffAtPos, timeVectors)
class CommunicationHandler: isRunning = False id = vtk.vtkMatrix4x4() def __init__(self): self.context = zmq.Context() self.PUB = self.context.socket(zmq.PUB) self.PUB.bind("tcp://*:5555") self.SUB = self.context.socket(zmq.SUB) self.SUB.bind("tcp://*:5556") self.SUB.setsockopt_string(zmq.SUBSCRIBE, np.unicode('')) self.REP = self.context.socket(zmq.REP) self.REP.bind("tcp://*:5557") self.run() logging.info('Connection establihed') self.id.Identity() cube = vtk.vtkCubeSource() centerPointCoord = [0.0, 0.0, 0.0] cube.SetCenter(centerPointCoord) cube.SetXLength(20) cube.SetYLength(5) cube.SetZLength(10) cube.Update() modelsLogic = slicer.modules.models.logic() model = modelsLogic.AddModel(cube.GetOutput()) model.GetDisplayNode().SetSliceIntersectionVisibility(True) model.GetDisplayNode().SetSliceIntersectionThickness(3) model.GetDisplayNode().SetColor(1, 0, 0) def stop(self): self.isRunning = False self.PUB.close() self.SUB.close() self.REP.close() self.context.destroy() def running(self): return self.isRunning def run(self): self.isRunning = True if self.isRunning: self.PUB.send_string("SlicerData") try: msg = self.SUB.recv(zmq.DONTWAIT) transform = np.frombuffer(msg, dtype=np.float32) transform = transform.reshape((4, 4)) mtx = vtk.vtkMatrix4x4() mtx.DeepCopy(transform.ravel()) node = slicer.mrmlScene.GetNodesByName("Model") node = node.GetItemAsObject(0) node.ApplyTransformMatrix(self.id) node.ApplyTransformMatrix(mtx) self.id = mtx self.id.Invert() except zmq.Again: pass try: msg2 = self.REP.recv(zmq.DONTWAIT) if msg2 == "volume": volume = np.random.rand(320, 240, 200) volume = volume.astype(np.float32) dim = volume.shape dimL = len(dim) b = struct.pack('=%ii' % dimL, *dim) data = b + volume.tobytes() reply = "/Users/thomas/Documents/tmpdata" f = open(reply, "w") f.write(data) f.close() else: reply = "reply" self.REP.send_string(reply) except zmq.Again: pass qt.QTimer.singleShot(16, self.run)
camera.SetPosition(0, 0, 0) camera.SetFocalPoint(0, 0, 1) camera.SetViewUp(0, 1, 0) camera.SetClippingRange(depth_min, depth_max) camera.SetWindowCenter(window_center_x, window_center_y) camera.SetViewAngle(view_angle) scene_renderer.SetActiveCamera(camera) render_window.Render() render_window_interactor.Initialize() render_window.SetDeviceIndex(0) render_window.SetDesiredUpdateRate(60) render_window.SetSize(1280, 720) fiber_RT = vtk.vtkMatrix4x4() operator_RT = vtk.vtkMatrix4x4() bgr = BackGroundRefresh() bgr.image_actor = image_actor bgr.actor = Operator_actor bgr.camera = camera bgr.frame = frame bgr.organ_actor = organ_actor bgr.sephere_actor = sephere_actor bgr.navigation_information = navigation_information bgr.navigation_text = Navigation_Text bgr.fiber_RT = fiber_RT bgr.operator_RT = operator_RT render_window_interactor.AddObserver('TimerEvent', bgr.execute) render_window_interactor.CreateRepeatingTimer(1)
def convertMatrixToVTK(self, matrix): matrix_vtk = vtk.vtkMatrix4x4() for i in range(4): for j in range(4): matrix_vtk.SetElement(i, j, matrix[i][j]) return matrix_vtk
def TestSection_03_qMRMLSegmentationGeometryWidget(self): logging.info('Test section 2: qMRMLSegmentationGeometryWidget') import vtkSegmentationCore binaryLabelmapReprName = vtkSegmentationCore.vtkSegmentationConverter.GetBinaryLabelmapRepresentationName( ) closedSurfaceReprName = vtkSegmentationCore.vtkSegmentationConverter.GetClosedSurfaceRepresentationName( ) # Use MRHead and Tinypatient for testing import SampleData mrVolumeNode = SampleData.downloadSample("MRHead") [tinyVolumeNode, tinySegmentationNode] = SampleData.downloadSamples('TinyPatient') # Convert MRHead to oriented image data import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic mrOrientedImageData = vtkSlicerSegmentationsModuleLogic.vtkSlicerSegmentationsModuleLogic.CreateOrientedImageDataFromVolumeNode( mrVolumeNode) mrOrientedImageData.UnRegister(None) # Create segmentation node with binary labelmap master and one segment with MRHead geometry segmentationNode = slicer.mrmlScene.AddNewNodeByClass( 'vtkMRMLSegmentationNode') segmentationNode.GetSegmentation().SetMasterRepresentationName( binaryLabelmapReprName) geometryStr = vtkSegmentationCore.vtkSegmentationConverter.SerializeImageGeometry( mrOrientedImageData) segmentationNode.GetSegmentation().SetConversionParameter( vtkSegmentationCore.vtkSegmentationConverter. GetReferenceImageGeometryParameterName(), geometryStr) threshold = vtk.vtkImageThreshold() threshold.SetInputData(mrOrientedImageData) threshold.ThresholdByUpper(16.0) threshold.SetInValue(1) threshold.SetOutValue(0) threshold.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) threshold.Update() segmentOrientedImageData = vtkSegmentationCore.vtkOrientedImageData() segmentOrientedImageData.DeepCopy(threshold.GetOutput()) mrImageToWorldMatrix = vtk.vtkMatrix4x4() mrOrientedImageData.GetImageToWorldMatrix(mrImageToWorldMatrix) segmentOrientedImageData.SetImageToWorldMatrix(mrImageToWorldMatrix) segment = vtkSegmentationCore.vtkSegment() segment.SetName('Brain') segment.SetColor(0.0, 0.0, 1.0) segment.AddRepresentation(binaryLabelmapReprName, segmentOrientedImageData) segmentationNode.GetSegmentation().AddSegment(segment) # Create geometry widget geometryWidget = slicer.qMRMLSegmentationGeometryWidget() geometryWidget.setSegmentationNode(segmentationNode) geometryWidget.editEnabled = True geometryImageData = vtkSegmentationCore.vtkOrientedImageData( ) # To contain the output later # Volume source with no transforms geometryWidget.setSourceNode(tinyVolumeNode) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (49, 49, 23), (248.8439, 248.2890, -123.75), [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 92) # Transformed volume source translationTransformMatrix = vtk.vtkMatrix4x4() translationTransformMatrix.SetElement(0, 3, 24.5) translationTransformMatrix.SetElement(1, 3, 24.5) translationTransformMatrix.SetElement(2, 3, 11.5) translationTransformNode = slicer.vtkMRMLLinearTransformNode() translationTransformNode.SetName('TestTranslation') slicer.mrmlScene.AddNode(translationTransformNode) translationTransformNode.SetMatrixTransformToParent( translationTransformMatrix) tinyVolumeNode.SetAndObserveTransformNodeID( translationTransformNode.GetID()) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (49, 49, 23), (224.3439, 223.7890, -135.25), [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 94) # Volume source with isotropic spacing tinyVolumeNode.SetAndObserveTransformNodeID(None) geometryWidget.setIsotropicSpacing(True) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (23, 23, 23), (248.8439, 248.2890, -123.75), [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 414) # Volume source with oversampling geometryWidget.setIsotropicSpacing(False) geometryWidget.setOversamplingFactor(2.0) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (24.5, 24.5, 11.5), (261.0939, 260.5390, -129.5), [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 751) slicer.util.delayDisplay('Volume source cases - OK') # Segmentation source with binary labelmap master geometryWidget.setOversamplingFactor(1.0) geometryWidget.setSourceNode(tinySegmentationNode) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (49, 49, 23), (248.8439, 248.2890, -123.75), [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 92) # Segmentation source with closed surface master tinySegmentationNode.GetSegmentation().SetConversionParameter( 'Smoothing factor', '0.0') self.assertTrue( tinySegmentationNode.GetSegmentation().CreateRepresentation( closedSurfaceReprName)) tinySegmentationNode.GetSegmentation().SetMasterRepresentationName( closedSurfaceReprName) tinySegmentationNode.Modified( ) # Trigger re-calculation of geometry (only generic Modified event is observed) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (1, 1, 1), (-167.156, -217.711, -135.75), [[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5223846) slicer.util.delayDisplay('Segmentation source cases - OK') # Model source with no transform shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode( slicer.mrmlScene) outputFolderId = shNode.CreateFolderItem(shNode.GetSceneItemID(), 'ModelsFolder') success = vtkSlicerSegmentationsModuleLogic.vtkSlicerSegmentationsModuleLogic.ExportVisibleSegmentsToModels( tinySegmentationNode, outputFolderId) self.assertTrue(success) modelNode = slicer.util.getNode('Body_Contour') geometryWidget.setSourceNode(modelNode) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (1, 1, 1), (-167.156, -217.711, -135.75), [[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5223846) # Transformed model source rotationTransform = vtk.vtkTransform() rotationTransform.RotateX(45) rotationTransformMatrix = vtk.vtkMatrix4x4() rotationTransform.GetMatrix(rotationTransformMatrix) rotationTransformNode = slicer.vtkMRMLLinearTransformNode() rotationTransformNode.SetName('TestRotation') slicer.mrmlScene.AddNode(rotationTransformNode) rotationTransformNode.SetMatrixTransformToParent( rotationTransformMatrix) modelNode.SetAndObserveTransformNodeID(rotationTransformNode.GetID()) modelNode.Modified() geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (1, 1, 1), (-167.156, -58.6623, -249.228), [[0.0, 0.0, 1.0], [-0.7071, -0.7071, 0.0], [0.7071, -0.7071, 0.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5221241) # ROI source roiNode = slicer.vtkMRMLAnnotationROINode() roiNode.SetName('SourceROI') slicer.mrmlScene.AddNode(roiNode) roiNode.UnRegister(None) xyz = [0] * 3 center = [0] * 3 slicer.vtkMRMLSliceLogic.GetVolumeRASBox(tinyVolumeNode, xyz, center) radius = [x / 2.0 for x in xyz] roiNode.SetXYZ(center) roiNode.SetRadiusXYZ(radius) geometryWidget.setSourceNode(roiNode) geometryWidget.geometryImageData(geometryImageData) self.assertTrue( self.compareOutputGeometry( geometryImageData, (1, 1, 1), (-216.156, -217.711, -135.75), [[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]])) vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage( segmentOrientedImageData, geometryImageData, geometryImageData, False, True) self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5223846) slicer.util.delayDisplay('Model and ROI source cases - OK') slicer.util.delayDisplay('Segmentation geometry widget test passed')
def makeMaskImage(self, polyData): """ Create a screen space (2D) mask image for the given polydata. Need to know the mapping from RAS into polygon space so the painter can use this as a mask - need the bounds in RAS space - need to get an IJKToRAS for just the mask area - directions are the XYToRAS for this slice - origin is the lower left of the polygon bounds - TODO: need to account for the boundary pixels Note: uses the slicer2-based vtkImageFillROI filter """ labelLogic = self.sliceLogic.GetLabelLayer() sliceNode = self.sliceLogic.GetSliceNode() maskIJKToRAS = vtk.vtkMatrix4x4() maskIJKToRAS.DeepCopy(sliceNode.GetXYToRAS()) polyData.GetPoints().Modified() bounds = polyData.GetBounds() xlo = bounds[0] - 1 xhi = bounds[1] ylo = bounds[2] - 1 yhi = bounds[3] originRAS = self.xyToRAS((xlo, ylo)) maskIJKToRAS.SetElement(0, 3, originRAS[0]) maskIJKToRAS.SetElement(1, 3, originRAS[1]) maskIJKToRAS.SetElement(2, 3, originRAS[2]) # # get a good size for the draw buffer # - needs to include the full region of the polygon # - plus a little extra # # round to int and add extra pixel for both sides # -- TODO: figure out why we need to add buffer pixels on each # side for the width in order to end up with a single extra # pixel in the rasterized image map. Probably has to # do with how boundary conditions are handled in the filler w = int(xhi - xlo) + 32 h = int(yhi - ylo) + 32 imageData = vtk.vtkImageData() imageData.SetDimensions(w, h, 1) labelNode = labelLogic.GetVolumeNode() if not labelNode: return labelImage = labelNode.GetImageData() if not labelImage: return imageData.AllocateScalars(labelImage.GetScalarType(), 1) # # move the points so the lower left corner of the # bounding box is at 1, 1 (to avoid clipping) # translate = vtk.vtkTransform() translate.Translate(-1. * xlo, -1. * ylo, 0) drawPoints = vtk.vtkPoints() drawPoints.Reset() translate.TransformPoints(polyData.GetPoints(), drawPoints) drawPoints.Modified() fill = slicer.vtkImageFillROI() fill.SetInputData(imageData) fill.SetValue(1) fill.SetPoints(drawPoints) fill.Update() mask = vtk.vtkImageData() mask.DeepCopy(fill.GetOutput()) return [maskIJKToRAS, mask]
def add_coord(endPos, color, ren): arrowSource = vtk.vtkArrowSource() arrowSource.SetShaftRadius(0.01) arrowSource.SetTipLength(0.1) arrowSource.SetTipRadius(0.03) startPoint = [0 for i in range(3)] startPoint[0] = 0 startPoint[1] = 0 startPoint[2] = 0 endPoint = [0 for i in range(3)] endPoint[0] = endPos[0] endPoint[1] = endPos[1] endPoint[2] = endPos[2] # Compute a basis normalizedX = [0 for i in range(3)] normalizedY = [0 for i in range(3)] normalizedZ = [0 for i in range(3)] # The X axis is a vector from start to end math = vtk.vtkMath() math.Subtract(endPoint, startPoint, normalizedX) length = math.Norm(normalizedX) math.Normalize(normalizedX) # The Z axis is an arbitrary vector cross X arbitrary = [0 for i in range(3)] arbitrary[0] = random.uniform(-10, 10) arbitrary[1] = random.uniform(-10, 10) arbitrary[2] = random.uniform(-10, 10) math.Cross(normalizedX, arbitrary, normalizedZ) math.Normalize(normalizedZ) # The Y axis is Z cross X math.Cross(normalizedZ, normalizedX, normalizedY) matrix = vtk.vtkMatrix4x4() # Create the direction cosine matrix matrix.Identity() for i in range(3): matrix.SetElement(i, 0, normalizedX[i]) matrix.SetElement(i, 1, normalizedY[i]) matrix.SetElement(i, 2, normalizedZ[i]) # Apply the transforms transform = vtk.vtkTransform() transform.Translate(startPoint) transform.Concatenate(matrix) transform.Scale(length, length, length) # Transform the polydata transformPD = vtk.vtkTransformPolyDataFilter() transformPD.SetTransform(transform) transformPD.SetInputConnection(arrowSource.GetOutputPort()) # Create a mapper and actor for the arrow mapper = vtk.vtkPolyDataMapper() actor = vtk.vtkActor() mapper.SetInputConnection(transformPD.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) ##alternatively to using the transform above one could use: actor.RotateZ etc and Scale actor.GetProperty().SetColor(color[0], color[1], color[2]) ren.AddActor(actor)
def processInteractionEvents(self, callerInteractor, eventId, viewWidget): import vtkSegmentationCorePython as vtkSegmentationCore abortEvent = False # Only allow in modes where segment selection is needed if not self.currentOperationRequiresSegmentSelection(): return False # Only allow for slice views if viewWidget.className() != "qMRMLSliceWidget": return abortEvent if eventId != vtk.vtkCommand.LeftButtonPressEvent: return abortEvent abortEvent = True # Generate merged labelmap of all visible segments segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() visibleSegmentIds = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs( visibleSegmentIds) if visibleSegmentIds.GetNumberOfValues() == 0: logging.info( "Smoothing operation skipped: there are no visible segments") return abortEvent self.scriptedEffect.saveStateForUndo() # This can be a long operation - indicate it to the user qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) operationName = self.scriptedEffect.parameter("Operation") if operationName == ADD_SELECTED_ISLAND: inputLabelImage = slicer.vtkOrientedImageData() if not segmentationNode.GenerateMergedLabelmapForAllSegments( inputLabelImage, vtkSegmentationCore.vtkSegmentation. EXTENT_UNION_OF_SEGMENTS_PADDED, None, visibleSegmentIds): logging.error( 'Failed to apply smoothing: cannot get list of visible segments' ) qt.QApplication.restoreOverrideCursor() return abortEvent else: selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap( ) # We need to know exactly the value of the segment voxels, apply threshold to make force the selected label value labelValue = 1 backgroundValue = 0 thresh = vtk.vtkImageThreshold() thresh.SetInputData(selectedSegmentLabelmap) thresh.ThresholdByLower(0) thresh.SetInValue(backgroundValue) thresh.SetOutValue(labelValue) thresh.SetOutputScalarType(selectedSegmentLabelmap.GetScalarType()) thresh.Update() # Create oriented image data from output import vtkSegmentationCorePython as vtkSegmentationCore inputLabelImage = slicer.vtkOrientedImageData() inputLabelImage.ShallowCopy(thresh.GetOutput()) selectedSegmentLabelmapImageToWorldMatrix = vtk.vtkMatrix4x4() selectedSegmentLabelmap.GetImageToWorldMatrix( selectedSegmentLabelmapImageToWorldMatrix) inputLabelImage.SetImageToWorldMatrix( selectedSegmentLabelmapImageToWorldMatrix) xy = callerInteractor.GetEventPosition() ijk = self.xyToIjk(xy, viewWidget, inputLabelImage) pixelValue = inputLabelImage.GetScalarComponentAsFloat( ijk[0], ijk[1], ijk[2], 0) try: floodFillingFilter = vtk.vtkImageThresholdConnectivity() floodFillingFilter.SetInputData(inputLabelImage) seedPoints = vtk.vtkPoints() origin = inputLabelImage.GetOrigin() spacing = inputLabelImage.GetSpacing() seedPoints.InsertNextPoint(origin[0] + ijk[0] * spacing[0], origin[1] + ijk[1] * spacing[1], origin[2] + ijk[2] * spacing[2]) floodFillingFilter.SetSeedPoints(seedPoints) floodFillingFilter.ThresholdBetween(pixelValue, pixelValue) if operationName == ADD_SELECTED_ISLAND: floodFillingFilter.SetInValue(1) floodFillingFilter.SetOutValue(0) floodFillingFilter.Update() modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap( ) modifierLabelmap.DeepCopy(floodFillingFilter.GetOutput()) self.scriptedEffect.modifySelectedSegmentByLabelmap( modifierLabelmap, slicer. qSlicerSegmentEditorAbstractEffect.ModificationModeAdd) elif pixelValue != 0: # if clicked on empty part then there is nothing to remove or keep if operationName == KEEP_SELECTED_ISLAND: floodFillingFilter.SetInValue(1) floodFillingFilter.SetOutValue(0) else: # operationName == REMOVE_SELECTED_ISLAND: floodFillingFilter.SetInValue(1) floodFillingFilter.SetOutValue(0) floodFillingFilter.Update() modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap( ) modifierLabelmap.DeepCopy(floodFillingFilter.GetOutput()) if operationName == KEEP_SELECTED_ISLAND: self.scriptedEffect.modifySelectedSegmentByLabelmap( modifierLabelmap, slicer. qSlicerSegmentEditorAbstractEffect.ModificationModeSet) else: # operationName == REMOVE_SELECTED_ISLAND: self.scriptedEffect.modifySelectedSegmentByLabelmap( modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect. ModificationModeRemove) except IndexError: logging.error('apply: Failed to threshold master volume!') finally: qt.QApplication.restoreOverrideCursor() return abortEvent
def get_matrix(self,data_reader,origin,normal,camera_normal): # do funkcji zostal dostarczony argument definiujacy polozenie kamery, #oddaje ten argument w Panskie rece, bo sam nie wiem za bardzo co z nim zrobic #podejrzewam tylko ,ze musi on stanowic wartosc poczatkowa i trzeba go odjac lub dodac w odpowiednim przypadku # Calculate the center of the volume data_reader.get_data_set().UpdateInformation() (self.xMin,self.xMax,self.yMin,self.yMax,self.zMin,self.zMax) = data_reader.get_whole_extent() (self.xSpacing,self.ySpacing,self.zSpacing) = data_reader.get_spacing() (self.x0,self.y0,self.z0) = data_reader.get_origin() self.center = [self.x0 + self.xSpacing * 0.5 * (self.xMin + self.xMax), self.y0 + self.ySpacing * 0.5 * (self.yMin + self.yMax), self.z0 + self.zSpacing * 0.5 * (self.zMin + self.zMax)] # print self.center #----------------------------- c="c" # TU jesli poda sie funkcji orgin postaci (c,c,c) to zrobi przeciecie przez srodek if origin[0]==c or origin[1]==c or origin[2]==c: origin=self.center origin=(float(origin[0]),float(origin[1]),float(origin[2])) self.axial = vtk.vtkMatrix4x4() if normal[0]=="p": # jesli poda sie funkcji normal postaci (p,*,*) to zrobi prostopadla do tej osi self.axial.DeepCopy((0,0,1,origin[0], 1,0,0,origin[1], 0,1,0,origin[2], 0,0,0,1)) elif normal[1]=="p": # jesli poda sie funkcji normal postaci (*,p,*) to zrobi prostopadla do tej osi self.axial.DeepCopy((0,1,0,origin[0], 0,0,1,origin[1], 1,0,0,origin[2], 0,0,0,1)) elif normal[2]=="p": # jesli poda sie funkcji normal postaci (*,*,p) to zrobi prostopadla do tej osi self.axial.DeepCopy((1,0,0,origin[0], 0,1,0,origin[1], 0,0,1,origin[2], 0,0,0,1)) else: #zabezpieczenie przed nadmiernym liczeniem - i tak nie ma roznicy przy volumach 150x150x150 pkt , bo 150/10000 = 0 ;-) tzn. na brzegu voluma #plaszczyzna i tak nie przetnie innego punktu (voxela) niz wlasciwy normal[0]=float(normal[0]) normal[1]=float(normal[1]) normal[2]=float(normal[2]) e=0 for dir in normal: if dir==0: normal[e]=0.0001 elif dir==1: normal[e]=0.9999 e=e+1 #tu najprawdopodobniej jest blad w jakims minusie, albo sinus zamiast cos, moze wikipedia sie myli #http://pl.wikipedia.org/wiki/K%C4%85ty_Eulera self.Alfa=[acos(normal[0]),acos(normal[1]),acos(normal[2])] # self.Alfa jest dla mnie normalna plaszczyzny ciecia wyrazona w stopniach tzn (kat_x,kat_y,kat_z) self.SinAlfa=[sin(self.Alfa[0]),sin(self.Alfa[1]),sin(self.Alfa[2])] self.i=[normal[0]*normal[2]-self.SinAlfa[0]*self.SinAlfa[1]*normal[1], self.SinAlfa[0]*normal[2]+normal[0]*self.SinAlfa[2]*normal[1],self.SinAlfa[2]*self.SinAlfa[1]] self.j=[-normal[0]*normal[2]-self.SinAlfa[0]*self.SinAlfa[1]*normal[1], -self.SinAlfa[0]*normal[2]-normal[0]*self.SinAlfa[1]*normal[1],normal[2]*self.SinAlfa[1]] self.k=[self.SinAlfa[1]*self.SinAlfa[1],-normal[0]*self.SinAlfa[2],normal[1]] #macierz obrotu - kat eulera w wikipedii #http://pl.wikipedia.org/wiki/K%C4%85ty_Eulera - na dole jest macierz obrotu self.axial.DeepCopy((self.i[0], self.i[1], self.i[2], origin[0], self.j[0], self.j[1], self.j[2], origin[1], self.k[0], self.k[1], self.k[2], origin[2], 0, 0, 0, 1)) return self.axial
def smoothMultipleSegments(self, maskImage=None, maskExtent=None): import vtkSegmentationCorePython as vtkSegmentationCore # Generate merged labelmap of all visible segments segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() visibleSegmentIds = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs( visibleSegmentIds) if visibleSegmentIds.GetNumberOfValues() == 0: logging.info( "Smoothing operation skipped: there are no visible segments") return mergedImage = slicer.vtkOrientedImageData() if not segmentationNode.GenerateMergedLabelmapForAllSegments( mergedImage, vtkSegmentationCore.vtkSegmentation. EXTENT_UNION_OF_SEGMENTS_PADDED, None, visibleSegmentIds): logging.error( 'Failed to apply smoothing: cannot get list of visible segments' ) return segmentLabelValues = [] # list of [segmentId, labelValue] for i in range(visibleSegmentIds.GetNumberOfValues()): segmentId = visibleSegmentIds.GetValue(i) segmentLabelValues.append([segmentId, i + 1]) # Perform smoothing in voxel space ici = vtk.vtkImageChangeInformation() ici.SetInputData(mergedImage) ici.SetOutputSpacing(1, 1, 1) ici.SetOutputOrigin(0, 0, 0) # Convert labelmap to combined polydata # vtkDiscreteFlyingEdges3D cannot be used here, as in the output of that filter, # each labeled region is completely disconnected from neighboring regions, and # for joint smoothing it is essential for the points to move together. convertToPolyData = vtk.vtkDiscreteMarchingCubes() convertToPolyData.SetInputConnection(ici.GetOutputPort()) convertToPolyData.SetNumberOfContours(len(segmentLabelValues)) contourIndex = 0 for segmentId, labelValue in segmentLabelValues: convertToPolyData.SetValue(contourIndex, labelValue) contourIndex += 1 # Low-pass filtering using Taubin's method smoothingFactor = self.scriptedEffect.doubleParameter( "JointTaubinSmoothingFactor") smoothingIterations = 100 # according to VTK documentation 10-20 iterations could be enough but we use a higher value to reduce chance of shrinking passBand = pow( 10.0, -4.0 * smoothingFactor ) # gives a nice range of 1-0.0001 from a user input of 0-1 smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(convertToPolyData.GetOutputPort()) smoother.SetNumberOfIterations(smoothingIterations) smoother.BoundarySmoothingOff() smoother.FeatureEdgeSmoothingOff() smoother.SetFeatureAngle(90.0) smoother.SetPassBand(passBand) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() # Extract a label threshold = vtk.vtkThreshold() threshold.SetInputConnection(smoother.GetOutputPort()) # Convert to polydata geometryFilter = vtk.vtkGeometryFilter() geometryFilter.SetInputConnection(threshold.GetOutputPort()) # Convert polydata to stencil polyDataToImageStencil = vtk.vtkPolyDataToImageStencil() polyDataToImageStencil.SetInputConnection( geometryFilter.GetOutputPort()) polyDataToImageStencil.SetOutputSpacing(1, 1, 1) polyDataToImageStencil.SetOutputOrigin(0, 0, 0) polyDataToImageStencil.SetOutputWholeExtent(mergedImage.GetExtent()) # Convert stencil to image stencil = vtk.vtkImageStencil() emptyBinaryLabelMap = vtk.vtkImageData() emptyBinaryLabelMap.SetExtent(mergedImage.GetExtent()) emptyBinaryLabelMap.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) vtkSegmentationCore.vtkOrientedImageDataResample.FillImage( emptyBinaryLabelMap, 0) stencil.SetInputData(emptyBinaryLabelMap) stencil.SetStencilConnection(polyDataToImageStencil.GetOutputPort()) stencil.ReverseStencilOn() stencil.SetBackgroundValue( 1 ) # General foreground value is 1 (background value because of reverse stencil) imageToWorldMatrix = vtk.vtkMatrix4x4() mergedImage.GetImageToWorldMatrix(imageToWorldMatrix) # TODO: Temporarily setting the overwite mode to OverwriteVisibleSegments is an approach that should be change once additional # layer control options have been implemented. Users may wish to keep segments on separate layers, and not allow them to be separated/merged automatically. # This effect could leverage those options once they have been implemented. oldOverwriteMode = self.scriptedEffect.parameterSetNode( ).GetOverwriteMode() self.scriptedEffect.parameterSetNode().SetOverwriteMode( slicer.vtkMRMLSegmentEditorNode.OverwriteVisibleSegments) for segmentId, labelValue in segmentLabelValues: threshold.ThresholdBetween(labelValue, labelValue) stencil.Update() smoothedBinaryLabelMap = slicer.vtkOrientedImageData() smoothedBinaryLabelMap.ShallowCopy(stencil.GetOutput()) smoothedBinaryLabelMap.SetImageToWorldMatrix(imageToWorldMatrix) self.scriptedEffect.modifySegmentByLabelmap( segmentationNode, segmentId, smoothedBinaryLabelMap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet, False) self.scriptedEffect.parameterSetNode().SetOverwriteMode( oldOverwriteMode)
def createModels(self): self.deleteModels() for sr in self.summary_reports: self.labelScores[sr]=[] self.selectedLabelList = [] if self.calcificationType == 0 and self.volumeNode and self.roiNode: #print 'in Heart Create Models' slicer.vtkSlicerCropVolumeLogic().CropVoxelBased(self.roiNode, self.volumeNode, self.croppedNode) croppedImage = sitk.ReadImage( sitkUtils.GetSlicerITKReadWriteAddress(self.croppedNode.GetName())) thresholdImage = sitk.BinaryThreshold(croppedImage,self.ThresholdMin, self.ThresholdMax, 1, 0) connectedCompImage =sitk.ConnectedComponent(thresholdImage, True) relabelImage =sitk.RelabelComponent(connectedCompImage) labelStatFilter =sitk.LabelStatisticsImageFilter() labelStatFilter.Execute(croppedImage, relabelImage) if relabelImage.GetPixelID() != sitk.sitkInt16: relabelImage = sitk.Cast( relabelImage, sitk.sitkInt16 ) sitk.WriteImage( relabelImage, sitkUtils.GetSlicerITKReadWriteAddress(self.labelsNode.GetName())) nLabels = labelStatFilter.GetNumberOfLabels() #print "Number of labels = ", nLabels self.totalScore = 0 count = 0 #Computation of the score follows this paper: #C. H McCollough, Radiology, 243(2), 2007 for n in range(0,nLabels): max = labelStatFilter.GetMaximum(n) mean = labelStatFilter.GetMean(n) size = labelStatFilter.GetCount(n) volume = size*self.voxelVolume if volume > self.MaximumLesionSize: continue if volume < self.MinimumLesionSize: nLabels = n+1 break density_score = self.computeDensityScore(max) #Agatston score is \sum_i area_i * density_score_i #For now we assume that all the plaques have the same density score score = size*(self.sx*self.sy)*density_score mass_score = mean*volume #print "label = ", n, " max = ", max, " score = ", score, " voxels = ", size self.labelScores["Agatston Score"].append(score) self.labelScores["Mass Score"].append(mass_score) self.labelScores["Volume"].append(volume) self.selectedLabelList.append(0) self.marchingCubes.SetInputData(self.labelsNode.GetImageData()) self.marchingCubes.SetValue(0, n) self.marchingCubes.Update() self.transformPolyData.SetInputData(self.marchingCubes.GetOutput()) mat = vtk.vtkMatrix4x4() self.labelsNode.GetIJKToRASMatrix(mat) trans = vtk.vtkTransform() trans.SetMatrix(mat) self.transformPolyData.SetTransform(trans) self.transformPolyData.Update() poly = vtk.vtkPolyData() poly.DeepCopy(self.transformPolyData.GetOutput()) modelNode = slicer.vtkMRMLModelNode() slicer.mrmlScene.AddNode(modelNode) dnode = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(dnode) modelNode.AddAndObserveDisplayNodeID(dnode.GetID()) modelNode.SetAndObservePolyData(poly) ct=slicer.mrmlScene.GetNodeByID('vtkMRMLColorTableNodeLabels') rgb = [0,0,0] ct.GetLookupTable().GetColor(count+1,rgb) dnode.SetColor(rgb) #Enable Slice intersection dnode.SetSliceDisplayMode(0) dnode.SetSliceIntersectionVisibility(1) self.addLabel(count, rgb, [score,mass_score,volume,mean,max]) count = count+1 self.modelNodes.append(modelNode) self.selectedLabels[poly] = n #a = slicer.util.array(tn.GetID()) #sa = sitk.GetImageFromArray(a) for sr in self.summary_reports: self.scoreField[sr].setText(self.totalScores[sr]) else: print ("not implemented")