def ResizeData(self, imageData, factor=1.0, maximum=0): self.imageResampler = vtkImageResample() self.imageResampler.SetInterpolationModeToLinear() self.imageResampler.SetInputData(imageData) # If a maximum has been set: calculate the right factor if maximum > 0: factor = self.calculateFactor(imageData.GetDimensions(), maximum) # Make sure that we are never upscaling the data if factor > 1.0: factor = 1.0 # The factor is now only in amount of pixels. This has to be translated # to each of the dimensions: factor^(1/3) axisMagnificationFactor = pow(factor, 1.0 / 3.0) self.resampledImageData = None if factor != 1.0: self.imageResampler.SetAxisMagnificationFactor(0, axisMagnificationFactor) self.imageResampler.SetAxisMagnificationFactor(1, axisMagnificationFactor) self.imageResampler.SetAxisMagnificationFactor(2, axisMagnificationFactor) self.imageResampler.Update() self.resampledImageData = self.imageResampler.GetOutput() else: self.resampledImageData = imageData return self.resampledImageData
def on_buttonPreview_clicked(button=None): pars = widgets.get_params() print "type(pars)=", type(pars) pars = widgets.validate(pars) if pars is None: return #print "on_buttonPreview_clicked: pars = ", pars reader = widgets.get_reader(pars) inDim1, inDim2 = pars.dimensions print "on_buttonPreview_clicked(): pars.dimensions = ", pars.dimensions outDim1, outDim2 = widgets.outDim print "on_buttonPreview_clicked(): outDim = ", widgets.outDim scale1 = outDim1/inDim1 scale2 = outDim2/inDim2 print "on_buttonPreview_clicked(): scale1 = ", scale1, "scale2=", scale2 resample = vtk.vtkImageResample() print "on_buttonPreview_clicked(): calling reader.GetOutput()" resample.SetInput(reader.GetOutput()) resample.SetAxisMagnificationFactor(0, scale1) resample.SetAxisMagnificationFactor(1, scale2) widgets.viewer.SetInput(resample.GetOutput()) widgets.preview.Render() # set up the scroll bars widgets['hscrollbarColorLevel'].set_range(0, 2000) widgets['hscrollbarColorLevel'].set_value(1000) widgets['hscrollbarColorWindow'].set_range(0, 6000) widgets['hscrollbarColorWindow'].set_value(2000) widgets['hscrollbarSlice'].set_range(0, pars.last-pars.first+1) widgets['hscrollbarSlice'].set_value(0.5*(pars.last-pars.first))
def update_image(self): reslice = vtk.vtkImageReslice() if self.origin_x is not None: # add padding so that origin_x is in the middle of the image pad = vtk.vtkImageConstantPad() pad.SetInputConnection(self.reader.GetOutputPort()) pad.SetConstant(BG_HU) # GetExtent() returns a tuple (minX, maxX, minY, maxY, minZ, maxZ) extent = list(self.reader.GetOutput().GetExtent()) x_size = extent[1] - extent[0] extent[0] -= max(x_size - 2 * self.origin_x, 0) extent[1] += max(2 * self.origin_x - x_size, 0) pad.SetOutputWholeExtent(*extent) reslice.SetInputConnection(pad.GetOutputPort()) else: reslice.SetInputConnection(self.reader.GetOutputPort()) transform = vtk.vtkPerspectiveTransform() # gantry tilt transform.Shear(0, *self.shear_params) if self.angle_z != 0 or self.angle_y != 0: transform.RotateWXYZ(-self.angle_z, 0, 0, 1) # top transform.RotateWXYZ(self.angle_y, 0, 1, 0) # front reslice.SetResliceTransform(transform) reslice.SetInterpolationModeToCubic() reslice.AutoCropOutputOn() reslice.SetBackgroundLevel(BG_HU) reslice.Update() spacings_lists = reslice.GetOutput().GetSpacing() if self.spacing == 'auto': min_spacing = min(spacings_lists) if not min_spacing: raise ValueError('Invalid scan. Path: {}'.format( self.scan_dir)) spacing = [min_spacing, min_spacing, min_spacing] elif self.spacing == 'none': spacing = None else: spacing = self.spacing if spacing is None: self.image = reslice else: resample = vtkImageResample() resample.SetInputConnection(reslice.GetOutputPort()) resample.SetAxisOutputSpacing(0, spacing[0]) # x axis resample.SetAxisOutputSpacing(1, spacing[1]) # y axis resample.SetAxisOutputSpacing(2, spacing[2]) # z axis resample.SetInterpolationModeToCubic() resample.Update() self.image = resample
def initView(self, data, widget): image_type = data.getITKImageType() self.image = data.getITKImage() self.space = data.getResolution().tolist() # Resolution: x(col), y(row), z(slice) if len(self.space) == 3: self.space = [float(x) / self.space[-1] for x in self.space] #self.space = [1.0, 1.0, 1.0] self.image.SetSpacing(self.space) self.itk_vtk_converter = itk.ImageToVTKImageFilter[image_type].New() self.itk_vtk_converter.SetInput(self.image) self.image_resample = vtk.vtkImageResample() self.image_resample.SetInput(self.itk_vtk_converter.GetOutput()) # image_matrix = data.getData() # image_matrix = npy.round((image_matrix - npy.min(image_matrix)) / (npy.max(image_matrix) - npy.min(image_matrix)) * 255) # image_matrix = image_matrix.astype(npy.uint8) # self.dataImporter = vtk.vtkImageImport() # data_string = image_matrix.tostring() # self.dataImporter.CopyImportVoidPointer(data_string, len(data_string)) # self.dataImporter.SetDataScalarTypeToUnsignedChar() # self.dataImporter.SetNumberOfScalarComponents(1) # extent = image_matrix.shape # self.dataImporter.SetDataExtent(0, extent[2] - 1, 0, extent[1] - 1, 0, extent[0] - 1) # self.dataImporter.SetWholeExtent(0, extent[2] - 1, 0, extent[1] - 1, 0, extent[0] - 1) # self.dataImporter.SetDataSpacing(self.space) # self.image_resample = vtk.vtkImageResample() # self.image_resample.SetInput(self.dataImporter.GetOutput()) self.renderer = vtk.vtkRenderer() self.render_window = widget.GetRenderWindow() self.render_window.AddRenderer(self.renderer)
def run(self): global vtk_error #----- verify extension ------------------ extension = VerifyDataType(self.filepath) file_name = self.filepath.split(os.path.sep)[-1] n_array = ReadBitmap(self.filepath) if not(isinstance(n_array, numpy.ndarray)): return False image = converters.to_vtk(n_array, spacing=(1,1,1),\ slice_number=1, orientation="AXIAL") dim = image.GetDimensions() x = dim[0] y = dim[1] img = vtk.vtkImageResample() img.SetInputData(image) img.SetAxisMagnificationFactor ( 0, 0.25 ) img.SetAxisMagnificationFactor ( 1, 0.25 ) img.SetAxisMagnificationFactor ( 2, 1 ) img.Update() tp = img.GetOutput().GetScalarTypeAsString() image_copy = vtk.vtkImageData() image_copy.DeepCopy(img.GetOutput()) thumbnail_path = tempfile.mktemp() write_png = vtk.vtkPNGWriter() write_png.SetInputConnection(img.GetOutputPort()) write_png.AddObserver("WarningEvent", VtkErrorPNGWriter) write_png.SetFileName(thumbnail_path) write_png.Write() if vtk_error: img = vtk.vtkImageCast() img.SetInputData(image_copy) img.SetOutputScalarTypeToUnsignedShort() #img.SetClampOverflow(1) img.Update() write_png = vtk.vtkPNGWriter() write_png.SetInputConnection(img.GetOutputPort()) write_png.SetFileName(thumbnail_path) write_png.Write() vtk_error = False id = wx.NewId() bmp_item = [self.filepath, thumbnail_path, extension, x, y,\ str(x) + ' x ' + str(y), file_name, id] self.bmp_file.Add(bmp_item)
def ResizeData(self, imageData, factor=1.0, maximum=0): self.imageResampler = vtkImageResample() self.imageResampler.SetInterpolationModeToLinear() self.imageResampler.SetInputData(imageData) # If a maximum has been set: calculate the right factor if maximum > 0: factor = self.calculateFactor(imageData.GetDimensions(), maximum) # Make sure that we are never upscaling the data if factor > 1.0: factor = 1.0 # The factor is now only in amount of pixels. This has to be translated # to each of the dimensions: factor^(1/3) axisMagnificationFactor = pow(factor, 1.0/3.0) self.resampledImageData = None if factor != 1.0: self.imageResampler.SetAxisMagnificationFactor(0, axisMagnificationFactor) self.imageResampler.SetAxisMagnificationFactor(1, axisMagnificationFactor) self.imageResampler.SetAxisMagnificationFactor(2, axisMagnificationFactor) self.imageResampler.Update() self.resampledImageData = self.imageResampler.GetOutput() else: self.resampledImageData = imageData return self.resampledImageData
def _volume(dimensions, origin, spacing, scalars, surface_alpha, resolution, blending, center): # Now we can actually construct the visualization grid = pyvista.UniformGrid() grid.dimensions = dimensions + 1 # inject data on the cells grid.origin = origin grid.spacing = spacing grid.cell_arrays['values'] = scalars # Add contour of enclosed volume (use GetOutput instead of # GetOutputPort below to avoid updating) grid_alg = vtk.vtkCellDataToPointData() grid_alg.SetInputDataObject(grid) grid_alg.SetPassCellData(False) grid_alg.Update() if surface_alpha > 0: grid_surface = vtk.vtkMarchingContourFilter() grid_surface.ComputeNormalsOn() grid_surface.ComputeScalarsOff() grid_surface.SetInputData(grid_alg.GetOutput()) grid_surface.SetValue(0, 0.1) grid_surface.Update() grid_mesh = vtk.vtkPolyDataMapper() grid_mesh.SetInputData(grid_surface.GetOutput()) else: grid_mesh = None mapper = vtk.vtkSmartVolumeMapper() if resolution is None: # native mapper.SetScalarModeToUseCellData() mapper.SetInputDataObject(grid) else: upsampler = vtk.vtkImageResample() upsampler.SetInterpolationModeToNearestNeighbor() upsampler.SetOutputSpacing(*([resolution] * 3)) upsampler.SetInputConnection(grid_alg.GetOutputPort()) mapper.SetInputConnection(upsampler.GetOutputPort()) # Additive, AverageIntensity, and Composite might also be reasonable remap = dict(composite='Composite', mip='MaximumIntensity') getattr(mapper, f'SetBlendModeTo{remap[blending]}')() volume_pos = vtk.vtkVolume() volume_pos.SetMapper(mapper) dist = grid.length / (np.mean(grid.dimensions) - 1) volume_pos.GetProperty().SetScalarOpacityUnitDistance(dist) if center is not None and blending == 'mip': # We need to create a minimum intensity projection for the neg half mapper_neg = vtk.vtkSmartVolumeMapper() if resolution is None: # native mapper_neg.SetScalarModeToUseCellData() mapper_neg.SetInputDataObject(grid) else: mapper_neg.SetInputConnection(upsampler.GetOutputPort()) mapper_neg.SetBlendModeToMinimumIntensity() volume_neg = vtk.vtkVolume() volume_neg.SetMapper(mapper_neg) volume_neg.GetProperty().SetScalarOpacityUnitDistance(dist) else: volume_neg = None return grid, grid_mesh, volume_pos, volume_neg
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkImageResample(), 'Processing.', ('vtkImageData', 'vtkImageStencilData'), ('vtkImageData',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def resample_image(vtk_im, min_): resample = vtk.vtkImageResample() spacing = vtk_im.GetSpacing() resample.SetInputData(vtk_im) for i in range(3): resample.SetAxisOutputSpacing(i, min_) resample.Update() return resample.GetOutput()
def setWidgetView(self, widget): self.initView(self.parent.getData('fix'), widget) data = self.parent.getData() image_type = data.getITKImageType() self.image2 = data.getITKImage() self.space2 = data.getResolution().tolist() if len(self.space2) == 3: self.space2 = [float(x) / self.space2[-1] for x in self.space2] self.image2.SetSpacing(self.space2) shapeList = data.getData().shape y, x = shapeList[-2], shapeList[-1] itk_vtk_converter = itk.ImageToVTKImageFilter[image_type].New() itk_vtk_converter.SetInput(self.image2) image_resample = vtk.vtkImageResample() image_resample.SetInput(itk_vtk_converter.GetOutput()) self.renderer2 = vtk.vtkRenderer() self.render_window.AddRenderer(self.renderer2) self.reslice_mapper2 = vtk.vtkImageResliceMapper() self.reslice_mapper2.SetInput(image_resample.GetOutput()) self.reslice_mapper2.SliceFacesCameraOn() self.reslice_mapper2.SliceAtFocalPointOn() self.reslice_mapper2.JumpToNearestSliceOn() self.reslice_mapper2.BorderOff() self.reslice_mapper2.BackgroundOn() array = data.getData() self.minI2 = array.min() self.maxI2 = array.max() self.image_slice2 = vtk.vtkImageSlice() self.image_slice2.SetMapper(self.reslice_mapper2) image_property2 = vtk.vtkImageProperty() image_property2.SetColorWindow(self.maxI2 - self.minI2) image_property2.SetColorLevel((self.maxI2 + self.minI2) / 2.0) image_property2.SetAmbient(0.0) image_property2.SetDiffuse(1.0) image_property2.SetOpacity(1.0) image_property2.SetInterpolationTypeToLinear() self.image_slice2.SetProperty(image_property2) self.renderer2.AddViewProp(self.image_slice2) self.renderer.SetViewport(0, 0, 0.5, 1) self.renderer2.SetViewport(0.5, 0, 1, 1) self.renderer2.SetActiveCamera(self.camera) self.render_window.Render()
def getResampledData(self, data, n, resampleToDimensions=None): """ Return the data resampled to given dimensions """ if self.resampling and not scripting.resamplingDisabled: currentResamplingDimensions = self.getResampleDimensions() # If we're given dimensions to resample to, then we use those if resampleToDimensions: currentResamplingDimensions = resampleToDimensions # If the resampling dimensions are not defined (even though resampling is requested) # then don't resample the data if not currentResamplingDimensions: return data if n == self.resampledTimepoint and self.resampleFilter and not currentResamplingDimensions: data = self.resampleFilter.GetOutput() else: Logging.info("Resampling data to ", self.resampleDims, kw="datasource") if not self.resampleFilter: self.resampleFilter = vtk.vtkImageResample() x, y, z = self.originalDimensions rx, ry, rz = currentResamplingDimensions xf = rx / float(x) yf = ry / float(y) zf = rz / float(z) self.resampleFilter.SetAxisMagnificationFactor(0, xf) self.resampleFilter.SetAxisMagnificationFactor(1, yf) self.resampleFilter.SetAxisMagnificationFactor(2, zf) else: self.resampleFilter.RemoveAllInputs() self.resampleFilter.SetInputConnection(data.GetProducerPort()) data = self.resampleFilter.GetOutput() if self.mask: if not self.maskImageFilter: self.maskImageFilter = vtk.vtkImageMask() self.maskImageFilter.SetMaskedOutputValue(0) else: self.maskImageFilter.RemoveAllInputs() self.maskImageFilter.SetImageInput(data) self.maskImageFilter.SetMaskInput(self.mask.getMaskImage()) data = self.maskImageFilter.GetOutput() return data
def getResampledData(self, data, n, resampleToDimensions = None): """ Return the data resampled to given dimensions """ if self.resampling and not scripting.resamplingDisabled: currentResamplingDimensions = self.getResampleDimensions() # If we're given dimensions to resample to, then we use those if resampleToDimensions: currentResamplingDimensions = resampleToDimensions # If the resampling dimensions are not defined (even though resampling is requested) # then don't resample the data if not currentResamplingDimensions: return data if n == self.resampledTimepoint and self.resampleFilter and not currentResamplingDimensions: data = self.resampleFilter.GetOutput() else: Logging.info("Resampling data to ", self.resampleDims, kw = "datasource") if not self.resampleFilter: self.resampleFilter = vtk.vtkImageResample() x, y, z = self.originalDimensions rx, ry, rz = currentResamplingDimensions xf = rx / float(x) yf = ry / float(y) zf = rz / float(z) self.resampleFilter.SetAxisMagnificationFactor(0, xf) self.resampleFilter.SetAxisMagnificationFactor(1, yf) self.resampleFilter.SetAxisMagnificationFactor(2, zf) else: self.resampleFilter.RemoveAllInputs() self.resampleFilter.SetInputConnection(data.GetProducerPort()) data = self.resampleFilter.GetOutput() if self.mask: if not self.maskImageFilter: self.maskImageFilter = vtk.vtkImageMask() self.maskImageFilter.SetMaskedOutputValue(0) else: self.maskImageFilter.RemoveAllInputs() self.maskImageFilter.SetImageInput(data) self.maskImageFilter.SetMaskInput(self.mask.getMaskImage()) data = self.maskImageFilter.GetOutput() return data
def _handleFailedImage(idiff, pngr, img_fname): """Writes all the necessary images when an image comparison failed.""" f_base, f_ext = os.path.splitext(img_fname) # write out the difference file in full. pngw = vtk.vtkPNGWriter() pngw.SetFileName(_getTempImagePath(f_base + ".diff.png")) pngw.SetInput(idiff.GetOutput()) pngw.Write() # write the difference image scaled and gamma adjusted for the # dashboard. sz = pngr.GetOutput().GetDimensions() if sz[1] <= 250.0: mag = 1.0 else: mag = 250.0 / sz[1] shrink = vtk.vtkImageResample() shrink.SetInput(idiff.GetOutput()) shrink.InterpolateOn() shrink.SetAxisMagnificationFactor(0, mag) shrink.SetAxisMagnificationFactor(1, mag) gamma = vtk.vtkImageShiftScale() gamma.SetInput(shrink.GetOutput()) gamma.SetShift(0) gamma.SetScale(10) jpegw = vtk.vtkJPEGWriter() jpegw.SetFileName(_getTempImagePath(f_base + ".diff.small.jpg")) jpegw.SetInput(gamma.GetOutput()) jpegw.SetQuality(85) jpegw.Write() # write out the image that was generated. shrink.SetInput(idiff.GetInput()) jpegw.SetInput(shrink.GetOutput()) jpegw.SetFileName(_getTempImagePath(f_base + ".test.small.jpg")) jpegw.Write() # write out the valid image that matched. shrink.SetInput(idiff.GetImage()) jpegw.SetInput(shrink.GetOutput()) jpegw.SetFileName(_getTempImagePath(f_base + ".small.jpg")) jpegw.Write()
def _handleFailedImage(idiff, pngr, img_fname): """Writes all the necessary images when an image comparison failed.""" f_base, f_ext = os.path.splitext(img_fname) # write out the difference file in full. pngw = vtk.vtkPNGWriter() pngw.SetFileName(_getTempImagePath(f_base + ".diff.png")) pngw.SetInput(idiff.GetOutput()) pngw.Write() # write the difference image scaled and gamma adjusted for the # dashboard. sz = pngr.GetOutput().GetDimensions() if sz[1] <= 250.0: mag = 1.0 else: mag = 250.0/sz[1] shrink = vtk.vtkImageResample() shrink.SetInput(idiff.GetOutput()) shrink.InterpolateOn() shrink.SetAxisMagnificationFactor(0, mag) shrink.SetAxisMagnificationFactor(1, mag) gamma = vtk.vtkImageShiftScale() gamma.SetInput(shrink.GetOutput()) gamma.SetShift(0) gamma.SetScale(10) jpegw = vtk.vtkJPEGWriter() jpegw.SetFileName(_getTempImagePath(f_base + ".diff.small.jpg")) jpegw.SetInput(gamma.GetOutput()) jpegw.SetQuality(85) jpegw.Write() # write out the image that was generated. shrink.SetInput(idiff.GetInput()) jpegw.SetInput(shrink.GetOutput()) jpegw.SetFileName(_getTempImagePath(f_base + ".test.small.jpg")) jpegw.Write() # write out the valid image that matched. shrink.SetInput(idiff.GetImage()) jpegw.SetInput(shrink.GetOutput()) jpegw.SetFileName(_getTempImagePath(f_base + ".small.jpg")) jpegw.Write()
def __init__(self, module_manager): ModuleBase.__init__(self, module_manager) self._imageResample = vtk.vtkImageResample() module_utils.setup_vtk_object_progress(self, self._imageResample, 'Resampling image.') # 0: nearest neighbour # 1: linear # 2: cubic self._config.interpolationMode = 1 self._config.magFactors = [1.0, 1.0, 1.0] self._view_frame = None self.sync_module_logic_with_config()
def ResampleImage3D(imagedata, value): """ Resample vtkImageData matrix. """ spacing = imagedata.GetSpacing() extent = imagedata.GetExtent() size = imagedata.GetDimensions() width = float(size[0]) height = float(size[1] / value) resolution = (height / (extent[1] - extent[0]) + 1) * spacing[1] resample = vtk.vtkImageResample() resample.SetInputData(imagedata) resample.SetAxisMagnificationFactor(0, resolution) resample.SetAxisMagnificationFactor(1, resolution) return resample.GetOutput()
def ResampleImage3D(imagedata, value): """ Resample vtkImageData matrix. """ spacing = imagedata.GetSpacing() extent = imagedata.GetExtent() size = imagedata.GetDimensions() width = float(size[0]) height = float(size[1]/value) resolution = (height/(extent[1]-extent[0])+1)*spacing[1] resample = vtk.vtkImageResample() resample.SetInput(imagedata) resample.SetAxisMagnificationFactor(0, resolution) resample.SetAxisMagnificationFactor(1, resolution) return resample.GetOutput()
def ResampleImage2D(imagedata, px=None, py=None, resolution_percentage=None, update_progress=None): """ Resample vtkImageData matrix. """ extent = imagedata.GetExtent() spacing = imagedata.GetSpacing() dimensions = imagedata.GetDimensions() if resolution_percentage: px = math.ceil(dimensions[0] * resolution_percentage) py = math.ceil(dimensions[1] * resolution_percentage) if abs(extent[1] - extent[3]) < abs(extent[3] - extent[5]): f = extent[1] elif abs(extent[1] - extent[5]) < abs(extent[1] - extent[3]): f = extent[1] elif abs(extent[3] - extent[5]) < abs(extent[1] - extent[3]): f = extent[3] else: f = extent[1] factor_x = px / float(f + 1) factor_y = py / float(f + 1) resample = vtk.vtkImageResample() resample.SetInputData(imagedata) resample.SetAxisMagnificationFactor(0, factor_x) resample.SetAxisMagnificationFactor(1, factor_y) resample.SetOutputSpacing(spacing[0] * factor_x, spacing[1] * factor_y, spacing[2]) if (update_progress): message = _("Generating multiplanar visualization...") resample.AddObserver( "ProgressEvent", lambda obj, evt: update_progress(resample, message)) resample.Update() return resample.GetOutput()
def resample(self, newSpacing, interpolation=1): """ Resamples a ``Volume`` to be larger or smaller. This method modifies the spacing of the input. Linear interpolation is used to resample the data. :param list newSpacing: a list of 3 new spacings for the 3 axes. :param int interpolation: 0=nearest_neighbor, 1=linear, 2=cubic """ rsp = vtk.vtkImageResample() oldsp = self.spacing() for i in range(3): if oldsp[i] != newSpacing[i]: rsp.SetAxisOutputSpacing(i, newSpacing[i]) rsp.InterpolateOn() rsp.SetInterpolationMode(interpolation) rsp.OptimizationOn() rsp.Update() return self._update(rsp.GetOutput())
def Rasample(input_img: Image_Data, target_dim, method): ori_spacing = np.array(input_img.Get_Spacing()) ori_dim = np.array(input_img.Get_Dim()) target_spacing = ori_spacing / target_dim * ori_dim input_vtk_image = input_img.Get_vtkImageData() resample_filter = vtk.vtkImageResample() resample_filter.SetInputData(input_vtk_image) resample_filter.SetOutputSpacing(target_spacing) if method == 'Linear': resample_filter.SetInterpolationModeToLinear() elif method == 'Cubic': resample_filter.SetInterpolationModeToCubic() else: resample_filter.SetInterpolationModeToNearestNeighbor() resample_filter.Update() output_image_data = Image_Data() output_image_data.Init_From_Vtk(resample_filter.GetOutput()) return output_image_data
def ResampleImage2D(imagedata, px, py, update_progress = None): """ Resample vtkImageData matrix. """ extent = imagedata.GetExtent() spacing = imagedata.GetSpacing() #if extent[1]==extent[3]: # f = extent[1] #elif extent[1]==extent[5]: # f = extent[1] #elif extent[3]==extent[5]: # f = extent[3] if abs(extent[1]-extent[3]) < abs(extent[3]-extent[5]): f = extent[1] elif abs(extent[1]-extent[5]) < abs(extent[1] - extent[3]): f = extent[1] elif abs(extent[3]-extent[5]) < abs(extent[1] - extent[3]): f = extent[3] else: f = extent[1] factor_x = px/float(f+1) factor_y = py/float(f+1) resample = vtk.vtkImageResample() resample.SetInput(imagedata) resample.SetAxisMagnificationFactor(0, factor_x) resample.SetAxisMagnificationFactor(1, factor_y) resample.SetOutputSpacing(spacing[0] * factor_x, spacing[1] * factor_y, spacing[2]) if (update_progress): message = _("Generating multiplanar visualization...") resample.AddObserver("ProgressEvent", lambda obj, evt:update_progress(resample,message)) resample.Update() return resample.GetOutput()
def loadIcon(self, system): if os.path.exists(system.get_filename_by_extension('.jpg')): reader = vtk.vtkJPEGReader() reader.SetFileName(system.get_filename_by_extension('jpg')) reader.Update() extent = reader.GetDataExtent() resizer = vtk.vtkImageResample() resizer.SetInterpolationModeToCubic() resizer.SetInput(reader.GetOutput()) scale = min((spade.top_width + 0.0) / extent[1], (spade.top_height / 2.0) / extent[3]) resizer.SetAxisMagnificationFactor(0, scale) resizer.SetAxisMagnificationFactor(1, scale) self.miniviewer.GetImageViewer().SetColorWindow(200) self.miniviewer.GetImageViewer().SetColorLevel(100) self.miniviewer.GetImageViewer().SetInput(resizer.GetOutput()) else: print 'no %s image available' % ( system.get_filename_by_extension('.jpg')) self.miniviewer.Render()
def ResampleImage2D(imagedata, px=None, py=None, resolution_percentage = None, update_progress = None): """ Resample vtkImageData matrix. """ extent = imagedata.GetExtent() spacing = imagedata.GetSpacing() dimensions = imagedata.GetDimensions() if resolution_percentage: px = math.ceil(dimensions[0] * resolution_percentage) py = math.ceil(dimensions[1] * resolution_percentage) if abs(extent[1]-extent[3]) < abs(extent[3]-extent[5]): f = extent[1] elif abs(extent[1]-extent[5]) < abs(extent[1] - extent[3]): f = extent[1] elif abs(extent[3]-extent[5]) < abs(extent[1] - extent[3]): f = extent[3] else: f = extent[1] factor_x = px/float(f+1) factor_y = py/float(f+1) resample = vtk.vtkImageResample() resample.SetInputData(imagedata) resample.SetAxisMagnificationFactor(0, factor_x) resample.SetAxisMagnificationFactor(1, factor_y) resample.SetOutputSpacing(spacing[0] * factor_x, spacing[1] * factor_y, spacing[2]) if (update_progress): message = _("Generating multiplanar visualization...") resample.AddObserver("ProgressEvent", lambda obj, evt:update_progress(resample,message)) resample.Update() return resample.GetOutput()
def load_image_data(): ''' Used to load the knee image data. It is possible to choose if we want to downsample it with the write_file boolean declared above ''' # Loading image data from file reader = vtk.vtkSLCReader() reader.SetFileName('vw_knee.slc') reader.Update() spacing = reader.GetDataSpacing() # resampling if we want to if low_res: resample = vtk.vtkImageResample() resample.SetMagnificationFactors(0.2, 0.2, 0.2) resample.SetInputConnection(reader.GetOutputPort()) resample.Update() reader = resample # return the space between each point too return (reader, spacing)
import vtk from vtk.util.misc import vtkGetDataRoot VTK_DATA_ROOT = vtkGetDataRoot() if len(sys.argv)<2: msg = "Demonstrates interaction of a handle, represented be a user \n" \ "specified polygonal shape, so that it is constrained \n" \ "to lie on a polygonal surface.\n\n" \ "Usage args: [-DistanceOffset height_offset]." sys.exit(msg) # Read height field demReader = vtk.vtkDEMReader() demReader.SetFileName("%s/Data/SainteHelens.dem" % (VTK_DATA_ROOT,)) resample = vtk.vtkImageResample() resample.SetInput(demReader.GetOutput()) resample.SetDimensionality(2) resample.SetAxisMagnificationFactor(0, 1) resample.SetAxisMagnificationFactor(1, 1) # Extract geometry surface = vtk.vtkImageDataGeometryFilter() surface.SetInput(resample.GetOutput()) # The Dijkistra interpolator will not accept cells that aren't triangles triangleFilter = vtk.vtkTriangleFilter() triangleFilter.SetInput( surface.GetOutput() ) triangleFilter.Update() warp = vtk.vtkWarpScalar()
def create_dicom_thumbnails(filename, window=None, level=None): rvtk = vtkgdcm.vtkGDCMImageReader() rvtk.SetFileName(utils.encode(filename, const.FS_ENCODE)) rvtk.Update() img = rvtk.GetOutput() if window is None or level is None: _min, _max = img.GetScalarRange() window = _max - _min level = _min + window / 2 dx, dy, dz = img.GetDimensions() if dz > 1: thumbnail_paths = [] for i in range(dz): img_slice = ExtractVOI(img, 0, dx-1, 0, dy-1, i, i+1) colorer = vtk.vtkImageMapToWindowLevelColors() colorer.SetInputData(img_slice) colorer.SetWindow(window) colorer.SetLevel(level) colorer.SetOutputFormatToRGB() colorer.Update() resample = vtk.vtkImageResample() resample.SetInputData(colorer.GetOutput()) resample.SetAxisMagnificationFactor ( 0, 0.25 ) resample.SetAxisMagnificationFactor ( 1, 0.25 ) resample.SetAxisMagnificationFactor ( 2, 1 ) resample.Update() thumbnail_path = tempfile.mktemp() write_png = vtk.vtkPNGWriter() write_png.SetInputData(resample.GetOutput()) write_png.SetFileName(thumbnail_path) write_png.Write() thumbnail_paths.append(thumbnail_path) return thumbnail_paths else: colorer = vtk.vtkImageMapToWindowLevelColors() colorer.SetInputData(img) colorer.SetWindow(window) colorer.SetLevel(level) colorer.SetOutputFormatToRGB() colorer.Update() resample = vtk.vtkImageResample() resample.SetInputData(colorer.GetOutput()) resample.SetAxisMagnificationFactor ( 0, 0.25 ) resample.SetAxisMagnificationFactor ( 1, 0.25 ) resample.SetAxisMagnificationFactor ( 2, 1 ) resample.Update() thumbnail_path = tempfile.mktemp() write_png = vtk.vtkPNGWriter() write_png.SetInputData(resample.GetOutput()) write_png.SetFileName(thumbnail_path) write_png.Write() return thumbnail_path
renderer = vtk.vtkRenderer() for actor in actors: renderer.AddActor(actor) renderer.SetBackground(background) renderer.ResetCamera() return renderer # on lit les données depuis le fichier pour créer un ensemble structuré de points (volume) reader = vtk.vtkSLCReader() reader.SetFileName("vw_knee.slc") reader.Update() if RESAMPLE: KNEE_COLOR_FILE = "colorationBoneResampled.vtp" resample = vtk.vtkImageResample() resample.SetInputData(reader.GetOutput()) resample.SetDimensionality(3) resample.SetMagnificationFactors(0.5, 0.5, 0.5) imageData = resample.GetOutputPort() else: KNEE_COLOR_FILE = "colorationBone.vtp" imageData = reader.GetOutputPort() # utulise le volume pour en faire une isosurface pour l'os boneSurface = vtk.vtkContourFilter() boneSurface.SetInputConnection(imageData) boneSurface.SetValue(0, 73) boneSurface.ComputeScalarsOff() boneSurface.Update()
def create_dicom_thumbnails(filename, window=None, level=None): rvtk = vtkgdcm.vtkGDCMImageReader() rvtk.SetFileName(filename) rvtk.Update() img = rvtk.GetOutput() if window is None or level is None: _min, _max = img.GetScalarRange() window = _max - _min level = _min + window / 2 dx, dy, dz = img.GetDimensions() if dz > 1: thumbnail_paths = [] for i in xrange(dz): img_slice = ExtractVOI(img, 0, dx-1, 0, dy-1, i, i+1) colorer = vtk.vtkImageMapToWindowLevelColors() colorer.SetInputData(img_slice) colorer.SetWindow(window) colorer.SetLevel(level) colorer.SetOutputFormatToRGB() colorer.Update() resample = vtk.vtkImageResample() resample.SetInputData(colorer.GetOutput()) resample.SetAxisMagnificationFactor ( 0, 0.25 ) resample.SetAxisMagnificationFactor ( 1, 0.25 ) resample.SetAxisMagnificationFactor ( 2, 1 ) resample.Update() thumbnail_path = tempfile.mktemp() write_png = vtk.vtkPNGWriter() write_png.SetInputData(resample.GetOutput()) write_png.SetFileName(thumbnail_path) write_png.Write() thumbnail_paths.append(thumbnail_path) return thumbnail_paths else: colorer = vtk.vtkImageMapToWindowLevelColors() colorer.SetInputData(img) colorer.SetWindow(window) colorer.SetLevel(level) colorer.SetOutputFormatToRGB() colorer.Update() resample = vtk.vtkImageResample() resample.SetInputData(colorer.GetOutput()) resample.SetAxisMagnificationFactor ( 0, 0.25 ) resample.SetAxisMagnificationFactor ( 1, 0.25 ) resample.SetAxisMagnificationFactor ( 2, 1 ) resample.Update() thumbnail_path = tempfile.mktemp() write_png = vtk.vtkPNGWriter() write_png.SetInputData(resample.GetOutput()) write_png.SetFileName(thumbnail_path) write_png.Write() return thumbnail_path
#!/usr/bin/env python import vtk from vtk.test import Testing from vtk.util.misc import vtkGetDataRoot VTK_DATA_ROOT = vtkGetDataRoot() # Doubles the The number of images (x dimension). # Image pipeline reader = vtk.vtkImageReader() reader.ReleaseDataFlagOff() reader.SetDataByteOrderToLittleEndian() reader.SetDataExtent(0,63,0,63,1,93) reader.SetDataSpacing(3.2,3.2,1.5) reader.SetFilePrefix("" + str(VTK_DATA_ROOT) + "/Data/headsq/quarter") reader.SetDataMask(0x7fff) magnify = vtk.vtkImageResample() magnify.SetDimensionality(3) magnify.SetInputConnection(reader.GetOutputPort()) magnify.SetAxisOutputSpacing(0,0.52) magnify.SetAxisOutputSpacing(1,2.2) magnify.SetAxisOutputSpacing(2,0.8) magnify.ReleaseDataFlagOff() viewer = vtk.vtkImageViewer() viewer.SetInputConnection(magnify.GetOutputPort()) viewer.SetZSlice(30) viewer.SetColorWindow(2000) viewer.SetColorLevel(1000) viewer.Render() # --- end of script --
def main(): count = 1 dirname = None opacityWindow = 4096.0 opacityLevel = 2048.0 blendType = 0 clip = 0 reductionFactor = 1.0 frameRate = 10.0 fileName = None fileType = 0 independentComponents = True while (count < len(sys.argv)): if (sys.argv[count] == "?"): PrintUsage() sys.exit(0) elif (sys.argv[count] == "-DICOM"): dirname = sys.argv[count + 1] count += 2 elif (sys.argv[count] == "-VTI"): fileType = VTI_FILETYPE fileName = sys.argv[count + 1] count += 2 elif (sys.argv[count] == "-MHA"): fileType = MHA_FILETYPE fileName = sys.argv[count + 1] count += 2 elif (sys.argv[count] == "-Clip"): clip = 1 count += 1 elif (sys.argv[count] == "-MIP"): opacityWindow = float(sys.argv[count + 1]) opacityLevel = float(sys.argv[count + 2]) blendType = 0 count += 3 elif (sys.argv[count] == "-CompositeRamp"): opacityWindow = float(sys.argv[count + 1]) opacityLevel = float(sys.argv[count + 2]) blendType = 1 count += 3 elif (sys.argv[count] == "-CompositeShadeRamp"): opacityWindow = float(sys.argv[count + 1]) opacityLevel = float(sys.argv[count + 2]) blendType = 2 count += 3 elif (sys.argv[count] == "-CT_Skin"): blendType = 3 count += 1 elif (sys.argv[count] == "-CT_Bone"): blendType = 4 count += 1 elif (sys.argv[count] == "-CT_Muscle"): blendType = 5 count += 1 elif (sys.argv[count] == "-RGB_Composite"): blendType = 6 count += 1 elif (sys.argv[count] == "-FrameRate"): frameRate = float(sys.argv[count + 1]) if (frameRate < 0.01 or frameRate > 60.0): print( "Invalid frame rate - use a number between 0.01 and 60.0") print("Using default frame rate of 10 frames per second.") frameRate = 10.0 count += 2 elif (sys.argv[count] == "-ReductionFactor"): reductionFactor = float(sys.argv[count + 1]) if (reductionFactor <= 0.0 or reductionFactor >= 1.0): print( "Invalid reduction factor - use a number between 0 and 1 (exclusive)" ) print("Using the default of no reduction.") reductionFactor = 1.0 count += 2 elif (sys.argv[count] == "-DependentComponents"): independentComponents = false count += 1 else: print("Unrecognized option: %s\n" % (sys.argv[count])) PrintUsage() sys.exit(-1) if (dirname is None and fileName is None): print( "Error: you must specify a directory of DICOM data or a .vti file or a .mha!" ) PrintUsage() sys.exit(-1) # Create the renderer, render window and interactor renderer = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(renderer) # Connect it all. Note that funny arithematic on the # SetDesiredUpdateRate - the vtkRenderWindow divides it # allocated time across all renderers, and the renderer # divides it time across all props. If clip is # true then there are two props iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) iren.SetDesiredUpdateRate(frameRate / (1.0 + clip)) iren.GetInteractorStyle().SetDefaultRenderer(renderer) # Read the data reader = None _input = None if (dirname): dicomReader = vtk.vtkDICOMImageReader() dicomReader.SetDirectoryName(dirname) dicomReader.Update() _input = dicomReader.GetOutput() reader = dicomReader elif (fileType == VTI_FILETYPE): xmlReader = vtk.vtkXMLImageDataReader() xmlReader.SetFileName(fileName) xmlReader.Update() _input = xmlReader.GetOutput() reader = xmlReader elif (fileType == MHA_FILETYPE): metaReader = vtk.vtkMetaImageReader() metaReader.SetFileName(fileName) metaReader.Update() _input = metaReader.GetOutput() reader = metaReader else: print("Error! Not VTI or MHA!") exit(-1) # Verify that we actually have a volume dim = _input.GetDimensions() if (dim[0] < 2 or dim[1] < 2 or dim[2] < 2): print("Error loading data!") sys.exit(-1) resample = vtk.vtkImageResample() if (reductionFactor < 1.0): resample.SetInputConnection(reader.GetOutputPort()) resample.SetAxisMagnificationFactor(0, reductionFactor) resample.SetAxisMagnificationFactor(1, reductionFactor) resample.SetAxisMagnificationFactor(2, reductionFactor) # Create our volume and mapper volume = vtk.vtkVolume() mapper = vtk.vtkSmartVolumeMapper() # Add a box widget if the clip option was selected box = vtk.vtkBoxWidget() if (clip): box.SetInteractor(iren) box.SetPlaceFactor(1.01) if (reductionFactor < 1.0): box.SetInputConnection(resample.GetOutputPort()) else: box.SetInputData(_input) box.SetDefaultRenderer(renderer) box.InsideOutOn() box.PlaceWidget() callback = vtkBoxWidgetCallback() callback.SetMapper(mapper) box.AddObserver(vtk.vtkCommand.InteractionEvent, callback.onExecute) box.EnabledOn() box.GetSelectedFaceProperty().SetOpacity(0.0) if (reductionFactor < 1.0): mapper.SetInputConnection(resample.GetOutputPort()) else: mapper.SetInputConnection(reader.GetOutputPort()) # Set the sample distance on the ray to be 1/2 the average spacing spacing = None if (reductionFactor < 1.0): spacing = resample.GetOutput().GetSpacing() else: spacing = _input.GetSpacing() # mapper.SetSampleDistance( (spacing[0]+spacing[1]+spacing[2])/6.0 ) # mapper.SetMaximumImageSampleDistance(10.0) # Create our transfer function colorFun = vtk.vtkColorTransferFunction() opacityFun = vtk.vtkPiecewiseFunction() # Create the property and attach the transfer functions _property = vtk.vtkVolumeProperty() _property.SetIndependentComponents(independentComponents) _property.SetColor(colorFun) _property.SetScalarOpacity(opacityFun) _property.SetInterpolationTypeToLinear() # connect up the volume to the property and the mapper volume.SetProperty(_property) volume.SetMapper(mapper) # Depending on the blend type selected as a command line option, # adjust the transfer function if (blendType == 0): # MIP # Create an opacity ramp from the window and level values. # Color is white. Blending is MIP. colorFun.AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0) opacityFun.AddSegment(opacityLevel - 0.5 * opacityWindow, 0.0, opacityLevel + 0.5 * opacityWindow, 1.0) mapper.SetBlendModeToMaximumIntensity() elif blendType == 1: # CompositeRamp # Create a ramp from the window and level values. Use compositing # without shading. Color is a ramp from black to white. colorFun.AddRGBSegment(opacityLevel - 0.5 * opacityWindow, 0.0, 0.0, 0.0, opacityLevel + 0.5 * opacityWindow, 1.0, 1.0, 1.0) opacityFun.AddSegment(opacityLevel - 0.5 * opacityWindow, 0.0, opacityLevel + 0.5 * opacityWindow, 1.0) mapper.SetBlendModeToComposite() _property.ShadeOff() elif blendType == 2: # CompositeShadeRamp # Create a ramp from the window and level values. Use compositing # with shading. Color is white. colorFun.AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0) opacityFun.AddSegment(opacityLevel - 0.5 * opacityWindow, 0.0, opacityLevel + 0.5 * opacityWindow, 1.0) mapper.SetBlendModeToComposite() _property.ShadeOn() elif blendType == 3: # CT_Skin # Use compositing and functions set to highlight skin in CT data # Not for use on RGB data colorFun.AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0) colorFun.AddRGBPoint(-1000, .62, .36, .18, 0.5, 0.0) colorFun.AddRGBPoint(-500, .88, .60, .29, 0.33, 0.45) colorFun.AddRGBPoint(3071, .83, .66, 1, 0.5, 0.0) opacityFun.AddPoint(-3024, 0, 0.5, 0.0) opacityFun.AddPoint(-1000, 0, 0.5, 0.0) opacityFun.AddPoint(-500, 1.0, 0.33, 0.45) opacityFun.AddPoint(3071, 1.0, 0.5, 0.0) mapper.SetBlendModeToComposite() _property.ShadeOn() _property.SetAmbient(0.1) _property.SetDiffuse(0.9) _property.SetSpecular(0.2) _property.SetSpecularPower(10.0) _property.SetScalarOpacityUnitDistance(0.8919) elif blendType == 4: # CT_Bone # Use compositing and functions set to highlight bone in CT data # Not for use on RGB data colorFun.AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0) colorFun.AddRGBPoint(-16, 0.73, 0.25, 0.30, 0.49, .61) colorFun.AddRGBPoint(641, .90, .82, .56, .5, 0.0) colorFun.AddRGBPoint(3071, 1, 1, 1, .5, 0.0) opacityFun.AddPoint(-3024, 0, 0.5, 0.0) opacityFun.AddPoint(-16, 0, .49, .61) opacityFun.AddPoint(641, .72, .5, 0.0) opacityFun.AddPoint(3071, .71, 0.5, 0.0) mapper.SetBlendModeToComposite() _property.ShadeOn() _property.SetAmbient(0.1) _property.SetDiffuse(0.9) _property.SetSpecular(0.2) _property.SetSpecularPower(10.0) _property.SetScalarOpacityUnitDistance(0.8919) elif blendType == 5: # CT_Muscle # Use compositing and functions set to highlight muscle in CT data # Not for use on RGB data colorFun.AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0) colorFun.AddRGBPoint(-155, .55, .25, .15, 0.5, .92) colorFun.AddRGBPoint(217, .88, .60, .29, 0.33, 0.45) colorFun.AddRGBPoint(420, 1, .94, .95, 0.5, 0.0) colorFun.AddRGBPoint(3071, .83, .66, 1, 0.5, 0.0) opacityFun.AddPoint(-3024, 0, 0.5, 0.0) opacityFun.AddPoint(-155, 0, 0.5, 0.92) opacityFun.AddPoint(217, .68, 0.33, 0.45) opacityFun.AddPoint(420, .83, 0.5, 0.0) opacityFun.AddPoint(3071, .80, 0.5, 0.0) mapper.SetBlendModeToComposite() _property.ShadeOn() _property.SetAmbient(0.1) _property.SetDiffuse(0.9) _property.SetSpecular(0.2) _property.SetSpecularPower(10.0) _property.SetScalarOpacityUnitDistance(0.8919) elif blendType == 6: # RGB_Composite # Use compositing and functions set to highlight red/green/blue regions # in RGB data. Not for use on single component data opacityFun.AddPoint(0, 0.0) opacityFun.AddPoint(5.0, 0.0) opacityFun.AddPoint(30.0, 0.05) opacityFun.AddPoint(31.0, 0.0) opacityFun.AddPoint(90.0, 0.0) opacityFun.AddPoint(100.0, 0.3) opacityFun.AddPoint(110.0, 0.0) opacityFun.AddPoint(190.0, 0.0) opacityFun.AddPoint(200.0, 0.4) opacityFun.AddPoint(210.0, 0.0) opacityFun.AddPoint(245.0, 0.0) opacityFun.AddPoint(255.0, 0.5) mapper.SetBlendModeToComposite() _property.ShadeOff() _property.SetScalarOpacityUnitDistance(1.0) else: print("Unknown blend type.") # Set the default window size renWin.SetSize(600, 600) renWin.Render() # Add the volume to the scene renderer.AddVolume(volume) renderer.ResetCamera() # interact with data renWin.Render() iren.Start() return 0
def _BuildPipeline(self): """_BuildPipeline - Builds the visualization pipeline""" image = component.getUtility(ICurrentImage) # update image (VTK-6 compatible) image.Update() # image reslice object reslice = vtk.vtkImageReslice() reslice.SetInterpolationModeToCubic() reslice.ReleaseDataFlagOn() reslice.SetInputConnection(image.GetOutputPort()) if self._transform: reslice.SetTransform(self._transform) # get extents, spacings, etc in_extent = image.GetExtent() in_spacing = image.GetSpacing() in_origin = image.GetOrigin() # get stencil data stencil_data = image.GetStencilData() # Set image resample factor f = self.gui.m_sliderSurfaceQuality.GetValue() / 100.0 if f == 0.0: f = 0.001 # Set surface decimation factor decf = self.gui.m_sliderDecimationFactor.GetValue() / 100.0 # Enable/Disable stencil usage if self.gui.m_checkBoxClipping.GetValue() is True and stencil_data: if vtk.vtkVersion().GetVTKMajorVersion() > 5: reslice.SetStencilData(stencil_data) else: reslice.SetStencil(stencil_data) reslice.SetBackgroundLevel(image.GetScalarRange()[0]) ext = stencil_data.GetExtent() else: ext = in_extent if vtk.vtkVersion().GetVTKMajorVersion() > 5: reslice.SetStencilData(None) else: reslice.SetStencil(None) # expand extent slightly - account for downsampling later too fudge = int(math.ceil(1.0 / f)) ext = [ ext[0] - fudge, ext[1] + fudge, ext[2] - fudge, ext[3] + fudge, ext[4] - fudge, ext[5] + fudge ] reslice.SetOutputExtent(ext) # set default origin/spacing -- these two lines work... reslice.SetOutputSpacing(in_spacing) reslice.SetOutputOrigin(in_origin) # do we need to downsample the image? if (f < 1.0): resample = vtk.vtkImageResample() resample.SetInputConnection(reslice.GetOutputPort()) resample.ReleaseDataFlagOn() for i in range(3): resample.SetAxisMagnificationFactor(i, f) obj = resample else: obj = reslice # do we need to smooth the image? if (self.gui.m_checkBoxImageSmoothing.GetValue() == True): smooth = vtk.vtkImageGaussianSmooth() smooth.SetStandardDeviation(1.0) smooth.ReleaseDataFlagOn() smooth.SetInputConnection(obj.GetOutputPort()) obj = smooth clip = vtk.vtkImageClip() clip.SetInputConnection(obj.GetOutputPort()) # setup contour filter cf = vtk.vtkMarchingCubes() cf.SetNumberOfContours(1) val = float(self.gui.m_textCtrlImageThreshold.GetValue()) cf.SetValue(0, val) cf.SetComputeScalars(0) cf.SetComputeNormals(0) cf.SetInputConnection(clip.GetOutputPort()) # decimate surface decimate = vtk.vtkDecimatePro() decimate.SetInputConnection(cf.GetOutputPort()) decimate.PreserveTopologyOn() decimate.SetTargetReduction(decf) # To cut down on memory consumption, we use the clip object # to process the image a chunk at a time. By default we # use 20 chunks -- but if the chunks are too small, we'll adjust this # number clip.UpdateInformation() ext = clip.GetInput().GetExtent() # main processing loop with wx.BusyCursor(): event.notify(ProgressEvent("Generating surface...", 0.0)) clip.SetOutputWholeExtent(ext[0], ext[1], ext[2], ext[3], ext[4], ext[5]) decimate.Update() event.notify(ProgressEvent("Generating surface...", 1.0)) # Create the rendered Geometry if not self._app_states[self._current_image_index].GetFactory(): self._app_states[self._current_image_index].SetFactory( vtkAtamai.SurfaceObjectFactory.SurfaceObjectFactory()) self._app_states[ self._current_image_index].GetFactory().SetInputConnection( decimate.GetOutputPort()) self._app_states[ self._current_image_index].GetFactory().SetBackfaceProperty( self._app_states[ self._current_image_index].GetFactory().GetProperty()) self._app_states[ self._current_image_index].GetFactory().NormalGenerationOn() self.SetSurfaceColor() self.GetMicroView().pane3D.ConnectActorFactory( self._app_states[self._current_image_index].GetFactory()) self._app_states[self._current_image_index]._disconnected = False # Update math values self.UpdateMathValues()
def _BuildPipeline(self): """_BuildPipeline - Builds the visualization pipeline""" image = component.getUtility(ICurrentImage) # update image (VTK-6 compatible) image.Update() # image reslice object reslice = vtk.vtkImageReslice() reslice.SetInterpolationModeToCubic() reslice.ReleaseDataFlagOn() reslice.SetInputConnection(image.GetOutputPort()) if self._transform: reslice.SetTransform(self._transform) # get extents, spacings, etc in_extent = image.GetExtent() in_spacing = image.GetSpacing() in_origin = image.GetOrigin() # get stencil data stencil_data = image.GetStencilData() # Set image resample factor f = self.gui.m_sliderSurfaceQuality.GetValue() / 100.0 if f == 0.0: f = 0.001 # Set surface decimation factor decf = self.gui.m_sliderDecimationFactor.GetValue() / 100.0 # Enable/Disable stencil usage if self.gui.m_checkBoxClipping.GetValue() is True and stencil_data: if vtk.vtkVersion().GetVTKMajorVersion() > 5: reslice.SetStencilData(stencil_data) else: reslice.SetStencil(stencil_data) reslice.SetBackgroundLevel(image.GetScalarRange()[0]) ext = stencil_data.GetExtent() else: ext = in_extent if vtk.vtkVersion().GetVTKMajorVersion() > 5: reslice.SetStencilData(None) else: reslice.SetStencil(None) # expand extent slightly - account for downsampling later too fudge = int(math.ceil(1.0 / f)) ext = [ext[0] - fudge, ext[1] + fudge, ext[2] - fudge, ext[3] + fudge, ext[4] - fudge, ext[5] + fudge] reslice.SetOutputExtent(ext) # set default origin/spacing -- these two lines work... reslice.SetOutputSpacing(in_spacing) reslice.SetOutputOrigin(in_origin) # do we need to downsample the image? if f < 1.0: resample = vtk.vtkImageResample() resample.SetInputConnection(reslice.GetOutputPort()) resample.ReleaseDataFlagOn() for i in range(3): resample.SetAxisMagnificationFactor(i, f) obj = resample else: obj = reslice # do we need to smooth the image? if self.gui.m_checkBoxImageSmoothing.GetValue() == True: smooth = vtk.vtkImageGaussianSmooth() smooth.SetStandardDeviation(1.0) smooth.ReleaseDataFlagOn() smooth.SetInputConnection(obj.GetOutputPort()) obj = smooth clip = vtk.vtkImageClip() clip.SetInputConnection(obj.GetOutputPort()) # setup contour filter cf = vtk.vtkMarchingCubes() cf.SetNumberOfContours(1) val = float(self.gui.m_textCtrlImageThreshold.GetValue()) cf.SetValue(0, val) cf.SetComputeScalars(0) cf.SetComputeNormals(0) cf.SetInputConnection(clip.GetOutputPort()) # decimate surface decimate = vtk.vtkDecimatePro() decimate.SetInputConnection(cf.GetOutputPort()) decimate.PreserveTopologyOn() decimate.SetTargetReduction(decf) # To cut down on memory consumption, we use the clip object # to process the image a chunk at a time. By default we # use 20 chunks -- but if the chunks are too small, we'll adjust this # number clip.UpdateInformation() ext = clip.GetInput().GetExtent() # main processing loop with wx.BusyCursor(): event.notify(ProgressEvent("Generating surface...", 0.0)) clip.SetOutputWholeExtent(ext[0], ext[1], ext[2], ext[3], ext[4], ext[5]) decimate.Update() event.notify(ProgressEvent("Generating surface...", 1.0)) # Create the rendered Geometry if not self._app_states[self._current_image_index].GetFactory(): self._app_states[self._current_image_index].SetFactory( vtkAtamai.SurfaceObjectFactory.SurfaceObjectFactory() ) self._app_states[self._current_image_index].GetFactory().SetInputConnection(decimate.GetOutputPort()) self._app_states[self._current_image_index].GetFactory().SetBackfaceProperty( self._app_states[self._current_image_index].GetFactory().GetProperty() ) self._app_states[self._current_image_index].GetFactory().NormalGenerationOn() self.SetSurfaceColor() self.GetMicroView().pane3D.ConnectActorFactory(self._app_states[self._current_image_index].GetFactory()) self._app_states[self._current_image_index]._disconnected = False # Update math values self.UpdateMathValues()
def initView(self, data, widget): image_type = data.getITKImageType() self.image = data.getITKImage() self.space = data.getResolution().tolist() if len(self.space) == 3: self.space = [float(x) / self.space[-1] for x in self.space] self.image.SetSpacing(self.space) self.rescale_filter = itk.RescaleIntensityImageFilter[image_type, image_type].New() self.rescale_filter.SetOutputMinimum(0) self.rescale_filter.SetOutputMaximum(255) self.rescale_filter.SetInput(self.image) self.itk_vtk_converter = itk.ImageToVTKImageFilter[image_type].New() self.itk_vtk_converter.SetInput(self.rescale_filter.GetOutput()) self.image_resample = vtk.vtkImageResample() self.image_resample.SetInput(self.itk_vtk_converter.GetOutput()) data = self.parent.getData() image_type = data.getITKImageType() self.image2 = data.getITKImage() self.space2 = data.getResolution().tolist() if len(self.space2) == 3: self.space2 = [float(x) / self.space2[-1] for x in self.space2] self.image2.SetSpacing(self.space2) shapeList = data.getData().shape y, x = shapeList[-2], shapeList[-1] self.dimension = len(shapeList) == 2 self.rescale_filter2 = itk.RescaleIntensityImageFilter[image_type, image_type].New() self.rescale_filter2.SetOutputMinimum(0) self.rescale_filter2.SetOutputMaximum(255) self.rescale_filter2.SetInput(self.image2) self.itk_vtk_converter2 = itk.ImageToVTKImageFilter[image_type].New() self.itk_vtk_converter2.SetInput(self.rescale_filter2.GetOutput()) self.image_resample2 = vtk.vtkImageResample() self.image_resample2.SetInput(self.itk_vtk_converter2.GetOutput()) self.checkers = vtk.vtkImageCheckerboard() self.checkers.SetInput1(self.image_resample.GetOutput()) self.checkers.SetInput2(self.image_resample2.GetOutput()) self.division = 3 self.checkers.SetNumberOfDivisions(self.division, self.division, 0) self.renderer = vtk.vtkRenderer() self.render_window = widget.GetRenderWindow() self.render_window.AddRenderer(self.renderer) self.reslice_mapper = vtk.vtkImageResliceMapper() self.reslice_mapper.SetInput(self.checkers.GetOutput()) self.reslice_mapper.SliceFacesCameraOn() self.reslice_mapper.SliceAtFocalPointOn() self.reslice_mapper.JumpToNearestSliceOn() self.reslice_mapper.BorderOff() self.reslice_mapper.BackgroundOn() array = data.getData() self.minI = 0 self.maxI = 255 image_property = vtk.vtkImageProperty() image_property.SetColorWindow(self.maxI - self.minI) image_property.SetColorLevel((self.maxI + self.minI) / 2.0) image_property.SetAmbient(0.0) image_property.SetDiffuse(1.0) image_property.SetOpacity(1.0) image_property.SetInterpolationTypeToLinear() self.image_slice = vtk.vtkImageSlice() self.image_slice.SetMapper(self.reslice_mapper) self.image_slice.SetProperty(image_property) self.renderer.AddViewProp(self.image_slice) self.window_interactor = vtk.vtkRenderWindowInteractor() self.interactor_style = vtk.vtkInteractorStyleImage() self.interactor_style.SetInteractionModeToImage3D() self.window_interactor.SetInteractorStyle(self.interactor_style) self.render_window.SetInteractor(self.window_interactor) point_picker = vtk.vtkPointPicker() self.window_interactor.SetPicker(point_picker) self.render_window.GlobalWarningDisplayOff() self.render_window.Render() self.camera = self.renderer.GetActiveCamera() self.camera.ParallelProjectionOn() w, h = self.window_interactor.GetSize() if h * x * self.space[0] < w * y * self.space[1]: scale = y / 2.0 * self.space[1] else: scale = h * x * self.space[0] / 2.0 / w self.camera.SetParallelScale(scale) point = self.camera.GetFocalPoint() dis = self.camera.GetDistance() self.camera.SetViewUp(0, -1, 0) self.camera.SetPosition(point[0], point[1], point[2] - dis) self.renderer.ResetCameraClippingRange() # View of image self.view = 2 self.interactor_style.AddObserver("MouseMoveEvent", self.MouseMoveCallback) self.interactor_style.AddObserver("LeftButtonReleaseEvent", self.LeftButtonReleaseCallback) self.interactor_style.AddObserver("LeftButtonPressEvent", self.LeftButtonPressCallback) self.interactor_style.AddObserver("MiddleButtonPressEvent", self.MiddleButtonPressCallback) self.interactor_style.AddObserver("RightButtonPressEvent", self.RightButtonPressCallback) self.interactor_style.AddObserver("RightButtonReleaseEvent", self.RightButtonReleaseCallback) self.interactor_style.AddObserver("KeyPressEvent", self.KeyPressCallback) self.interactor_style.AddObserver("CharEvent", self.CharCallback) self.updateAfter() self.render_window.Render()
#!/usr/bin/env python import vtk from vtk.util.misc import vtkGetDataRoot VTK_DATA_ROOT = vtkGetDataRoot() # Doubles the The number of images (x dimension). # Image pipeline reader = vtk.vtkImageReader() reader.ReleaseDataFlagOff() reader.SetDataByteOrderToLittleEndian() reader.SetDataExtent(0, 63, 0, 63, 1, 93) reader.SetDataSpacing(3.2, 3.2, 1.5) reader.SetFilePrefix("" + str(VTK_DATA_ROOT) + "/Data/headsq/quarter") reader.SetDataMask(0x7fff) magnify = vtk.vtkImageResample() magnify.SetDimensionality(3) magnify.SetInputConnection(reader.GetOutputPort()) magnify.SetAxisOutputSpacing(0, 0.52) magnify.SetAxisOutputSpacing(1, 2.2) magnify.SetAxisOutputSpacing(2, 0.8) magnify.ReleaseDataFlagOff() viewer = vtk.vtkImageViewer() viewer.SetInputConnection(magnify.GetOutputPort()) viewer.SetZSlice(30) viewer.SetColorWindow(2000) viewer.SetColorLevel(1000) viewer.Render() # --- end of script --
def extractT2texture(self, t_T2image, image_pos_pat, image_ori_pat, VOI_mesh, patchdirname): ################################### # Haralick et al. defined 10 grey-level co-occurrence matrix (GLCM) enhancement features # 3D textrue features # self = funcD # T2image = self.load.T2Images # image_pos_pat = self.load.T2image_pos_pat # image_ori_pat = self.load.T2image_ori_pat # VOI_mesh = funcD.lesion3D # loadDisplay = funcD.loadDisplay ## Transform T2 img #localloadDisplay = Display() # Proceed to build reference frame for display objects based on DICOM coords #[t_T2image, transform_cube] = loadDisplay.dicomTransform(T2image, image_pos_pat, image_ori_pat) # Update info t_T2image.UpdateInformation() print "\nLoading VOI_mesh MASK... " VOIPnt = [0,0,0]; pixVals_margin = []; pixVals = [] #################### TO NUMPY VOI_scalars = t_T2image.GetPointData().GetScalars() np_VOI_imagedata = vtk_to_numpy(VOI_scalars) dims = t_T2image.GetDimensions() spacing = t_T2image.GetSpacing() np_VOI_imagedata = np_VOI_imagedata.reshape(dims[2], dims[1], dims[0]) np_VOI_imagedata = array(np_VOI_imagedata.transpose(2,1,0)) #****************************" print "Normalizing data..." np_VOI_imagedataflat = np_VOI_imagedata.flatten().astype(float) np_VOI_imagedata_num = (np_VOI_imagedataflat-min(np_VOI_imagedataflat)) np_VOI_imagedata_den = (max(np_VOI_imagedataflat)-min(np_VOI_imagedataflat)) np_VOI_imagedata_flatten = 255*(np_VOI_imagedata_num/np_VOI_imagedata_den) np_VOI_imagedata = np_VOI_imagedata_flatten.reshape(dims[0], dims[1], dims[2]) # Prepare lesion localization and PATCH size for Texture analysis # lesion_centroid lesionBox = VOI_mesh.GetBounds() self.boxWidget.PlaceWidget( lesionBox ) self.boxWidget.On() deltax = lesionBox[1] - lesionBox[0] print deltax deltay = lesionBox[3]-lesionBox[2] print deltay deltaz = lesionBox[5]-lesionBox[4] print deltaz # find largest dimension and use that for lesion radius if deltax > deltay: lesion_dia = deltax/spacing[0] print "deltax was largest %d... " % lesion_dia else: lesion_dia = deltay/spacing[1] print "deltay was largest %d... " % lesion_dia lesion_radius = lesion_dia/2 lesionthick = deltaz/spacing[2]/2 print "VOI_efect_diameter %s... " % str(lesion_radius) lesion_location = VOI_mesh.GetCenter() print "lesion_location %s... " % str(lesion_location) lesion_patches = [] ######### translate lesion location to ijk coordinates # sub_pre_transformed_image.FindPoint(lesion_location pixId = t_T2image.FindPoint(lesion_location[0], lesion_location[1], lesion_location[2]) sub_pt = [0,0,0] t_T2image.GetPoint(pixId, sub_pt) ijk = [0,0,0] pco = [0,0,0] inorout = t_T2image.ComputeStructuredCoordinates( sub_pt, ijk, pco) print "coresponding ijk_vtk indices:" print ijk ijk_vtk = ijk # Perform texture classification using grey level co-occurrence matrices (GLCMs). # A GLCM is a histogram of co-occurring greyscale values at a given offset over an image. # compute some GLCM properties each patch # p(i,j) is the (i,j)th entry in a normalized spatial gray-level dependence matrix; lesion_patches = np_VOI_imagedata[ int(ijk_vtk[0] - lesion_radius-1):int(ijk_vtk[0] + lesion_radius+1), int(ijk_vtk[1] - lesion_radius-1):int(ijk_vtk[1] + lesion_radius), int(ijk_vtk[2] - lesionthick/2-1):int(ijk_vtk[2] + lesionthick/2+1) ] print '\n Lesion_patches:' print lesion_patches #################### RESAMPLE TO ISOTROPIC # pass to vtk lesion_patches_shape = lesion_patches.shape vtklesion_patches = lesion_patches.transpose(2,1,0) vtklesion_patches_data = numpy_to_vtk(num_array=vtklesion_patches.ravel(), deep=True, array_type=vtk.VTK_FLOAT) # probe into the unstructured grid using ImageData geometry vtklesion_patches = vtk.vtkImageData() vtklesion_patches.SetExtent(0,lesion_patches_shape[0]-1,0,lesion_patches_shape[1]-1,0,lesion_patches_shape[2]-1) vtklesion_patches.SetOrigin(0,0,0) vtklesion_patches.SetSpacing(spacing) vtklesion_patches.GetPointData().SetScalars(vtklesion_patches_data) # write #################### isowriter = vtk.vtkMetaImageWriter() isowriter.SetInput(vtklesion_patches) isowriter.SetFileName(patchdirname+"_T2w.mha") isowriter.Write() isopix = mean(vtklesion_patches.GetSpacing()) resample = vtk.vtkImageResample () resample.SetInput( vtklesion_patches ) resample.SetAxisOutputSpacing( 0, isopix ) resample.SetAxisOutputSpacing( 1, isopix ) resample.SetAxisOutputSpacing( 2, isopix ) resample.Update() isoImage = resample.GetOutput() #################### get isotropic patches ISO_scalars = isoImage.GetPointData().GetScalars() np_ISO_Image = vtk_to_numpy(ISO_scalars) isodims = isoImage.GetDimensions() isospacing = isoImage.GetSpacing() np_ISO_Imagedata = np_ISO_Image.reshape(isodims[2], isodims[1], isodims[0]) np_ISO_Imagedata = array(np_ISO_Imagedata.transpose(2,1,0)) #################### save isotropic patches fig = plt.figure() # patch histogram ax1 = fig.add_subplot(221) n, bins, patches = plt.hist(array(np_ISO_Imagedata.flatten()), 50, normed=1, facecolor='green', alpha=0.75) ax1.set_ylabel('histo') ax2 = fig.add_subplot(222) plt.imshow(np_ISO_Imagedata[:,:,np_ISO_Imagedata.shape[2]/2]) plt.gray() ax2.set_ylabel('iso: '+str(isodims) ) ax3 = fig.add_subplot(223) plt.imshow(lesion_patches[:,:,lesion_patches.shape[2]/2]) plt.gray() ax3.set_ylabel('original: '+str(lesion_patches_shape)) ax4 = fig.add_subplot(224) plt.imshow(np_VOI_imagedata[:,:,ijk_vtk[2]]) plt.gray() ax4.set_ylabel('lesion centroid(ijk): '+str(ijk_vtk)) # FInally display # plt.show() plt.savefig(patchdirname+'_T2w.png', format='png') #################### #################### 3D GLCM from graycomatrix3D import glcm3d patch = np_ISO_Imagedata.astype(np.uint8) lev = int(patch.max()+1) # levels # perfor glmc extraction in all 13 directions in 3D pixel neighbors g1 = glcm3d(lev, patch, offsets=[0,0,1]) # orientation 0 degrees (example same slices: equal to Nslices*0degree 2D case) g2 = glcm3d(lev, patch, offsets=[0,1,-1]) # orientation 45 degrees (example same slices: equal to Nslices*45degree 2D case) g3 = glcm3d(lev, patch, offsets=[0,1,0]) # orientation 90 degrees (example same slices: equal to Nslices*90degree 2D case) g4 = glcm3d(lev, patch, offsets=[0,1,1]) # orientation 135 degrees (example same slices: equal to Nslices*135degree 2D case) g5 = glcm3d(lev, patch, offsets=[1,0,-1]) # 0 degrees/45 degrees (example same slices: equal to (Nslices-1)*0degree 2D case) g6 = glcm3d(lev, patch, offsets=[1,0,0]) # straight up (example same slices: equal to np.unique()) g7 = glcm3d(lev, patch, offsets=[1,0,1]) # 0 degree/135 degrees (example same slices: equal to (Nslices-1)*transpose of 0degree 2D case) g8 = glcm3d(lev, patch, offsets=[1,1,0]) # 90 degrees/45 degrees (example same slices: equal to (Nslices-1)*90 degree 2D case) g9 = glcm3d(lev, patch, offsets=[1,-1,0]) # 90 degrees/135 degrees (example same slices: equal to (Nslices-1)*transpose of 90 degree 2D case) g10 = glcm3d(lev, patch, offsets=[1,1,-1]) # 45 degrees/45 degrees (example same slices: equal to (Nslices-1)*45 degree 2D case) g11 = glcm3d(lev, patch, offsets=[1,-1,1]) # 45 degree/135 degrees (example same slices: equal to (Nslices-1)*transpose of 45 degree 2D case) g12 = glcm3d(lev, patch, offsets=[1,1,1]) # 135 degrees/45 degrees (example same slices: equal to (Nslices-1)*135 degree 2D case) g13 = glcm3d(lev, patch, offsets=[0,0,1]) # 135 degrees/135 degrees (example same slices: equal to (Nslices-1)*transpose of 135 degree 2D case) # plot fig = plt.figure() fig.add_subplot(431); plt.imshow(g1); plt.gray() fig.add_subplot(432); plt.imshow(g2); plt.gray() fig.add_subplot(433); plt.imshow(g3); plt.gray() fig.add_subplot(434); plt.imshow(g4); plt.gray() fig.add_subplot(435); plt.imshow(g5); plt.gray() fig.add_subplot(436); plt.imshow(g6); plt.gray() fig.add_subplot(437); plt.imshow(g7); plt.gray() fig.add_subplot(438); plt.imshow(g8); plt.gray() # add all directions to make features non-directional g = g1+g2+g3+g4+g5+g6+g7+g8+g9+g10+g11+g12+g13 fig.add_subplot(439); plt.imshow(g); plt.gray() #plt.show() ### glcm normalization ### if g.sum() != 0: g = g.astype(float)/g.sum() ### compute auxiliary variables ### (num_level, num_level2) = g.shape I, J = np.ogrid[0:num_level, 0:num_level] I = 1+ np.array(range(num_level)).reshape((num_level, 1)) J = 1+ np.array(range(num_level)).reshape((1, num_level)) diff_i = I - np.apply_over_axes(np.sum, (I * g), axes=(0, 1))[0, 0] diff_j = J - np.apply_over_axes(np.sum, (J * g), axes=(0, 1))[0, 0] std_i = np.sqrt(np.apply_over_axes(np.sum, (g * (diff_i) ** 2),axes=(0, 1))[0, 0]) std_j = np.sqrt(np.apply_over_axes(np.sum, (g * (diff_j) ** 2),axes=(0, 1))[0, 0]) cov = np.apply_over_axes(np.sum, (g * (diff_i * diff_j)),axes=(0, 1))[0, 0] gxy = np.zeros(2*g.shape[0]-1) ### g x+y gx_y = np.zeros(g.shape[0]) ### g x-y for i in xrange(g.shape[0]): for j in xrange(g.shape[0]): gxy[i+j] += g[i,j] gx_y[np.abs(i-j)] += g[i,j] mx_y = (gx_y*np.arange(len(gx_y))).sum() v = np.zeros(11) i,j = np.indices(g.shape)+1 ii = np.arange(len(gxy))+2 ii_ = np.arange(len(gx_y)) ### compute descriptors ### v[0] = np.apply_over_axes(np.sum, (g ** 2), axes=(0, 1))[0, 0] # energy or Angular second moment v[1] = np.apply_over_axes(np.sum, (g * ((I - J) ** 2)), axes=(0, 1))[0, 0] # Contrast if std_i>1e-15 and std_j>1e-15: # handle the special case of standard deviations near zero v[2] = cov/(std_i*std_j)#v[2] = greycoprops(g,'correlation') # Correlation else: v[2] = 1 v[3] = np.apply_over_axes(np.sum, (g* (diff_i) ** 2),axes=(0, 1))[0, 0]# Variance or Sum of squares v[4] = np.sum(g * (1. / (1. + (I - J) ** 2))) # Inverse difference moment v[5] = (gxy*ii).sum() # Sum average v[6] = ((ii-v[5])*(ii-v[5])*gxy).sum() # Sum variance v[7] = -1*(gxy*np.log10(gxy+ np.spacing(1))).sum() # Sum entropy v[8] = -1*(g*np.log10(g+np.spacing(1))).sum() # Entropy v[9] = ((ii_-mx_y)*(ii_-mx_y)*gx_y).sum() # Difference variance v[10] = -1*(gx_y*np.log10(gx_y++np.spacing(1))).sum() # Difference entropy # writing to file from row_lesionID Drow_PathRepID ################################################## # writing to file from row_lesionID Drow_PathRepID print "\n Append texture features for each post contrast" [self.T2texture_energy_nondir, self.T2texture_contrast_nondir, self.T2texture_correlation_nondir, self.T2texture_variance_nondir, self.T2texture_inversediffmoment_nondir, self.T2texture_sumaverage_nondir, self.T2texture_sumvariance_nondir, self.T2texture_sumentropy_nondir, self.T2texture_entropy_nondir, self.T2texture_diffvariance_nondir,self.T2texture_diffentropy_nondir] = v ################################################## # orgamize into dataframe self.textureT2Features = DataFrame( data=array([[ self.T2texture_energy_nondir, self.T2texture_contrast_nondir, self.T2texture_correlation_nondir, self.T2texture_variance_nondir, self.T2texture_inversediffmoment_nondir, self.T2texture_sumaverage_nondir, self.T2texture_sumvariance_nondir, self.T2texture_sumentropy_nondir, self.T2texture_entropy_nondir, self.T2texture_diffvariance_nondir,self.T2texture_diffentropy_nondir ]]), columns=['texture_energy_nondir','texture_contrast_nondir','texture_correlation_nondir', 'texture_variance_nondir', 'texture_inversediffmoment_nondir', 'texture_sumaverage_nondir', 'texture_sumvariance_nondir', 'texture_sumentropy_nondir', 'texture_entropy_nondir', 'texture_diffvariance_nondir', 'texture_diffentropy_nondir']) return self.textureT2Features
def run(self): grouper = self.grouper reader = gdcm.ImageReader() reader.SetFileName(self.filepath) if (reader.Read()): file = reader.GetFile() # Retrieve data set dataSet = file.GetDataSet() # Retrieve header header = file.GetHeader() stf = gdcm.StringFilter() field_dict = {} data_dict = {} tag = gdcm.Tag(0x0008, 0x0005) ds = reader.GetFile().GetDataSet() if ds.FindDataElement(tag): encoding_value = str(ds.GetDataElement(tag).GetValue()).split('\\')[0] if encoding_value.startswith("Loaded"): encoding = "ISO_IR 100" else: try: encoding = const.DICOM_ENCODING_TO_PYTHON[encoding_value] except KeyError: encoding = 'ISO_IR 100' else: encoding = "ISO_IR 100" # Iterate through the Header iterator = header.GetDES().begin() while (not iterator.equal(header.GetDES().end())): dataElement = iterator.next() stf.SetFile(file) tag = dataElement.GetTag() data = stf.ToStringPair(tag) stag = tag.PrintAsPipeSeparatedString() group = str(tag.GetGroup()) field = str(tag.GetElement()) tag_labels[stag] = data[0] if not group in data_dict.keys(): data_dict[group] = {} if not(utils.VerifyInvalidPListCharacter(data[1])): data_dict[group][field] = data[1].decode(encoding) else: data_dict[group][field] = "Invalid Character" # Iterate through the Data set iterator = dataSet.GetDES().begin() while (not iterator.equal(dataSet.GetDES().end())): dataElement = iterator.next() stf.SetFile(file) tag = dataElement.GetTag() data = stf.ToStringPair(tag) stag = tag.PrintAsPipeSeparatedString() group = str(tag.GetGroup()) field = str(tag.GetElement()) tag_labels[stag] = data[0] if not group in data_dict.keys(): data_dict[group] = {} if not(utils.VerifyInvalidPListCharacter(data[1])): data_dict[group][field] = data[1].decode(encoding, 'replace') else: data_dict[group][field] = "Invalid Character" # -------------- To Create DICOM Thumbnail ----------- rvtk = vtkgdcm.vtkGDCMImageReader() rvtk.SetFileName(self.filepath) rvtk.Update() try: data = data_dict[str(0x028)][str(0x1050)] level = [float(value) for value in data.split('\\')][0] data = data_dict[str(0x028)][str(0x1051)] window = [float(value) for value in data.split('\\')][0] except(KeyError): level = 300.0 window = 2000.0 colorer = vtk.vtkImageMapToWindowLevelColors() colorer.SetInput(rvtk.GetOutput()) colorer.SetWindow(float(window)) colorer.SetLevel(float(level)) colorer.SetOutputFormatToRGB() colorer.Update() resample = vtk.vtkImageResample() resample.SetInput(colorer.GetOutput()) resample.SetAxisMagnificationFactor ( 0, 0.25 ) resample.SetAxisMagnificationFactor ( 1, 0.25 ) resample.SetAxisMagnificationFactor ( 2, 1 ) resample.Update() thumbnail_path = tempfile.mktemp() write_png = vtk.vtkPNGWriter() write_png.SetInput(resample.GetOutput()) write_png.SetFileName(thumbnail_path) write_png.Write() #------ Verify the orientation -------------------------------- img = reader.GetImage() direc_cosines = img.GetDirectionCosines() orientation = gdcm.Orientation() try: type = orientation.GetType(tuple(direc_cosines)) except TypeError: type = orientation.GetType(direc_cosines) label = orientation.GetLabel(type) # ---------- Refactory -------------------------------------- data_dict['invesalius'] = {'orientation_label' : label} # ------------------------------------------------------------- dict_file[self.filepath] = data_dict #---------- Verify is DICOMDir ------------------------------- is_dicom_dir = 1 try: if (data_dict[str(0x002)][str(0x002)] != "1.2.840.10008.1.3.10"): #DICOMDIR is_dicom_dir = 0 except(KeyError): is_dicom_dir = 0 if not(is_dicom_dir): parser = dicom.Parser() parser.SetDataImage(dict_file[self.filepath], self.filepath, thumbnail_path) dcm = dicom.Dicom() #self.l.acquire() dcm.SetParser(parser) grouper.AddFile(dcm)
def extractfeatures(self, DICOMImages, image_pos_pat, image_ori_pat, series_path, phases_series, VOI_mesh, VOI_efect_diameter, lesion_centroid, patchdirname): ################################### # Haralick et al. defined 10 grey-level co-occurrence matrix (GLCM) enhancement features (energy, maximum probability, contrast, homogeneity, entropy, correlation, sum average, sum variance, difference average and difference variance) to describe texture # N is the number of distinct gray levels in the histogram equalized image; allglcmdesc = [] for postt in range(1,len(DICOMImages)): # obtain vols of interest subtractedImage = Display().subImage(DICOMImages, postt) [sub_pre_transformed_image, transform_cube] = Display().dicomTransform(subtractedImage, image_pos_pat, image_ori_pat) print "\nLoading VOI_mesh MASK for Series %s... " % str(postt) VOIPnt = [0,0,0]; pixVals_margin = []; pixVals = [] #################### TO NUMPY VOI_scalars = sub_pre_transformed_image.GetPointData().GetScalars() np_VOI_imagedata = vtk_to_numpy(VOI_scalars) dims = sub_pre_transformed_image.GetDimensions() spacing = sub_pre_transformed_image.GetSpacing() np_VOI_imagedata = np_VOI_imagedata.reshape(dims[2], dims[1], dims[0]) np_VOI_imagedata = array(np_VOI_imagedata.transpose(2,1,0)) #****************************" print "Normalizing data..." np_VOI_imagedataflat = np_VOI_imagedata.flatten().astype(float) np_VOI_imagedata_num = (np_VOI_imagedataflat-min(np_VOI_imagedataflat)) np_VOI_imagedata_den = (max(np_VOI_imagedataflat)-min(np_VOI_imagedataflat)) np_VOI_imagedata_flatten = 255*(np_VOI_imagedata_num/np_VOI_imagedata_den) np_VOI_imagedata = np_VOI_imagedata_flatten.reshape(dims[0], dims[1], dims[2]) lesion_patches = [] # Prepare lesion localization and PATCH size for Texture analysis # lesion_centroid lesion_radius = VOI_efect_diameter/(spacing[0]) lesionthick = VOI_efect_diameter/(spacing[2]) print "VOI_efect_diameter %s... " % str(lesion_radius) lesion_location = lesion_centroid print "lesion_location %s... " % str(lesion_location) ######### translate lesion location to ijk coordinates # sub_pre_transformed_image.FindPoint(lesion_location pixId = sub_pre_transformed_image.FindPoint(lesion_location[0], lesion_location[1], lesion_location[2]) sub_pt = [0,0,0] sub_pre_transformed_image.GetPoint(pixId, sub_pt) ijk = [0,0,0] pco = [0,0,0] inorout = sub_pre_transformed_image.ComputeStructuredCoordinates( sub_pt, ijk, pco) print "coresponding ijk_vtk indices:" print ijk ijk_vtk = ijk # Perform texture classification using grey level co-occurrence matrices (GLCMs). # A GLCM is a histogram of co-occurring greyscale values at a given offset over an image. # compute some GLCM properties each patch # p(i,j) is the (i,j)th entry in a normalized spatial gray-level dependence matrix; lesion_patches = [] lesion_patches = np_VOI_imagedata[ int(ijk_vtk[0] - lesion_radius-1):int(ijk_vtk[0] + lesion_radius+1), int(ijk_vtk[1] - lesion_radius-1):int(ijk_vtk[1] + lesion_radius), int(ijk_vtk[2] - lesionthick-1):int(ijk_vtk[2] + lesionthick+1) ] print '\n Lesion_patches:' print lesion_patches #################### RESAMPLE TO ISOTROPIC # pass to vtk lesion_patches_shape = lesion_patches.shape vtklesion_patches = lesion_patches.transpose(2,1,0) vtklesion_patches_data = numpy_to_vtk(num_array=vtklesion_patches.ravel(), deep=True, array_type=vtk.VTK_FLOAT) # probe into the unstructured grid using ImageData geometry vtklesion_patches = vtk.vtkImageData() vtklesion_patches.SetExtent(0,lesion_patches_shape[0]-1,0,lesion_patches_shape[1]-1,0,lesion_patches_shape[2]-1) vtklesion_patches.SetOrigin(0,0,0) vtklesion_patches.SetSpacing(spacing) vtklesion_patches.GetPointData().SetScalars(vtklesion_patches_data) # write #################### isowriter = vtk.vtkMetaImageWriter() isowriter.SetInput(vtklesion_patches) isowriter.SetFileName(patchdirname+"_"+str(postt)+".mha") isowriter.Write() isopix = mean(vtklesion_patches.GetSpacing()) resample = vtk.vtkImageResample () resample.SetInput( vtklesion_patches ) resample.SetAxisOutputSpacing( 0, isopix ) resample.SetAxisOutputSpacing( 1, isopix ) resample.SetAxisOutputSpacing( 2, isopix ) resample.Update() isoImage = resample.GetOutput() #################### get isotropic patches ISO_scalars = isoImage.GetPointData().GetScalars() np_ISO_Image = vtk_to_numpy(ISO_scalars) isodims = isoImage.GetDimensions() isospacing = isoImage.GetSpacing() np_ISO_Imagedata = np_ISO_Image.reshape(isodims[2], isodims[1], isodims[0]) np_ISO_Imagedata = array(np_ISO_Imagedata.transpose(2,1,0)) #################### save isotropic patches fig = plt.figure() # patch histogram ax1 = fig.add_subplot(221) n, bins, patches = plt.hist(array(np_ISO_Imagedata.flatten()), 50, normed=1, facecolor='green', alpha=0.75) ax1.set_ylabel('histo') ax2 = fig.add_subplot(222) plt.imshow(np_ISO_Imagedata[:,:,np_ISO_Imagedata.shape[2]/2]) plt.gray() ax2.set_ylabel('iso: '+str(isodims) ) ax3 = fig.add_subplot(223) plt.imshow(lesion_patches[:,:,lesion_patches.shape[2]/2]) plt.gray() ax3.set_ylabel('original: '+str(lesion_patches_shape)) ax4 = fig.add_subplot(224) plt.imshow(np_VOI_imagedata[:,:,ijk_vtk[2]]) plt.gray() ax4.set_ylabel('lesion centroid(ijk): '+str(ijk_vtk)) # FInally display # plt.show() plt.savefig(patchdirname+"_"+str(postt)+'.png', format='png') #################### #################### 3D GLCM from graycomatrix3D import glcm3d patch = np_ISO_Imagedata.astype(np.uint8) lev = int(patch.max()+1) # levels # perfor glmc extraction in all 13 directions in 3D pixel neighbors g1 = glcm3d(lev, patch, offsets=[0,0,1]) # orientation 0 degrees (example same slices: equal to Nslices*0degree 2D case) g2 = glcm3d(lev, patch, offsets=[0,1,-1]) # orientation 45 degrees (example same slices: equal to Nslices*45degree 2D case) g3 = glcm3d(lev, patch, offsets=[0,1,0]) # orientation 90 degrees (example same slices: equal to Nslices*90degree 2D case) g4 = glcm3d(lev, patch, offsets=[0,1,1]) # orientation 135 degrees (example same slices: equal to Nslices*135degree 2D case) g5 = glcm3d(lev, patch, offsets=[1,0,-1]) # 0 degrees/45 degrees (example same slices: equal to (Nslices-1)*0degree 2D case) g6 = glcm3d(lev, patch, offsets=[1,0,0]) # straight up (example same slices: equal to np.unique()) g7 = glcm3d(lev, patch, offsets=[1,0,1]) # 0 degree/135 degrees (example same slices: equal to (Nslices-1)*transpose of 0degree 2D case) g8 = glcm3d(lev, patch, offsets=[1,1,0]) # 90 degrees/45 degrees (example same slices: equal to (Nslices-1)*90 degree 2D case) g9 = glcm3d(lev, patch, offsets=[1,-1,0]) # 90 degrees/135 degrees (example same slices: equal to (Nslices-1)*transpose of 90 degree 2D case) g10 = glcm3d(lev, patch, offsets=[1,1,-1]) # 45 degrees/45 degrees (example same slices: equal to (Nslices-1)*45 degree 2D case) g11 = glcm3d(lev, patch, offsets=[1,-1,1]) # 45 degree/135 degrees (example same slices: equal to (Nslices-1)*transpose of 45 degree 2D case) g12 = glcm3d(lev, patch, offsets=[1,1,1]) # 135 degrees/45 degrees (example same slices: equal to (Nslices-1)*135 degree 2D case) g13 = glcm3d(lev, patch, offsets=[0,0,1]) # 135 degrees/135 degrees (example same slices: equal to (Nslices-1)*transpose of 135 degree 2D case) # plot fig = plt.figure() fig.add_subplot(431); plt.imshow(g1); plt.gray() fig.add_subplot(432); plt.imshow(g2); plt.gray() fig.add_subplot(433); plt.imshow(g3); plt.gray() fig.add_subplot(434); plt.imshow(g4); plt.gray() fig.add_subplot(435); plt.imshow(g5); plt.gray() fig.add_subplot(436); plt.imshow(g6); plt.gray() fig.add_subplot(437); plt.imshow(g7); plt.gray() fig.add_subplot(438); plt.imshow(g8); plt.gray() # add all directions to make features non-directional g = g1+g2+g3+g4+g5+g6+g7+g8+g9+g10+g11+g12+g13 fig.add_subplot(439); plt.imshow(g); plt.gray() #plt.show() ### glcm normalization ### if g.sum() != 0: g = g.astype(float)/g.sum() ### compute auxiliary variables ### (num_level, num_level2) = g.shape I, J = np.ogrid[0:num_level, 0:num_level] I = 1+ np.array(range(num_level)).reshape((num_level, 1)) J = 1+ np.array(range(num_level)).reshape((1, num_level)) diff_i = I - np.apply_over_axes(np.sum, (I * g), axes=(0, 1))[0, 0] diff_j = J - np.apply_over_axes(np.sum, (J * g), axes=(0, 1))[0, 0] std_i = np.sqrt(np.apply_over_axes(np.sum, (g * (diff_i) ** 2),axes=(0, 1))[0, 0]) std_j = np.sqrt(np.apply_over_axes(np.sum, (g * (diff_j) ** 2),axes=(0, 1))[0, 0]) cov = np.apply_over_axes(np.sum, (g * (diff_i * diff_j)),axes=(0, 1))[0, 0] gxy = np.zeros(2*g.shape[0]-1) ### g x+y gx_y = np.zeros(g.shape[0]) ### g x-y for i in xrange(g.shape[0]): for j in xrange(g.shape[0]): gxy[i+j] += g[i,j] gx_y[np.abs(i-j)] += g[i,j] mx_y = (gx_y*np.arange(len(gx_y))).sum() v = np.zeros(11) i,j = np.indices(g.shape)+1 ii = np.arange(len(gxy))+2 ii_ = np.arange(len(gx_y)) ### compute descriptors ### v[0] = np.apply_over_axes(np.sum, (g ** 2), axes=(0, 1))[0, 0] # energy or Angular second moment v[1] = np.apply_over_axes(np.sum, (g * ((I - J) ** 2)), axes=(0, 1))[0, 0] # Contrast if std_i>1e-15 and std_j>1e-15: # handle the special case of standard deviations near zero v[2] = cov/(std_i*std_j)#v[2] = greycoprops(g,'correlation') # Correlation else: v[2] = 1 v[3] = np.apply_over_axes(np.sum, (g* (diff_i) ** 2),axes=(0, 1))[0, 0]# Variance or Sum of squares v[4] = np.sum(g * (1. / (1. + (I - J) ** 2))) # Inverse difference moment v[5] = (gxy*ii).sum() # Sum average v[6] = ((ii-v[5])*(ii-v[5])*gxy).sum() # Sum variance v[7] = -1*(gxy*np.log10(gxy+ np.spacing(1))).sum() # Sum entropy v[8] = -1*(g*np.log10(g+np.spacing(1))).sum() # Entropy v[9] = ((ii_-mx_y)*(ii_-mx_y)*gx_y).sum() # Difference variance v[10] = -1*(gx_y*np.log10(gx_y++np.spacing(1))).sum() # Difference entropy """TEXTURE FEATURES accumulated""" allglcmdesc = append(allglcmdesc, v) ################################################## # writing to file from row_lesionID Drow_PathRepID print "\n Append texture features for each post contrast" [self.texture_energy_nondir_post1, self.texture_contrast_nondir_post1, self.texture_correlation_nondir_post1, self.texture_variance_nondir_post1, self.texture_inversediffmoment_nondir_post1, self.texture_sumaverage_nondir_post1, self.texture_sumvariance_nondir_post1, self.texture_sumentropy_nondir_post1, self.texture_entropy_nondir_post1, self.texture_diffvariance_nondir_post1,self.texture_diffentropy_nondir_post1] = allglcmdesc[0:11] [self.texture_energy_nondir_post2, self.texture_contrast_nondir_post2, self.texture_correlation_nondir_post2, self.texture_variance_nondir_post2, self.texture_inversediffmoment_nondir_post2, self.texture_sumaverage_nondir_post2, self.texture_sumvariance_nondir_post2, self.texture_sumentropy_nondir_post2, self.texture_entropy_nondir_post2, self.texture_diffvariance_nondir_post2, self.texture_diffentropy_nondir_post2] = allglcmdesc[11:22] [self.texture_energy_nondir_post3, self.texture_contrast_nondir_post3, self.texture_correlation_nondir_post3, self.texture_variance_nondir_post3, self.texture_inversediffmoment_nondir_post3, self.texture_sumaverage_nondir_post3, self.texture_sumvariance_nondir_post3, self.texture_sumentropy_nondir_post3, self.texture_entropy_nondir_post3, self.texture_diffvariance_nondir_post3, self.texture_diffentropy_nondir_post3] = allglcmdesc[22:33] [self.texture_energy_nondir_post4, self.texture_contrast_nondir_post4, self.texture_correlation_nondir_post4, self.texture_variance_nondir_post4, self.texture_inversediffmoment_nondir_post4, self.texture_sumaverage_nondir_post4, self.texture_sumvariance_nondir_post4, self.texture_sumentropy_nondir_post4, self.texture_entropy_nondir_post4, self.texture_diffvariance_nondir_post4, self.texture_diffentropy_nondir_post4] = allglcmdesc[33:44] # orgamize into dataframe self.texture_features = DataFrame( data=array([[self.texture_energy_nondir_post1, self.texture_contrast_nondir_post1, self.texture_correlation_nondir_post1, self.texture_variance_nondir_post1, self.texture_inversediffmoment_nondir_post1, self.texture_sumaverage_nondir_post1, self.texture_sumvariance_nondir_post1, self.texture_sumentropy_nondir_post1, self.texture_entropy_nondir_post1, self.texture_diffvariance_nondir_post1,self.texture_diffentropy_nondir_post1, self.texture_energy_nondir_post2, self.texture_contrast_nondir_post2, self.texture_correlation_nondir_post2, self.texture_variance_nondir_post2, self.texture_inversediffmoment_nondir_post2, self.texture_sumaverage_nondir_post2, self.texture_sumvariance_nondir_post2, self.texture_sumentropy_nondir_post2, self.texture_entropy_nondir_post2, self.texture_diffvariance_nondir_post2, self.texture_diffentropy_nondir_post2, self.texture_energy_nondir_post3, self.texture_contrast_nondir_post3, self.texture_correlation_nondir_post3, self.texture_variance_nondir_post3, self.texture_inversediffmoment_nondir_post3, self.texture_sumaverage_nondir_post3, self.texture_sumvariance_nondir_post3, self.texture_sumentropy_nondir_post3, self.texture_entropy_nondir_post3, self.texture_diffvariance_nondir_post3, self.texture_diffentropy_nondir_post3, self.texture_energy_nondir_post4, self.texture_contrast_nondir_post4, self.texture_correlation_nondir_post4, self.texture_variance_nondir_post4, self.texture_inversediffmoment_nondir_post4, self.texture_sumaverage_nondir_post4, self.texture_sumvariance_nondir_post4, self.texture_sumentropy_nondir_post4, self.texture_entropy_nondir_post4, self.texture_diffvariance_nondir_post4, self.texture_diffentropy_nondir_post4]]), columns=[ 'texture_energy_nondir_post1','texture_contrast_nondir_post1','texture_correlation_nondir_post1', 'texture_variance_nondir_post1', 'texture_inversediffmoment_nondir_post1', 'texture_sumaverage_nondir_post1', 'texture_sumvariance_nondir_post1', 'texture_sumentropy_nondir_post1', 'texture_entropy_nondir_post1', 'texture_diffvariance_nondir_post1', 'texture_diffentropy_nondir_post1', 'texture_energy_nondir_post2', 'texture_contrast_nondir_post2', 'texture_correlation_nondir_post2', 'texture_variance_nondir_post2', 'texture_inversediffmoment_nondir_post2', 'texture_sumaverage_nondir_post2', 'texture_sumvariance_nondir_post2', 'texture_sumentropy_nondir_post2', 'texture_entropy_nondir_post2', 'texture_diffvariance_nondir_post2', 'texture_diffentropy_nondir_post2', 'texture_energy_nondir_post3', 'texture_contrast_nondir_post3', 'texture_correlation_nondir_post3', 'texture_variance_nondir_post3', 'texture_inversediffmoment_nondir_post3', 'texture_sumaverage_nondir_post3', 'texture_sumvariance_nondir_post3', 'texture_sumentropy_nondir_post3', 'texture_entropy_nondir_post3', 'texture_diffvariance_nondir_post3', 'texture_diffentropy_nondir_post3', 'texture_energy_nondir_post4', 'texture_contrast_nondir_post4', 'texture_correlation_nondir_post4', 'texture_variance_nondir_post4', 'texture_inversediffmoment_nondir_post4', 'texture_sumaverage_nondir_post4', 'texture_sumvariance_nondir_post4', 'texture_sumentropy_nondir_post4', 'texture_entropy_nondir_post4', 'texture_diffvariance_nondir_post4', 'texture_diffentropy_nondir_post4', ]) return self.texture_features
def run(self): grouper = self.grouper reader = gdcm.ImageReader() reader.SetFileName(self.filepath) if (reader.Read()): file = reader.GetFile() # Retrieve data set dataSet = file.GetDataSet() # Retrieve header header = file.GetHeader() stf = gdcm.StringFilter() field_dict = {} data_dict = {} tag = gdcm.Tag(0x0008, 0x0005) ds = reader.GetFile().GetDataSet() if ds.FindDataElement(tag): encoding_value = str( ds.GetDataElement(tag).GetValue()).split('\\')[0] if encoding_value.startswith("Loaded"): encoding = "ISO_IR 100" else: try: encoding = const.DICOM_ENCODING_TO_PYTHON[ encoding_value] except KeyError: encoding = 'ISO_IR 100' else: encoding = "ISO_IR 100" # Iterate through the Header iterator = header.GetDES().begin() while (not iterator.equal(header.GetDES().end())): dataElement = iterator.next() stf.SetFile(file) tag = dataElement.GetTag() data = stf.ToStringPair(tag) stag = tag.PrintAsPipeSeparatedString() group = str(tag.GetGroup()) field = str(tag.GetElement()) tag_labels[stag] = data[0] if not group in data_dict.keys(): data_dict[group] = {} if not (utils.VerifyInvalidPListCharacter(data[1])): data_dict[group][field] = data[1].decode(encoding) else: data_dict[group][field] = "Invalid Character" # Iterate through the Data set iterator = dataSet.GetDES().begin() while (not iterator.equal(dataSet.GetDES().end())): dataElement = iterator.next() stf.SetFile(file) tag = dataElement.GetTag() data = stf.ToStringPair(tag) stag = tag.PrintAsPipeSeparatedString() group = str(tag.GetGroup()) field = str(tag.GetElement()) tag_labels[stag] = data[0] if not group in data_dict.keys(): data_dict[group] = {} if not (utils.VerifyInvalidPListCharacter(data[1])): data_dict[group][field] = data[1].decode( encoding, 'replace') else: data_dict[group][field] = "Invalid Character" # -------------- To Create DICOM Thumbnail ----------- rvtk = vtkgdcm.vtkGDCMImageReader() rvtk.SetFileName(self.filepath) rvtk.Update() try: data = data_dict[str(0x028)][str(0x1050)] level = [float(value) for value in data.split('\\')][0] data = data_dict[str(0x028)][str(0x1051)] window = [float(value) for value in data.split('\\')][0] except (KeyError): level = 300.0 window = 2000.0 colorer = vtk.vtkImageMapToWindowLevelColors() colorer.SetInputConnection(rvtk.GetOutputPort()) colorer.SetWindow(float(window)) colorer.SetLevel(float(level)) colorer.SetOutputFormatToRGB() colorer.Update() resample = vtk.vtkImageResample() resample.SetInputConnection(colorer.GetOutputPort()) resample.SetAxisMagnificationFactor(0, 0.25) resample.SetAxisMagnificationFactor(1, 0.25) resample.SetAxisMagnificationFactor(2, 1) resample.Update() thumbnail_path = tempfile.mktemp() write_png = vtk.vtkPNGWriter() write_png.SetInputConnection(resample.GetOutputPort()) write_png.SetFileName(thumbnail_path) write_png.Write() #------ Verify the orientation -------------------------------- img = reader.GetImage() direc_cosines = img.GetDirectionCosines() orientation = gdcm.Orientation() try: type = orientation.GetType(tuple(direc_cosines)) except TypeError: type = orientation.GetType(direc_cosines) label = orientation.GetLabel(type) # ---------- Refactory -------------------------------------- data_dict['invesalius'] = {'orientation_label': label} # ------------------------------------------------------------- dict_file[self.filepath] = data_dict #---------- Verify is DICOMDir ------------------------------- is_dicom_dir = 1 try: if (data_dict[str(0x002)][str(0x002)] != "1.2.840.10008.1.3.10"): #DICOMDIR is_dicom_dir = 0 except (KeyError): is_dicom_dir = 0 if not (is_dicom_dir): parser = dicom.Parser() parser.SetDataImage(dict_file[self.filepath], self.filepath, thumbnail_path) dcm = dicom.Dicom() #self.l.acquire() dcm.SetParser(parser) grouper.AddFile(dcm)