def writenifti(image, filename, info): """Write nifti file.""" writer = vtk.vtkNIFTIImageWriter() writer.SetInputData(image) writer.SetFileName(filename) writer.SetInformation(info) writer.Write()
def vtk_write_mask_as_nifty(mask, M, image_fn, mask_fn): reader = vtk.vtkNIFTIImageReader() reader.SetFileName(image_fn) reader.Update() writer = vtk.vtkNIFTIImageWriter() M.Invert() if reader.GetQFac() == -1: for i in range(3): temp = M.GetElement(i, 2) M.SetElement(i, 2, temp * -1) reslice = vtk.vtkImageReslice() reslice.SetInputData(mask) reslice.SetResliceAxes(M) reslice.SetInterpolationModeToNearestNeighbor() reslice.Update() mask = reslice.GetOutput() mask.SetOrigin([0., 0., 0.]) writer.SetInputData(mask) writer.SetFileName(mask_fn) writer.SetQFac(reader.GetQFac()) q_mat = reader.GetQFormMatrix() writer.SetQFormMatrix(q_mat) s_mat = reader.GetSFormMatrix() writer.SetSFormMatrix(s_mat) writer.Write() return
def vtk_write_mask_as_nifty(mask, image_fn, mask_fn): import vtk origin = mask.GetOrigin() reader = vtk.vtkNIFTIImageReader() reader.SetFileName(image_fn) reader.Update() writer = vtk.vtkNIFTIImageWriter() Sign = vtk.vtkMatrix4x4() Sign.Identity() Sign.SetElement(0, 0, -1) Sign.SetElement(1, 1, -1) M = reader.GetQFormMatrix() if M is None: M = reader.GetSFormMatrix() M2 = vtk.vtkMatrix4x4() M2.Multiply4x4(Sign, M, M2) reslice = vtk.vtkImageReslice() reslice.SetInputData(mask) reslice.SetResliceAxes(M2) reslice.SetInterpolationModeToNearestNeighbor() reslice.Update() mask = reslice.GetOutput() mask.SetOrigin([0., 0., 0.]) writer.SetInputData(mask) writer.SetFileName(mask_fn) writer.SetQFac(reader.GetQFac()) q_mat = reader.GetQFormMatrix() writer.SetQFormMatrix(q_mat) s_mat = reader.GetSFormMatrix() writer.SetSFormMatrix(s_mat) writer.Write() return
def write_image(_data, path_to_image): # == make sure data type is unsigned char cast = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: cast.SetInput(_data) else: cast.SetInputData(_data) cast.SetOutputScalarTypeToUnsignedChar() cast.Update() _data = cast.GetOutput() # == write file_ext = fu.get_file_extension(path_to_image) if (file_ext == "vti"): print("Writing as '.vti' file.") image_writer = vtk.vtkXMLImageDataWriter() elif (file_ext == "nii"): print("Writing as '.nii' file.") image_writer = vtk.vtkNIFTIImageWriter() print( "VTK seems to change image orientation of NIFTI. Make sure to check image orientation relative to original image" ) elif (file_ext == "mhd" or file_ext == "mha"): print("Writing as .mhd/.raw or .mha image.") image_writer = vtk.vtkMetaImageWriter() image_writer.SetCompression(False) else: print("No valid image file extension specified!") if vtk.VTK_MAJOR_VERSION <= 5: image_writer.SetInput(_data) else: image_writer.SetInputData(_data) image_writer.SetFileName(path_to_image) # image_writer.Update() image_writer.Write() print("Image has been saved as %s " % (path_to_image))
def test_get_nii_gz(self): '''compressed nifti file returns correct reader''' extension='.nii.gz' expected = type(vtk.vtkNIFTIImageReader()) writer = vtk.vtkNIFTIImageWriter() filename = os.path.join(self.test_dir, 'file'+extension) self.generate_image(filename, writer) self.assertEqual(type(get_vtk_reader(filename)), expected)
def ImageCropper(Image,X1, X2,Y1,Y2, Z1,Z2): CroppedImage = vtk.vtkExtractVOI() CroppedImage.SetInputData(Image) CroppedImage.SetVOI(X1, X2,Y1,Y2, Z1,Z2) CroppedImage.Update() writer=vtk.vtkNIFTIImageWriter() writer.SetInputConnection(CroppedImage.GetOutputPort()) writer.SetFileName("CroppedImageout.nii") writer.Write() reader=vtk.vtkNIFTIImageReader() reader.SetFileName("CroppedImageout.nii") reader.Update() image=reader.GetOutput() return(image)
def TestReadWriteRead(infile, outfile): """Read, write, and re-read a file, return difference.""" inpath = os.path.join(str(VTK_DATA_ROOT), "Data", infile) outpath = os.path.join(str(VTK_TEMP_DIR), outfile) # read a NIFTI file reader = vtk.vtkNIFTIImageReader() reader.SetFileName(inpath) reader.TimeAsVectorOn() reader.Update() writer = vtk.vtkNIFTIImageWriter() writer.SetInputConnection(reader.GetOutputPort()) writer.SetFileName(outpath) # copy most information directoy from the header writer.SetNIFTIHeader(reader.GetNIFTIHeader()) # this information will override the reader's header writer.SetQFac(reader.GetQFac()) writer.SetTimeDimension(reader.GetTimeDimension()) writer.SetQFormMatrix(reader.GetQFormMatrix()) writer.SetSFormMatrix(reader.GetSFormMatrix()) writer.Write() reader2 = vtk.vtkNIFTIImageReader() reader2.SetFileName(outpath) reader2.TimeAsVectorOn() reader2.Update() diff = vtk.vtkImageMathematics() diff.SetOperationToSubtract() diff.SetInputConnection(0,reader.GetOutputPort()) diff.SetInputConnection(1,reader2.GetOutputPort()) diff.Update() diffrange = diff.GetOutput().GetScalarRange() differr = diffrange[0]**2 + diffrange[1]**2 return differr
def write(objct, fileoutput, binary=True): """ Write 3D object to file. (same as `save()`). Possile extensions are: - vtk, vti, npy, ply, obj, stl, byu, vtp, vti, mhd, xyz, tif, png, bmp. """ obj = objct if isinstance(obj, Mesh): # picks transformation obj = objct.polydata(True) elif isinstance(obj, (vtk.vtkActor, vtk.vtkVolume)): obj = objct.GetMapper().GetInput() elif isinstance(obj, (vtk.vtkPolyData, vtk.vtkImageData)): obj = objct fr = fileoutput.lower() if fr.endswith(".vtk"): writer = vtk.vtkPolyDataWriter() elif fr.endswith(".ply"): writer = vtk.vtkPLYWriter() pscal = obj.GetPointData().GetScalars() if not pscal: pscal = obj.GetCellData().GetScalars() if pscal and pscal.GetName(): writer.SetArrayName(pscal.GetName()) #writer.SetColorMode(0) lut = objct.GetMapper().GetLookupTable() if lut: writer.SetLookupTable(lut) elif fr.endswith(".stl"): writer = vtk.vtkSTLWriter() elif fr.endswith(".vtp"): writer = vtk.vtkXMLPolyDataWriter() elif fr.endswith(".vtm"): g = vtk.vtkMultiBlockDataGroupFilter() for ob in objct: if isinstance(ob, Mesh): # picks transformation ob = ob.polydata(True) elif isinstance(ob, (vtk.vtkActor, vtk.vtkVolume)): ob = ob.GetMapper().GetInput() g.AddInputData(ob) g.Update() mb = g.GetOutputDataObject(0) wri = vtk.vtkXMLMultiBlockDataWriter() wri.SetInputData(mb) wri.SetFileName(fileoutput) wri.Write() return mb elif fr.endswith(".xyz"): writer = vtk.vtkSimplePointsWriter() elif fr.endswith(".facet"): writer = vtk.vtkFacetWriter() elif fr.endswith(".tif"): writer = vtk.vtkTIFFWriter() writer.SetFileDimensionality(len(obj.GetDimensions())) elif fr.endswith(".vti"): writer = vtk.vtkXMLImageDataWriter() elif fr.endswith(".mhd"): writer = vtk.vtkMetaImageWriter() elif fr.endswith(".nii"): writer = vtk.vtkNIFTIImageWriter() elif fr.endswith(".png"): writer = vtk.vtkPNGWriter() elif fr.endswith(".jpg"): writer = vtk.vtkJPEGWriter() elif fr.endswith(".bmp"): writer = vtk.vtkBMPWriter() elif fr.endswith(".npy"): if utils.isSequence(objct): objslist = objct else: objslist = [objct] dicts2save = [] for obj in objslist: dicts2save.append( _np_dump(obj) ) np.save(fileoutput, dicts2save) return dicts2save elif fr.endswith(".obj"): outF = open(fileoutput, "w") outF.write('# OBJ file format with ext .obj\n') outF.write('# File Created by vtkplotter\n') cobjct = objct.clone().clean() for p in cobjct.points(): outF.write('v '+ str(p[0]) +" "+ str(p[1])+" "+ str(p[2])+'\n') for vn in cobjct.normals(cells=False): outF.write('vn '+str(vn[0])+" "+str(vn[1])+" "+str(vn[2])+'\n') #pdata = cobjct.polydata().GetPointData().GetScalars() #if pdata: # ndata = vtk_to_numpy(pdata) # for vd in ndata: # outF.write('vp '+ str(vd) +'\n') #ptxt = cobjct.polydata().GetPointData().GetTCoords() # not working #if ptxt: # ntxt = vtk_to_numpy(ptxt) # print(len(cobjct.faces()), cobjct.points().shape, ntxt.shape) # for vt in ntxt: # outF.write('vt '+ str(vt[0]) +" "+ str(vt[1])+ ' 0\n') for f in cobjct.faces(): fs = '' for fi in f: fs += " "+str(fi+1) outF.write('f' + fs + '\n') #ldata = cobjct.polydata().GetLines().GetData() #print(cobjct.polydata().GetLines()) #if ldata: # ndata = vtk_to_numpy(ldata) # print(ndata) # for l in ndata: # ls = '' # for li in l: # ls += str(li+1)+" " # outF.write('l '+ ls + '\n') outF.close() return objct elif fr.endswith(".xml"): # write tetrahedral dolfin xml vertices = objct.points().astype(str) faces = np.array(objct.faces()).astype(str) ncoords = vertices.shape[0] outF = open(fileoutput, "w") outF.write('<?xml version="1.0" encoding="UTF-8"?>\n') outF.write('<dolfin xmlns:dolfin="http://www.fenicsproject.org">\n') if len(faces[0]) == 4:# write tetrahedral mesh ntets = faces.shape[0] outF.write(' <mesh celltype="tetrahedron" dim="3">\n') outF.write(' <vertices size="' + str(ncoords) + '">\n') for i in range(ncoords): x, y, z = vertices[i] outF.write(' <vertex index="'+str(i)+'" x="'+x+'" y="'+y+'" z="'+z+'"/>\n') outF.write(' </vertices>\n') outF.write(' <cells size="' + str(ntets) + '">\n') for i in range(ntets): v0, v1, v2, v3 = faces[i] outF.write(' <tetrahedron index="'+str(i) + '" v0="'+v0+'" v1="'+v1+'" v2="'+v2+'" v3="'+v3+'"/>\n') elif len(faces[0]) == 3:# write triangle mesh ntri = faces.shape[0] outF.write(' <mesh celltype="triangle" dim="2">\n') outF.write(' <vertices size="' + str(ncoords) + '">\n') for i in range(ncoords): x, y, dummy_z = vertices[i] outF.write(' <vertex index="'+str(i)+'" x="'+x+'" y="'+y+'"/>\n') outF.write(' </vertices>\n') outF.write(' <cells size="' + str(ntri) + '">\n') for i in range(ntri): v0, v1, v2 = faces[i] outF.write(' <triangle index="'+str(i)+'" v0="'+v0+'" v1="'+v1+'" v2="'+v2+'"/>\n') outF.write(' </cells>\n') outF.write(" </mesh>\n") outF.write("</dolfin>\n") outF.close() return objct else: colors.printc("~noentry Unknown format", fileoutput, "file not saved.", c="r") return objct try: if hasattr(writer, 'SetFileTypeToBinary'): if binary: writer.SetFileTypeToBinary() else: writer.SetFileTypeToASCII() writer.SetInputData(obj) writer.SetFileName(fileoutput) writer.Write() except Exception as e: colors.printc("~noentry Error saving: " + fileoutput, "\n", e, c="r") return objct
BrainMask.SetScalarComponentFromFloat(x, y, z, 0, 1) else: BrainMask.SetScalarComponentFromFloat(x, y, z, 0, 0) voxelValueBrainMask = BrainMask.GetScalarComponentAsFloat( x, y, z, 0) if voxelValueBrainMask == 1: HeadMask.SetScalarComponentFromFloat(x, y, z, 0, 0) voxelValueHipoLeft = HipoLeft.GetOutput( ).GetScalarComponentAsFloat(x, y, z, 0) voxelValueHipoRight = HipoRight.GetOutput( ).GetScalarComponentAsFloat(x, y, z, 0) if voxelValueHipoLeft != 0 or voxelValueHipoRight != 0: BrainMask.SetScalarComponentFromFloat(x, y, z, 0, 0) #............................................................................................ #Write resulting masks writer1 = vtk.vtkNIFTIImageWriter() writer1.SetInputData(HeadMask) writer1.SetFileName("HeadMask.nii") writer1.Write() writer2 = vtk.vtkNIFTIImageWriter() writer2.SetInputData(BrainMask) writer2.SetFileName("BrainMask.nii") writer2.Write() #Define a function that takes an image and returns a same structured image but with zero values everywhere def ZeroImage(image): image1 = vtk.vtkImageData() image1.DeepCopy(image) for z in range(0, image.GetDimensions()[2]): for y in range(0, image.GetDimensions()[1]):
rightExtractor.SetVOI(rightVOI) print 'Extractiong right subvolume' rightExtractor.Update() # Extract right leftExtractor = vtk.vtkExtractVOI() leftExtractor.SetInputConnection(reader.GetOutputPort()) leftExtractor.SetVOI(leftVOI) print 'Extractiong left subvolume' leftExtractor.Update() # Flip image (left becomes right) leftFlipper = vtk.vtkImageFlip() leftFlipper.SetInputConnection(leftExtractor.GetOutputPort()) leftFlipper.SetFilteredAxis(0) print 'Flipping left subvolume' leftFlipper.Update() # Write data out rightWriter = vtk.vtkNIFTIImageWriter() rightWriter.SetInputConnection(rightExtractor.GetOutputPort()) rightWriter.SetFileName(args.outputRightFemurImageFile) print "Writing {fileName}".format(fileName=args.outputRightFemurImageFile) rightWriter.Write() leftWriter = vtk.vtkNIFTIImageWriter() leftWriter.SetInputConnection(leftFlipper.GetOutputPort()) leftWriter.SetFileName(args.outputLeftFemurImageFile) print "Writing {fileName}".format(fileName=args.outputLeftFemurImageFile) leftWriter.Write()
print('\tmu_scaling: {}'.format(mu_scaling)) print('\thu_mu_water: {}'.format(hu_mu_water)) # First convert Native -> mu (linear attenuation) # mu = Native / mu_scaling # Second convert mu -> HU # HU = 1000 * (mu - mu_water) / (mu_water - mu_air) m = 1000.0 / mu_scaling / (hu_mu_water - hu_mu_air) b = -1000.0 * hu_mu_water / (hu_mu_water - hu_mu_air) print "Proc. log eq: {0} * x {1:+f}".format(m, b) print "Proc. log eq: {0} * (x {1:+f})".format(m, b / m) # Apply shift caster = vtk.vtkImageShiftScale() caster.SetOutputScalarTypeToFloat() caster.ClampOverflowOn() caster.SetInputConnection(reader.GetOutputPort()) caster.SetShift(b / m) caster.SetScale(m) print("Shifting and scaling input...") caster.Update() # Write outputImage writer = vtk.vtkNIFTIImageWriter() writer.SetFileName(args.outputImage) writer.SetInputConnection(caster.GetOutputPort()) print("Writing to {}".format(args.outputImage)) writer.Update()
def filterSmooth(inputReader): inputImage = inputReader.GetOutput() imagePath = imageFile # determes the filename for the output file based on filter type and input if (os.path.isdir(imagePath)) and filterType == "gaussian": # outfile = "Thorax_GaussianSmoothed" outfile = str(os.path.basename(imagePath)) + '_GaussianSmoothed.nii' elif (os.path.isdir(imagePath)) and filterType == "median": # outfile = "Thorax_MedianSmoothed" outfile = str(os.path.basename(imagePath)) + '_MedianSmoothed.nii' elif filterType == "gaussian": outfile = str(os.path.splitext(imagePath)[0]) + '_GaussianSmoothed.nii' elif filterType == "median": outfile = str(os.path.splitext(imagePath)[0]) + '_MedianSmoothed.nii' ## used for debugging # outpath = os.path.join(os.getcwd(), outfile) # print('\nOutfile: ' + outfile) # print('\nOutpath: ' + outpath + '\n') # make a copy of the input image(s) to work with and maintain original data copyImage = vtk.vtkImageData() copyImage.DeepCopy(inputReader.GetOutput()) # get the image dimensions imageDim = inputImage.GetDimensions() imageExt = inputImage.GetExtent() kernelSize = 3 # could make this an input arg in the future imageDimMin = np.empty( 3, dtype=int ) # will have the starting coordinates for the image we want to smooth (padded) imageDimMax = np.empty( 3, dtype=int ) # will have the ending coordinates for the images we want to smooth (padded) ## used for debugging # print("imagedim= " + str(imageDim)) # print("image extents= " + str(imageExt)) # print("length of image ext= " + str(len(imageExt))) # dummy variables a = 0 b = 0 # set up the dimenions of the image we are analyzing to help iterate over the image's data # accounts for the size of the smoothing kernel (i.e. implementing padding) for i in range( 0, len(imageExt), 2 ): # 0 to 4 by twos to get all even numbers, corresponds to x y z min coords imageDimMin[a] = imageExt[i] + ( kernelSize - kernelSize // 2 ) # creates a list of the image's min coordinates to start smoothing from a += 1 for i in range( 1, (len(imageExt) + 1), 2 ): # 1 to 5 by twos to get all uneven numbers, corresponds to x y z max coords imageDimMax[b] = imageExt[i] - ( kernelSize - kernelSize // 2 ) # creates a list of the image's max coordinates to stop smoothing at b += 1 ## used for debugging # print("image dim min, max= " + str(imageDimMin) + str(imageDimMax)) # 3D Gaussian kernel, hard coded. Eventually change this to match the size of the array requested i.e. 3x3, 5x5, etc kernel = np.array([[[1, 2, 1], [2, 4, 2], [1, 2, 1]], [[2, 4, 2], [4, 16, 4], [2, 4, 2]], [[1, 2, 1], [2, 4, 2], [1, 2, 1]]]) # kernelNormal normalizes each entry in the array. If all normalized entries are summed, the answer is 1.0 # will be used as the gaussian kernel for fitering kernelNormal = kernel / np.sum(kernel) # used for testing to speed up processing. Set start and end Z-Slices to filter. imageDimMin[2] = 120 imageDimMax[2] = 130 # Itereate over all admissiblie pixels in a given image for x in range(imageDimMin[0] - 1, imageDimMax[0] + 1): for y in range(imageDimMin[1] - 1, imageDimMax[1] + 1): for z in range(imageDimMin[2] - 1, imageDimMax[2]): # a sub array of the image being filtered. Should be the size of the kernel subArray = np.empty((kernelSize, kernelSize, kernelSize), dtype=float) # iterate through values to append to the subArray based on 3x3x3 filter # the created sub array is composed to original image values and will be used to # apply the kernel to, and determine the filtered voxel value(s) l = 0 # dummy i index value for i in range(x - 1, x + 2): m = 0 # dummy j index value l += 1 for j in range(y - 1, y + 2): n = 0 # dummy k index value m += 1 for k in range(z - 1, z + 2): n += 1 voxelValue = inputImage.GetScalarComponentAsFloat( i, j, k, 0) subArray[l - 1][m - 1][n - 1] = voxelValue if filterType == "gaussian": # gives the value of the central voxel by summing all the values from the kernelNormal*subArray convolution # this is the gaussian blurring or smoothing step voxelBlurred = np.sum(kernelNormal * subArray) copyImage.SetScalarComponentFromFloat( x, y, z, 0, voxelBlurred) elif filterType == "median": # gives the value of the central voxel by determining the median value of the subArray # this is the median blurring or smoothing step voxelMedian = np.median(subArray) copyImage.SetScalarComponentFromFloat( x, y, z, 0, voxelMedian) # print('. ') # write the new filtered image as a NIFTI filetype to the working directory # I'm not sure how to do this for DICOM writer = vtk.vtkNIFTIImageWriter() writer.SetFileName(outfile) writer.SetInputData(copyImage) writer.Write() # updates the vtk reader to the new filtered image smoothedImage = vtk.vtkNIFTIImageReader() smoothedImage.SetFileName(outfile) smoothedImage.Update() return (smoothedImage)
reader = vtk.vtkNIFTIImageReader() reader.SetFileName(VTK_DATA_ROOT + "/PASIM_N002.nii") reader.Update() size = reader.GetOutput().GetDimensions() # Create Threshold Threshold = vtk.vtkImageThreshold() Threshold.SetInputConnection(reader.GetOutputPort()) Threshold.ThresholdBetween(IntensityValue, IntensityValue) Threshold.SetInValue(255) Threshold.SetOutValue(0) Threshold.SetOutputScalarTypeToUnsignedChar() Threshold.Update() # Write Threshold Image writer = vtk.vtkNIFTIImageWriter() writer.SetInputConnection(Threshold.GetOutputPort()) writer.SetFileName("BinaryImage.nii") writer.Write() # Calculate Euclidean distance dist = vtk.vtkImageEuclideanDistance() dist.SetInputConnection(Threshold.GetOutputPort()) dist.SetAlgorithmToSaitoCached() dist.Update() # Performs Square root to speed up processing time mathSqrt = vtk.vtkImageMathematics() mathSqrt.SetInputConnection(dist.GetOutputPort()) mathSqrt.SetOperationToSquareRoot() mathSqrt.Update()
def test_get_nii_gz(self): '''nii.gz filetype returns None''' expected = type(vtk.vtkNIFTIImageWriter()) self.assertEqual(type(get_vtk_writer('test.nIi.gZ')), expected)
reader = vtk.vtkNIFTIImageReader() reader.SetFileName(name) reader.Update() print "type is: ",reader.GetDataScalarType() matrix = reader.GetQFormMatrix() print "Ori QForm Matrix is",matrix caster = vtk.vtkImageCast() caster.SetInputData(reader.GetOutput()) caster.SetOutputScalarTypeToInt() caster.Update() i2 = "new"+i print "writing to", i2 writer = vtk.vtkNIFTIImageWriter() #writer.SetQFac(-1) writer.SetQFormMatrix(matrix) writer.SetFileName(folder_path+i2) writer.SetInputData(caster.GetOutput()) writer.Update() else: pass print "Done!!"
HipoCrop = ImageCropper(image, Array[0], Array[1], Array[2], Array[3], Array[4], Array[5]) print("croppedimage..............") print(HipoCrop.GetExtent()) print("origImage.................") print(image.GetExtent()) pad = vtk.vtkImageConstantPad() pad.SetInputData(HipoCrop) pad.SetOutputWholeExtent(-Array[0], image.GetExtent()[1] - Array[0], -Array[2], image.GetExtent()[3] - Array[2], -Array[4], image.GetExtent()[5] - Array[4]) pad.SetConstant(0) pad.Update() writer6 = vtk.vtkNIFTIImageWriter() writer6.SetInputConnection(pad.GetOutputPort()) writer6.SetFileName("SegmentedNoPostProcess_Hipo.nii") writer6.Write() reader1 = vtk.vtkNIFTIImageReader() reader1.SetFileName("SegmentedNoPostProcess_Hipo.nii") reader1.Update() image1 = reader.GetOutput() print("finalImage.................") print(reader1.GetOutput().GetExtent()) reslice = vtk.vtkImageReslice() reslice.SetInputConnection(reader1.GetOutputPort()) #reslice.SetInformationInput(reader.GetOutput())
ymax=max(yvector) Array=[xmin,xmax,ymin,ymax,zmin,zmax] return(Array) Array=TightBounder(im1) X1=Array[0] X2=Array[1] Y1=Array[2] Y2=Array[3] Z1=Array[4] Z2=Array[5] im1crop=ImageCropper(im1,X1,X2,Y1,Y2,Z1,Z2) im2crop=ImageCropper(im2,X1,X2,Y1,Y2,Z1,Z2) #im3crop=ImageCropper(im3,X1,X2,Y1,Y2,Z1,Z2) writer1=vtk.vtkNIFTIImageWriter() writer1.SetInputData(im1crop) writer1.SetFileName(args.output1) writer1.Write() writer2=vtk.vtkNIFTIImageWriter() writer2.SetInputData(im2crop) writer2.SetFileName(args.output2) writer2.Write()
def mesh_2_mask( inputMesh, outputImage, inputImage=None, superRes=False, spacing=(1.0, 1.0, 1.0) ): """ This program takes in a closed 3D surface, vtkPolyData, and converts it into volume representation (vtkImageData) where the foreground voxels are 1 and the background voxels are 0. Internally vtkPolyDataToImageStencil is utilized. The resultant image is saved to disk in NIFTIimage file format. SimpleITK is used to convert images to standard orientation used for 3D medical images. :param inputMesh: a vtkPolyData file of a 3D surface :param outputImage: output file path for NIFTI image :param inputImage: reference image to get desired spacing, origin, and direction. :param superRes: :param spacing: :return: """ VTK_MAJOR_VERSION = str(vtk.vtkVersion().GetVTKVersion()).split(".")[0] outputImage = str(outputImage) if inputImage: inputImage = str(inputImage) # check output image extension out_ext = outputImage.split(".", 1)[-1] if "nii" in out_ext: writer = vtk.vtkNIFTIImageWriter() else: print( "ERROR: Output must be NIFTI image file. \n\tUnrecognized extension: {0}".format( out_ext ) ) return sys.exit(os.EX_IOERR) if inputImage: image = read_vtk_image(inputImage) else: image = None # read the mesh in pd = read_poly_data(inputMesh) pd = preprocess_mesh(pd) # allocate whiteImage whiteImage = vtk.vtkImageData() # polygonal data -. image stencil: pol2stenc = vtk.vtkPolyDataToImageStencil() if VTK_MAJOR_VERSION <= 5: pol2stenc.SetInput(pd) else: pol2stenc.SetInputData(pd) # get the bounds bounds = pd.GetBounds() if image: spacing = image.GetSpacing() dim = image.GetDimensions() # set VTK direction to RAS vtk_direction = (-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0) # vtk does not get the correct origin # origin = image.GetOrigin () # use SimpleITK instead image_sitk = sitk.ReadImage(inputImage) origin = image_sitk.GetOrigin() direction = image_sitk.GetDirection() print(direction) print(origin) print(spacing) # superRes slows down the script quite a bit if superRes: """Creates an image with pixels a fourth the size of the original This helps allivaite some of the partial voluming effect that can take place.""" denom = 2 spacing = ( spacing[0] / float(denom), spacing[1] / float(denom), spacing[2] / float(denom), ) dim = (dim[0] * denom, dim[1] * denom, dim[2] * denom) # VTKImages seem to always have the same direction origin = ( origin[0] * vtk_direction[0], origin[1] * vtk_direction[4], origin[2] * vtk_direction[8], ) if direction != vtk_direction: if direction == (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0): origin = ( origin[0] - spacing[0] * (dim[0] - 1), origin[1] - spacing[1] * (dim[1] - 1), origin[2], ) else: print("ERROR: Not sure how to handle input image direction") sys.exit() print(origin) else: if superRes: spacing = ( spacing[0] / float(2), spacing[1] / float(2), spacing[2] / float(2), ) # compute dimensions dim = [0, 0, 0] for i in range(3): dim[i] = int(math.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i])) dim = tuple(dim) # get origin origin = [0, 0, 0] origin[0] = bounds[0] + spacing[0] / float(2) origin[1] = bounds[2] + spacing[1] / float(2) origin[2] = bounds[4] + spacing[2] / float(2) origin = tuple(origin) whiteImage.SetSpacing(spacing) whiteImage.SetOrigin(origin) pol2stenc.SetOutputOrigin(origin) pol2stenc.SetOutputSpacing(spacing) # set dimensions whiteImage.SetDimensions(dim) whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1) if VTK_MAJOR_VERSION <= 5: whiteImage.SetScalarTypeToUnsignedChar() whiteImage.AllocateScalars() else: whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) # fill the image with foreground voxels: inval = 1 outval = 0 count = whiteImage.GetNumberOfPoints() for i in range(count): whiteImage.GetPointData().GetScalars().SetTuple1(i, inval) # update pol2stenc pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent()) pol2stenc.Update() # cut the corresponding white image and set the background: imgstenc = vtk.vtkImageStencil() if VTK_MAJOR_VERSION <= 5: imgstenc.SetInput(whiteImage) imgstenc.SetStencil(pol2stenc.GetOutput()) else: imgstenc.SetInputData(whiteImage) imgstenc.SetStencilConnection(pol2stenc.GetOutputPort()) imgstenc.ReverseStencilOff() imgstenc.SetBackgroundValue(outval) imgstenc.Update() # write image to file writer.SetFileName(outputImage) if inputImage != None and direction != vtk_direction: flipFilter = vtk.vtkImageFlip() flipFilter.SetFilteredAxis(1) # flip y axis flipFilter.SetInputData(imgstenc.GetOutput()) flipFilter.SetFlipAboutOrigin(1) flipFilter.Update() flipFilter2 = vtk.vtkImageFlip() flipFilter2.SetFilteredAxis(0) # flip x axis flipFilter2.SetInputData(flipFilter.GetOutput()) flipFilter2.SetFlipAboutOrigin(1) flipFilter2.Update() if VTK_MAJOR_VERSION <= 5: writer.SetInput(flipFilter2.GetOutput()) else: writer.SetInputData(flipFilter2.GetOutput()) writer.Write() itk_image = sitk.ReadImage(inputImage) out_image = sitk.ReadImage(outputImage) out_image.SetDirection(itk_image.GetDirection()) out_image.SetOrigin(itk_image.GetOrigin()) sitk.WriteImage(out_image, outputImage) else: if VTK_MAJOR_VERSION <= 5: writer.SetInput(imgstenc.GetOutput()) else: writer.SetInputData(imgstenc.GetOutput()) writer.Write() return os.path.abspath(outputImage)
def vtkExtractOuterSurface(filename): reader = vtk.vtkNIFTIImageReader() reader.SetFileName(filename) reader.Update() image1 = reader.GetOutput() dim = image1.GetDimensions() print dim for x in [0, dim[0] - 1]: for y in [0, dim[1] - 1]: image1.SetScalarComponentFromFloat(x, y, dim[2] - 1, 0, 0.0) image1.SetScalarComponentFromFloat(x, y, dim[2] - 2, 0, 0.0) image1.SetScalarComponentFromFloat(x, y, dim[2] - 3, 0, 0.0) image1.SetScalarComponentFromFloat(x, y, dim[2] - 4, 0, 0.0) image1.SetScalarComponentFromFloat(x, y, 0, 0, 0.0) image1.SetScalarComponentFromFloat(x, y, 1, 0, 0.0) image1.SetScalarComponentFromFloat(x, y, 2, 0, 0.0) image1.SetScalarComponentFromFloat(x, y, 3, 0, 0.0) for y in [0, dim[1] - 1]: for z in [0, dim[2] - 1]: image1.SetScalarComponentFromFloat(dim[0] - 1, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(dim[0] - 2, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(dim[0] - 3, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(dim[0] - 4, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(dim[0] - 5, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(0, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(1, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(2, y, z, 0, 0.0) image1.SetScalarComponentFromFloat(3, y, z, 0, 0.0) for x in [0, dim[0] - 1]: for z in [0, dim[2] - 1]: image1.SetScalarComponentFromFloat(x, 0, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, 1, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, 2, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, 3, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, 4, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, 5, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, dim[1] - 1, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, dim[1] - 2, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, dim[1] - 3, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, dim[1] - 4, z, 0, 0.0) image1.SetScalarComponentFromFloat(x, dim[1] - 5, z, 0, 0.0) # threshold threshold = vtk.vtkImageThreshold() threshold.SetInputData(image1) threshold.ThresholdBetween(15, 1000) threshold.ReplaceInOn() threshold.SetInValue(200) threshold.ReplaceOutOn() threshold.SetOutValue(0) threshold.Update() image = threshold.GetOutput() # write to image writer = vtk.vtkNIFTIImageWriter() writer.SetFileName("C:/Users/QIN Shuo/Desktop/test.nii") writer.SetInputData(image) writer.Update() # marching here marching = vtk.vtkMarchingCubes() marching.SetInputData(image) marching.SetValue(0, 8) marching.Update() skin = marching.GetOutput() connector = vtk.vtkConnectivityFilter() connector.SetInputData(skin) connector.SetExtractionModeToLargestRegion() connector.Update() geo = vtk.vtkGeometryFilter() geo.SetInputData(connector.GetOutput()) geo.Update() area = geo.GetOutput() ## fill holes # filler = vtk.vtkFillHolesFilter() # filler.SetInputData(area) # filler.SetHoleSize(1E6) # filler.Update() # area = filler.GetOutput() # filter = vtk.vtkPolyDataConnectivityFilter() # filter.SetInputData(area) # filter.SetExtractionModeToSpecifiedRegions() # filter.AddSpecifiedRegion(0) # filter.Update() # area = filter.GetOutput() # visualization print "visualizing..." mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(area) # mapper.ScalarVisibilityOn() actor = vtk.vtkActor() actor.SetMapper(mapper) # actor.GetProperty().SetOpacity(0.7) renderer = vtk.vtkRenderer() renderer.AddActor(actor) window = vtk.vtkRenderWindow() window.AddRenderer(renderer) interactor = vtk.vtkRenderWindowInteractor() window.SetInteractor(interactor) window.Render() interactor.Start()
def mesh_2_mask(inputMesh, outputImage, inputImage=None, superRes=False, spacing=(1.0, 1.0, 1.0)): """ This program takes in a closed 3D surface, vtkPolyData, and converts it into volume representation (vtkImageData) where the foreground voxels are 1 and the background voxels are 0. Internally vtkPolyDataToImageStencil is utilized. The resultant image is saved to disk in NIFTIimage file format. SimpleITK is used to convert images to standard orientation used for 3D medical images. :param inputMesh: a vtkPolyData file of a 3D surface :param outputImage: output file path for NIFTI image :param inputImage: reference image to get desired spacing, origin, and direction. :param superRes: :param spacing: :return: """ VTK_MAJOR_VERSION = str(vtk.vtkVersion().GetVTKVersion()).split(".")[0] outputImage = str(outputImage) if inputImage: inputImage = str(inputImage) # check output image extension out_ext = outputImage.split(".", 1)[-1] if "nii" in out_ext: writer = vtk.vtkNIFTIImageWriter() else: print( "ERROR: Output must be NIFTI image file. \n\tUnrecognized extension: {0}" .format(out_ext)) return sys.exit(os.EX_IOERR) if inputImage: image = read_vtk_image(inputImage) else: image = None # read the mesh in pd = read_poly_data(inputMesh) pd = preprocess_mesh(pd) # allocate whiteImage whiteImage = vtk.vtkImageData() # polygonal data -. image stencil: pol2stenc = vtk.vtkPolyDataToImageStencil() if VTK_MAJOR_VERSION <= 5: pol2stenc.SetInput(pd) else: pol2stenc.SetInputData(pd) # get the bounds bounds = pd.GetBounds() if image: spacing = image.GetSpacing() dim = image.GetDimensions() # set VTK direction to RAS vtk_direction = (-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0) # vtk does not get the correct origin # origin = image.GetOrigin () # use SimpleITK instead image_sitk = sitk.ReadImage(inputImage) origin = image_sitk.GetOrigin() direction = image_sitk.GetDirection() print(direction) print(origin) print(spacing) # superRes slows down the script quite a bit if superRes: """Creates an image with pixels a fourth the size of the original This helps allivaite some of the partial voluming effect that can take place.""" denom = 2 spacing = ( spacing[0] / float(denom), spacing[1] / float(denom), spacing[2] / float(denom), ) dim = (dim[0] * denom, dim[1] * denom, dim[2] * denom) # VTKImages seem to always have the same direction origin = ( origin[0] * vtk_direction[0], origin[1] * vtk_direction[4], origin[2] * vtk_direction[8], ) if direction != vtk_direction: if direction == (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0): origin = ( origin[0] - spacing[0] * (dim[0] - 1), origin[1] - spacing[1] * (dim[1] - 1), origin[2], ) else: print("ERROR: Not sure how to handle input image direction") sys.exit() print(origin) else: if superRes: spacing = ( spacing[0] / float(2), spacing[1] / float(2), spacing[2] / float(2), ) # compute dimensions dim = [0, 0, 0] for i in range(3): dim[i] = int( math.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i])) dim = tuple(dim) # get origin origin = [0, 0, 0] origin[0] = bounds[0] + spacing[0] / float(2) origin[1] = bounds[2] + spacing[1] / float(2) origin[2] = bounds[4] + spacing[2] / float(2) origin = tuple(origin) whiteImage.SetSpacing(spacing) whiteImage.SetOrigin(origin) pol2stenc.SetOutputOrigin(origin) pol2stenc.SetOutputSpacing(spacing) # set dimensions whiteImage.SetDimensions(dim) whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1) if VTK_MAJOR_VERSION <= 5: whiteImage.SetScalarTypeToUnsignedChar() whiteImage.AllocateScalars() else: whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) # fill the image with foreground voxels: inval = 1 outval = 0 count = whiteImage.GetNumberOfPoints() for i in range(count): whiteImage.GetPointData().GetScalars().SetTuple1(i, inval) # update pol2stenc pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent()) pol2stenc.Update() # cut the corresponding white image and set the background: imgstenc = vtk.vtkImageStencil() if VTK_MAJOR_VERSION <= 5: imgstenc.SetInput(whiteImage) imgstenc.SetStencil(pol2stenc.GetOutput()) else: imgstenc.SetInputData(whiteImage) imgstenc.SetStencilConnection(pol2stenc.GetOutputPort()) imgstenc.ReverseStencilOff() imgstenc.SetBackgroundValue(outval) imgstenc.Update() # write image to file writer.SetFileName(outputImage) if inputImage != None and direction != vtk_direction: flipFilter = vtk.vtkImageFlip() flipFilter.SetFilteredAxis(1) # flip y axis flipFilter.SetInputData(imgstenc.GetOutput()) flipFilter.SetFlipAboutOrigin(1) flipFilter.Update() flipFilter2 = vtk.vtkImageFlip() flipFilter2.SetFilteredAxis(0) # flip x axis flipFilter2.SetInputData(flipFilter.GetOutput()) flipFilter2.SetFlipAboutOrigin(1) flipFilter2.Update() if VTK_MAJOR_VERSION <= 5: writer.SetInput(flipFilter2.GetOutput()) else: writer.SetInputData(flipFilter2.GetOutput()) writer.Write() itk_image = sitk.ReadImage(inputImage) out_image = sitk.ReadImage(outputImage) out_image.SetDirection(itk_image.GetDirection()) out_image.SetOrigin(itk_image.GetOrigin()) sitk.WriteImage(out_image, outputImage) else: if VTK_MAJOR_VERSION <= 5: writer.SetInput(imgstenc.GetOutput()) else: writer.SetInputData(imgstenc.GetOutput()) writer.Write() return os.path.abspath(outputImage)
def write(objct, fileoutput, binary=True): """ Write 3D object to file. (same as `save()`). Possile extensions are: - vtk, vti, npy, ply, obj, stl, byu, vtp, vti, mhd, xyz, tif, png, bmp. """ obj = objct if isinstance(obj, Actor): # picks transformation obj = objct.polydata(True) elif isinstance(obj, (vtk.vtkActor, vtk.vtkVolume)): obj = objct.GetMapper().GetInput() elif isinstance(obj, (vtk.vtkPolyData, vtk.vtkImageData)): obj = objct fr = fileoutput.lower() if ".vtk" in fr: writer = vtk.vtkPolyDataWriter() elif ".ply" in fr: writer = vtk.vtkPLYWriter() pscal = obj.GetPointData().GetScalars() if not pscal: pscal = obj.GetCellData().GetScalars() if pscal and pscal.GetName(): writer.SetArrayName(pscal.GetName()) #writer.SetColorMode(0) lut = objct.GetMapper().GetLookupTable() if lut: writer.SetLookupTable(lut) elif ".stl" in fr: writer = vtk.vtkSTLWriter() elif ".obj" in fr: writer = vtk.vtkOBJWriter() elif ".vtp" in fr: writer = vtk.vtkXMLPolyDataWriter() elif ".vtm" in fr: g = vtk.vtkMultiBlockDataGroupFilter() for ob in objct: g.AddInputData(ob) g.Update() mb = g.GetOutputDataObject(0) wri = vtk.vtkXMLMultiBlockDataWriter() wri.SetInputData(mb) wri.SetFileName(fileoutput) wri.Write() return mb elif ".xyz" in fr: writer = vtk.vtkSimplePointsWriter() elif ".facet" in fr: writer = vtk.vtkFacetWriter() elif ".tif" in fr: writer = vtk.vtkTIFFWriter() writer.SetFileDimensionality(len(obj.GetDimensions())) elif ".vti" in fr: writer = vtk.vtkXMLImageDataWriter() elif ".mhd" in fr: writer = vtk.vtkMetaImageWriter() elif ".nii" in fr: writer = vtk.vtkNIFTIImageWriter() elif ".png" in fr: writer = vtk.vtkPNGWriter() elif ".jpg" in fr: writer = vtk.vtkJPEGWriter() elif ".bmp" in fr: writer = vtk.vtkBMPWriter() elif ".npy" in fr: if utils.isSequence(objct): objslist = objct else: objslist = [objct] dicts2save = [] for obj in objslist: dicts2save.append( _np_dump(obj) ) np.save(fileoutput, dicts2save) return dicts2save elif ".xml" in fr: # write tetrahedral dolfin xml vertices = objct.coordinates().astype(str) faces = np.array(objct.faces()).astype(str) ncoords = vertices.shape[0] outF = open(fileoutput, "w") outF.write('<?xml version="1.0" encoding="UTF-8"?>\n') outF.write('<dolfin xmlns:dolfin="http://www.fenicsproject.org">\n') if len(faces[0]) == 4:# write tetrahedral mesh ntets = faces.shape[0] outF.write(' <mesh celltype="tetrahedron" dim="3">\n') outF.write(' <vertices size="' + str(ncoords) + '">\n') for i in range(ncoords): x, y, z = vertices[i] outF.write(' <vertex index="'+str(i)+'" x="'+x+'" y="'+y+'" z="'+z+'"/>\n') outF.write(' </vertices>\n') outF.write(' <cells size="' + str(ntets) + '">\n') for i in range(ntets): v0, v1, v2, v3 = faces[i] outF.write(' <tetrahedron index="'+str(i) + '" v0="'+v0+'" v1="'+v1+'" v2="'+v2+'" v3="'+v3+'"/>\n') elif len(faces[0]) == 3:# write triangle mesh ntri = faces.shape[0] outF.write(' <mesh celltype="triangle" dim="2">\n') outF.write(' <vertices size="' + str(ncoords) + '">\n') for i in range(ncoords): x, y, dummy_z = vertices[i] outF.write(' <vertex index="'+str(i)+'" x="'+x+'" y="'+y+'"/>\n') outF.write(' </vertices>\n') outF.write(' <cells size="' + str(ntri) + '">\n') for i in range(ntri): v0, v1, v2 = faces[i] outF.write(' <triangle index="'+str(i)+'" v0="'+v0+'" v1="'+v1+'" v2="'+v2+'"/>\n') outF.write(' </cells>\n') outF.write(" </mesh>\n") outF.write("</dolfin>\n") outF.close() return objct else: colors.printc("~noentry Unknown format", fileoutput, "file not saved.", c="r") return objct try: if hasattr(writer, 'SetFileTypeToBinary'): if binary: writer.SetFileTypeToBinary() else: writer.SetFileTypeToASCII() writer.SetInputData(obj) writer.SetFileName(fileoutput) writer.Write() colors.printc("~save Saved file: " + fileoutput, c="g") except Exception as e: colors.printc("~noentry Error saving: " + fileoutput, "\n", e, c="r") return objct
def ImageFilter(input_filename, output_filename, range, overwrite=False): # Python 2/3 compatible input from six.moves import input # Check if output exists and should overwrite if os.path.isfile(output_filename) and not overwrite: result = input('File \"{}\" already exists. Overwrite? [y/n]: '.format( output_filename)) if result.lower() not in ['y', 'yes']: print('Not overwriting. Exiting...') os.sys.exit() # Check valid range if (range[0] > range[1] or range[0] < 0): os.sys.exit('[ERROR] Invalid range: {:d} {:d}'.format( range[0], range[1])) # Read input if not os.path.isfile(input_filename): os.sys.exit('[ERROR] Cannot find file \"{}\"'.format(input_filename)) if input_filename.lower().endswith('.nii'): reader = vtk.vtkNIFTIImageReader() elif input_filename.lower().endswith('.nii.gz'): reader = vtk.vtkNIFTIImageReader() else: os.sys.exit('[ERROR] Cannot find reader for file \"{}\"'.format( input_filename)) print('Reading input image ' + input_filename) reader.SetFileName(input_filename) reader.Update() scalarType = reader.GetOutput().GetScalarType() print('Input image scalar type: {:s}'.format( reader.GetOutput().GetScalarTypeAsString())) print('Input image labels:') histogram(reader.GetOutput()) thres = vtk.vtkImageThreshold() thres.SetInputConnection(reader.GetOutputPort()) thres.SetOutputScalarType(scalarType) thres.ThresholdBetween(1, 10) thres.ReplaceOutOn() thres.SetOutValue(0) thres.Update() print('Output image labels:') histogram(thres.GetOutput()) # Create writer if output_filename.lower().endswith('.nii'): writer = vtk.vtkNIFTIImageWriter() elif output_filename.lower().endswith('.nii.gz'): writer = vtk.vtkNIFTIImageWriter() else: os.sys.exit('[ERROR] Cannot find writer for file \"{}\"'.format( output_filename)) writer.SetInputConnection(thres.GetOutputPort()) writer.SetFileName(output_filename) writer.SetTimeDimension(reader.GetTimeDimension()) writer.SetTimeSpacing(reader.GetTimeSpacing()) writer.SetRescaleSlope(reader.GetRescaleSlope()) writer.SetRescaleIntercept(reader.GetRescaleIntercept()) writer.SetQFac(reader.GetQFac()) writer.SetQFormMatrix(reader.GetQFormMatrix()) writer.SetNIFTIHeader(reader.GetNIFTIHeader()) print('Saving image ' + output_filename) writer.Update()