def write(self, filename, data, hdr=None): # now write it out print('Writing: ' + filename) npd = self._convert_data_to_numpy_if_needed(data) data_itk = self._get_itk_image_from_numpy(npd, hdr) itk.imwrite(data_itk, native_str(filename))
def label_ROI(roiDir, ROI_exp, allRoisView, roiBaseImage, label): #for ROI in fnmatch.filter(os.listdir(roiDir), ROI_exp): #print(f'{ROI_exp} {label}') found = False for ROI in os.listdir(roiDir): #print('here ' + ROI + ' ' + ROI_exp) if fnmatch.fnmatch(ROI.lower(), ROI_exp): #print('yes ' + ROI) roisImage = itk.imread(os.path.join(roiDir, ROI)) # resize roisImage = gt.applyTransformation(input=roisImage, like=roiBaseImage, force_resample=True, interpolation_mode='NN') itk.imwrite(roisImage, f'{roiDir}/resized_{ROI}') roisView = itk.array_from_image(roisImage) allRoisView += roisView * label if np.any(allRoisView > label): print("Overlapping structures: " + str(int(allRoisView[allRoisView > label][0] - label)) + " and " + str(label)) allRoisView = np.where(allRoisView > label, label, allRoisView) #return allRoisView, False found = True #return allRoisView, True return allRoisView, found
def refreshView(self): # revise the voxels values to draw a bounding box revisedVolMat = drawBB(self.volMat,self.arrayBB) # write the revised volume with the bounding box revisedVolFilename = self.imgfilename[:-4]+'_bb.hdr' itk.imwrite(itk.GetImageFromArray(revisedVolMat.astype(np.float32)),revisedVolFilename) imgfilename = revisedVolFilename # read the revised volume using vtk # Create source vtkReader = vtk.vtkNIFTIImageReader() vtkReader.SetFileName(imgfilename) vtkReader.Update() # set a vtkvolume self.mapper.SetInputData(vtkReader.GetOutput()) #self.mapper.Update() vtkvolume = vtk.vtkVolume() vtkvolume.SetMapper(self.mapper) vtkvolume.SetProperty(self.volumeProperty) # set renderer self.ren.SetBackground(1,1,1) self.ren.AddVolume(vtkvolume) self.ren.ResetCamera() #self.ren.GetActiveCamera().Zoom(1.5) self.tipnameLabel.setText(self.displayName) self.frame.setLayout(self.vl) self.setCentralWidget(self.frame) self.show() self.iren.Initialize()
def write(self, filename: PathLike, verbose: bool = False, **kwargs): """ Create an ITK object from ``self.create_backend_obj(self.obj, ...)`` and call ``itk.imwrite``. Args: filename: filename or PathLike object. verbose: if ``True``, log the progress. kwargs: keyword arguments passed to ``itk.imwrite``, currently support ``compression`` and ``imageio``. See also: - https://github.com/InsightSoftwareConsortium/ITK/blob/v5.2.1/Wrapping/Generators/Python/itk/support/extras.py#L809 """ super().write(filename, verbose=verbose) self.data_obj = self.create_backend_obj( self.data_obj, channel_dim=self.channel_dim, affine=self.affine, dtype=self.output_dtype, # type: ignore affine_lps_to_ras=self.affine_lps_to_ras, # type: ignore **kwargs, ) itk.imwrite(self.data_obj, filename, compression=kwargs.pop("compression", False), imageio=kwargs.pop("imageio", None))
def rescaleAndWrite(filter, fileName): caster = itk.RescaleIntensityImageFilter[InternalImageType, OutputImageType].New( filter, OutputMinimum=0, OutputMaximum=255) itk.imwrite(caster, os.path.join(outputDirectory, fileName))
def median_filter_with_mask(img, mask, radius_dilatation, radius_median): # debug debug = False if debug: input = img itk.imwrite(img, 'ctvi_before.mhd') ctvim = itk.median_image_filter(img, radius=radius_median) itk.imwrite(ctvim, 'ctvi_median.mhd') dimg = dilate_at_boundaries(img, radius_dilatation) if debug: itk.imwrite(dimg, 'ctvi_before_dilated.mhd') imgm = itk.median_image_filter(dimg, radius=radius_median) if debug: itk.imwrite(imgm, 'ctvi_median_after_dilated.mhd') # reapply mask after median imgm = itk.array_from_image(imgm) imgm = imgm.astype('float') imgm[mask == 0] = 0 if debug: imgm = imgm.astype(np.float32) a = itk.image_from_array(imgm) a.CopyInformation(input) itk.imwrite(a, 'ctvi_median_final.mhd') return imgm
def test_image_uncertainty_by_slice(self): x = np.arange(0, 1, 0.01) y = np.arange(0, 1, 0.01) z = np.arange(0, 1, 0.01) xx, yy, zz = np.meshgrid(x, y, z) npImage = 10 * xx + 4.5 npsImage = 10 * xx**2 + 9 * xx + 2.85 image = itk.image_from_array(np.float32(npImage)) images = [image] simage = itk.image_from_array(np.float32(npsImage)) simages = [simage] uncertainty, mean, nb = image_uncertainty_by_slice(images, simages, N=1000000000000) tmpdirpath = tempfile.mkdtemp() itk.imwrite(uncertainty, os.path.join(tmpdirpath, "uncertainty.mha")) #self.assertTrue(mean[0] == 0.3356322509765625) npt.assert_almost_equal(mean[0], 0.3356322509765625) self.assertTrue(nb[0] == 10000) with open(os.path.join(tmpdirpath, "uncertainty.mha"), "rb") as fnew: bytesNew = fnew.read() new_hash = hashlib.sha256(bytesNew).hexdigest() self.assertTrue( "0a2dc7a0e28509c569cecde6b6252507936b29365cb4db0c75ab3c0fab3b2bc4" == new_hash) shutil.rmtree(tmpdirpath)
def vesselsIllumination(self, inputPath, outputPath, nbGaussianArtefacts, aSigmaMin, aSigmaMax, aImin, aImax): # Retrieving nifti data into arrays img = itk.imread(inputPath) dat = itk.GetArrayFromImage(img) dat = dat.astype(np.float32) # Artefacts a = np.zeros(dat.shape) if (nbGaussianArtefacts > 0): for i in range(nbGaussianArtefacts): a += self.makeGaussian(dat, aSigmaMin, aSigmaMax) a = a / a.max() * (aImax - aImin) + aImin a[a < aImin + 2] = 0 print("a", np.max(a), np.min(a)) dat = a + dat dat[dat < 0] = 0 dat[dat > 255] = 255 dat[0, 0, 0] = 0 # used for easier display in slicer dat[0, 0, 1] = 255 # used for easier display in slicer # writing image on disk # writing image on disk if (dat.dtype == np.uint8): illuminatedImg = itk.GetImageFromArray(dat.astype(np.uint8)) else: illuminatedImg = itk.GetImageFromArray( dat.astype(np.float32) ) # data is in double but it is not supported in itk print(dat.dtype) itk.imwrite(illuminatedImg, outputPath)
def imageFromGaussianPDF(self, inputPath, outputPath, dataType): if (dataType == "MRI"): print("using MRI") gaussianPDFLiver = norm(loc=108, scale=12) gaussianPDFVessels = norm(loc=119, scale=16) if (dataType == "CT"): print("using CT") gaussianPDFLiver = norm(loc=101, scale=14) gaussianPDFVessels = norm(loc=139, scale=16) img = itk.imread(inputPath) img_np = itk.GetArrayFromImage(img) mask = (img_np == 0) img_np[mask] = gaussianPDFLiver.rvs(img_np[mask].shape[0]) mask_vessels = (img_np > 0) img_np[mask_vessels] = gaussianPDFVessels.rvs( img_np[mask_vessels].shape[0]) dat = img_np dat = dat.astype(np.uint8) # for now if (dat.dtype == np.uint8): img = itk.GetImageFromArray(dat.astype(np.uint8)) else: img = itk.GetImageFromArray( dat.astype(np.float32) ) # data is in double but it is not supported in itk itk.imwrite(img, outputPath)
def _image_output(img,filename=None): """ Helper function for optional writing to file of output images. """ if filename is not None: itk.imwrite(img,filename) return img
def makeHardClassificationPatches(self, DirPath, inputPath, maskPath, outputPath): imgInputPath = DirPath + "/" + inputPath #"/DATA/vascu_deepV2/maskWholeImage.nii" imgMaskPath = DirPath + "/" + maskPath imgROIPath = DirPath + "/" + outputPath imgInput = itk.imread(imgInputPath) imgMask = itk.imread(imgMaskPath) PixelType = itk.UC Dimension = 3 ImageType = itk.Image[PixelType, Dimension] radiusValue = 4 StructuringElementType = itk.FlatStructuringElement[Dimension] structuringElement = StructuringElementType.Ball(radiusValue) DilateFilterType = itk.BinaryDilateImageFilter[ImageType, ImageType, StructuringElementType] dilateFilter = DilateFilterType.New() dilateFilter.SetInput(imgMask) dilateFilter.SetKernel(structuringElement) dilateFilter.SetForegroundValue(255) imgMask = dilateFilter.GetOutput() imgInput = itk.GetArrayFromImage(imgInput) imgMask = itk.GetArrayFromImage(imgMask) imgROI = np.copy(imgInput) imgROI[imgMask > 0] = 0 itk.imwrite(itk.GetImageFromArray(imgROI.astype(np.uint8)), imgROIPath)
def test_roi(self): tmpdirpath = tempfile.mkdtemp() filenameStruct = wget.download( "https://gitlab.in2p3.fr/opengate/gatetools_data/-/raw/master/rtstruct.dcm?inline=false", out=tmpdirpath, bar=None) structset = pydicom.read_file(os.path.join(tmpdirpath, filenameStruct)) # roi names roi_names = list_roinames(structset) filenameCT = wget.download( "https://gitlab.in2p3.fr/opengate/gatetools_data/-/raw/master/ct.mha?inline=false", out=tmpdirpath, bar=None) img = itk.imread(os.path.join(tmpdirpath, filenameCT)) self.assertTrue(len(roi_names) == 11) self.assertTrue(roi_names[0] == 'External') #Convert PTV aroi = region_of_interest(structset, roi_names[6]) mask = aroi.get_mask(img, corrected=False) itk.imwrite(mask, os.path.join(tmpdirpath, "testPTV.mha")) with open(os.path.join(tmpdirpath, "testPTV.mha"), "rb") as fnew: bytesNew = fnew.read() new_hash = hashlib.sha256(bytesNew).hexdigest() self.assertTrue( "7fc957af4cc082330cf5d430bb4d0d09a7e3be9918472580db32b5a636d8c147" == new_hash) shutil.rmtree(tmpdirpath)
def vesselsAndBackground(self, DirPath, file): imgPath = DirPath + "/" + file Imin = 50 Imax = 80 img = itk.imread(imgPath) dat = itk.GetArrayFromImage(img) dat = dat / np.max(dat) * (Imax - Imin) + Imin minValue = np.min(dat[dat > 0]) print(minValue) dat[dat == 0] = minValue dat = dat.astype(np.uint8) # for now if (dat.dtype == np.uint8): img = itk.GetImageFromArray(dat.astype(np.uint8)) else: img = itk.GetImageFromArray( dat.astype(np.float32) ) # data is in double but it is not supported in itk outputPath = DirPath + "/vesselsAndBackground.nii" itk.imwrite(img, outputPath)
def noisyImage(self, DirPath, file, outputFile, noiseType): imgPath = DirPath + "/" + file print(DirPath) print(imgPath) for id, i in enumerate(self.noiseLevels): img = itk.imread(imgPath) dat = itk.GetArrayFromImage(img) # simulated CT noise poisson + gaussian noise if (noiseType == "poisson"): datNoisy = 0.5 * np.random.poisson( dat, None) + 0.5 * np.random.normal(dat, i, None) elif (noiseType == "rician"): datNoisy = rice.rvs(dat / i, scale=i) else: print("error noise type not supported") datNoisy[datNoisy < 0] = 0 datNoisy[datNoisy > 255] = 255 # writing image on disk if (dat.dtype == np.uint8): noisyImg = itk.GetImageFromArray(datNoisy.astype(np.uint8)) else: noisyImg = itk.GetImageFromArray( datNoisy.astype(np.float32) ) # data is in double but it is not supported in itk print(i) outputPath = DirPath + "/" + outputFile + "_" + str(i) + ".nii" itk.imwrite(noisyImg, outputPath) print(outputPath)
def sum_dose(filelist, imgoutput=None): """ Sum mhd/raw absolute doses; generate image if output specified or return array of values otherwise """ total = None if len(filelist) == 0: print("No files given to sum_dose") elif len(filelist) == 1: total = itk.array_from_image(itk.imread(filelist[0])) else: # Take first ff = filelist[0] total = itk.array_from_image(itk.imread(ff)) # Loop through rest for n in range(1, len(filelist)): file = filelist[n] total += itk.array_from_image(itk.imread(file)) if imgoutput == None: return total else: sumimg = itk.image_from_array(total) # Take properties from any; TODO: should check they're all the same? sumimg.CopyInformation(itk.imread(filelist[0])) itk.imwrite(sumimg, imgoutput)
def intensity_normalization_histmatch(args): # load the atlas image which will be used for histogram matching image_atlas = itk.imread(os.path.expanduser(args.atlas)) for i in range(0, len(args.input_images)): if args.affine: # affine registration has happened before image = itk.imread(os.path.expanduser(args.output_images[i])) else: image = itk.imread(os.path.expanduser(args.input_images[i])) image_np = itk.GetArrayViewFromImage(image) nan_mask = np.isnan(image_np) image_np[nan_mask] = 0 # perform histogram matching dim = image.GetImageDimension() ImageType = itk.Image[itk.F, dim] match_filter = itk.HistogramMatchingImageFilter[ImageType, ImageType].New() match_filter.SetReferenceImage(image_atlas) match_filter.SetInput(image) match_filter.Update() itk.imwrite(match_filter.GetOutput(), os.path.expanduser(args.output_images[i]), compression=True)
def convert_dose_to_water(ctpath, dosepath, emcalcpath, hu2matpath, output=None): """Convert a doseimg (to material) to dose-to-water Divide dose-to-tissue by RSP; see Paganetti2019 Input: paths to ct image and doseToMaterial image """ rsps = get_rsps_from_emcalc(emcalcpath) hu2mat = open(hu2matpath,"r").readlines() # Read lower HU bracket and physical density from materials database #hu_lims, den_lims = read_densities(materialdbpath) ctimg = itk.imread( ctpath ) doseimg = itk.imread( dosepath ) # Resample CT image to match voxel resolution of dose image resampledimg = resample( ctimg, doseimg ) #itk.imwrite(resampledimg, "resampled_ct.mhd") hus = itk.array_from_image( resampledimg ) doses = itk.array_from_image( doseimg ) shape = hus.shape hus_flat = hus.flatten() doses_flat = doses.flatten() d2water = np.zeros(len(hus_flat)) if len(hus_flat)!=len(doses_flat): print("ERROR: resampled image does not match dose image dimensions") exit() else: for i,hu in enumerate(hus_flat): # Get material name from HU material="" for line in hu2mat: cols = line.split() if hu < float(cols[1]): material = cols[2] break if material=="": print(" NO MATERIAL ASSIGNED for HU={}".format(hu)) material = "Adiposetissue3" rsp = rsps[material] d2w = doses_flat[i] / rsp if d2w<0: print(" WARNING: d2water < 0 detected") d2water[i] = d2w d2water_arr = d2water.reshape( shape ) dosetowater = itk.image_view_from_array( d2water_arr ) dosetowater.CopyInformation(doseimg) if output is not None: itk.imwrite(dosetowater, output) return dosetowater
def intensity_normalization_histadapt(args): print( 'WARNING: Make sure the ouput is really want you want. Settings not well tested.' ) for i in range(0, len(args.input_images)): if args.affine: # affine registration has happened before image = itk.imread(os.path.expanduser(args.output_images[i])) else: image = itk.imread(os.path.expanduser(args.input_images[i])) image_np = itk.GetArrayViewFromImage(image) nan_mask = np.isnan(image_np) image_np[nan_mask] = 0 # perform histogram matching dim = image.GetImageDimension() ImageType = itk.Image[itk.F, dim] adapt_filter = itk.AdaptiveHistogramEqualizationImageFilter[ ImageType].New() adapt_filter.SetAlpha( 0.1) # 0: classical histogram equalization; 1: unsharp mask adapt_filter.SetBeta(0.0) adapt_filter.SetRadius(5) adapt_filter.SetInput(image) adapt_filter.Update() itk.imwrite(adapt_filter.GetOutput(), os.path.expanduser(args.output_images[i]), compression=True)
def override_hu(img_file, structure_file, output_img, structure, hu): #MAYBE JUST PASS THE IMAGE OBJECT AND DICOM OBJECT?? """Override all HUs inside of specified structure""" img = itk.imread(img_file) ds = pydicom.dcmread(structure_file) # TESTING GATETOOLS aroi = roiutils.region_of_interest(ds, structure) mask = aroi.get_mask(img, corrected=False) ##aroi = rt.region_of_interest( ds, structure ) ##mask = aroi.get_mask(img, corrected=False) pix_mask = itk.array_view_from_image(mask) pix_img = itk.array_view_from_image(img) if (pix_mask.shape != pix_img.shape): print("Inconsistent shapes of mask and image") pix_img_flat = pix_img.flatten() for i, val in enumerate(pix_mask.flatten()): if val == 1: pix_img_flat[i] = hu pix_img = pix_img_flat.reshape(pix_img.shape) img_modified = itk.image_view_from_array(pix_img) img_modified.CopyInformation(img) ##img_modified.SetSpacing( img.GetSpacing() ) # "ElementSpacing" in .mhd ##img_modified.SetOrigin( img.GetOrigin() ) # "Offset" in .mhd itk.imwrite(img_modified, output_img)
def interpolate_secondaries(input_folder, output_folder, factor, target_numprojs): sec_numprojs = len(glob.glob(f'./{input_folder}/secondary????.mha')) img0 = itk.imread(f'./{input_folder}/secondary0000.mha') img_origin = itk.origin(img0) img_spacing = itk.spacing(img0) image_ind = 0 for projnum in range(sec_numprojs - 1): # get image1 = f'./{input_folder}/secondary{projnum:04d}.mha' image2 = f'./{input_folder}/secondary{projnum+1:04d}.mha' img1_array = itk.GetArrayFromImage(itk.imread(image1)) img2_array = itk.GetArrayFromImage(itk.imread(image2)) # save the first image itk.imwrite(itk.imread(image1), f'./{output_folder}/secondary{image_ind:04d}.mha') # interpolate xfactor images between those 2 images image_interpolate_recurrence(img1_array, img2_array, image_ind, image_ind + factor, output_folder, img_origin, img_spacing) image_ind = image_ind + factor # read the last image and save it until the target_numprojs is reached lastimage = itk.imread( f'./{input_folder}/secondary{sec_numprojs-1:04d}.mha') while image_ind < target_numprojs: itk.imwrite(lastimage, f'./{output_folder}/secondary{image_ind:04d}.mha') image_ind = image_ind + 1
def noisyImage(self, inputPath, outputName, noiseType): for id, i in enumerate(self.noiseLevels): img = itk.imread(inputPath) dat = itk.GetArrayFromImage(img) dat = dat.astype(np.float32) # simulated CT noise poisson + gaussian noise if (noiseType == "poisson"): datNoisy = 0.5 * np.random.poisson( dat, None) + 0.5 * np.random.normal(dat, i, None) elif (noiseType == "rician"): datNoisy = rice.rvs(dat / i, scale=i) else: print("error noise type not supported") datNoisy[datNoisy < 0] = 0 datNoisy[datNoisy > 255] = 255 # writing image on disk noisyImg = itk.GetImageFromArray(datNoisy.astype(np.uint8)) print(i) outputPath = outputName + "_" + str(i) + ".nii" itk.imwrite(noisyImg, outputPath) print(outputPath)
def image_interpolate_recurrence(image1, image2, ind1, ind2, output_folder, img_origin, img_spacing): avg_img = (image1 + image2) / 2 new_ind = (ind1 + ind2) / 2 integer_ind = int(new_ind) if (new_ind == integer_ind): # even number # save this projection output_imagename = f'./{output_folder}/secondary{int(integer_ind):04d}.mha' outputimage = itk.GetImageFromArray(avg_img) outputimage.SetOrigin(img_origin) outputimage.SetSpacing(img_spacing) itk.imwrite(outputimage, output_imagename) # check if can divide more if integer_ind - ind1 > 1: # call this function again twice, once to the left and once to the right image_interpolate_recurrence(image1, avg_img, ind1, integer_ind, output_folder, img_origin, img_spacing) image_interpolate_recurrence(avg_img, image2, integer_ind, ind2, output_folder, img_origin, img_spacing) else: # check if can divide more if new_ind - ind1 > 1: # call this function again twice, once to the left and once to the right image_interpolate_recurrence(image1, avg_img, ind1, int(math.ceil(new_ind)), output_folder, img_origin, img_spacing) image_interpolate_recurrence(avg_img, image2, int(math.floor(new_ind)), ind2, output_folder, img_origin, img_spacing)
def process_image(filename, output_folder, sigma): """ Reorient image at filename, smooth with sigma, clamp and save to output_folder. :param filename: The image filename. :param output_folder: The output folder. :param sigma: Sigma for smoothing. """ basename = os.path.basename(filename) basename_wo_ext = basename[:basename.find('.nii.gz')] print(basename_wo_ext) ImageType = itk.Image[itk.SS, 3] reader = itk.ImageFileReader[ImageType].New() reader.SetFileName(filename) image = reader.GetOutput() reoriented = reorient_to_rai(image) if not basename_wo_ext.endswith('_seg'): reoriented = smooth(reoriented, sigma) reoriented = clamp(reoriented) reoriented.SetOrigin([0, 0, 0]) m = itk.GetMatrixFromArray( np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.float64)) reoriented.SetDirection(m) reoriented.Update() itk.imwrite(reoriented, os.path.join(output_folder, basename_wo_ext + '.nii.gz'))
def dilat(input, output): ''' Doc todo ''' print(input) ctvi = itk.imread(input) ImageType = type(ctvi) Dimension = ctvi.GetImageDimension() radiusValue = 1 StructuringElementType = itk.FlatStructuringElement[Dimension] structuringElement = StructuringElementType.Ball(radiusValue) grayscaleFilter = itk.GrayscaleDilateImageFilter[ ImageType, ImageType, StructuringElementType].New() grayscaleFilter.SetInput(ctvi) grayscaleFilter.SetKernel(structuringElement) grayscaleFilter.Update() o = grayscaleFilter.GetOutput() o = itk.array_from_image(o) c = itk.array_from_image(ctvi) o[c > 0.0] = 0 o = c + o o = itk.image_from_array(o) o.CopyInformation(ctvi) itk.imwrite(o, output)
def write_itk(image_np, output_file, affine, dtype, compress): if len(image_np.shape) > 2: image_np = image_np.transpose().copy() if dtype: image_np = image_np.astype(dtype) result_image = itk.image_from_array(image_np) logger.debug(f"ITK Image size: {itk.size(result_image)}") # https://github.com/RSIP-Vision/medio/blob/master/medio/metadata/affine.py#L108-L121 if affine is not None: convert_aff_mat = np.diag([-1, -1, 1, 1]) if affine.shape[0] == 3: convert_aff_mat = np.diag([-1, -1, 1]) affine = convert_aff_mat @ affine dim = affine.shape[0] - 1 _origin_key = (slice(-1), -1) _m_key = (slice(-1), slice(-1)) origin = affine[_origin_key] spacing = np.linalg.norm(affine[_m_key] @ np.eye(dim), axis=0) direction = affine[_m_key] @ np.diag(1 / spacing) logger.debug(f"Affine: {affine}") logger.debug(f"Origin: {origin}") logger.debug(f"Spacing: {spacing}") logger.debug(f"Direction: {direction}") result_image.SetDirection(itk.matrix_from_array(direction)) result_image.SetSpacing(spacing) result_image.SetOrigin(origin) itk.imwrite(result_image, output_file, compress)
def setUp(self): '''Setup for TestGetVTKReaderFromFileName''' # Create a temporary directory self.test_dir = tempfile.mkdtemp() # Create an image with a known orientation dimension = 3 pixel_string = 'unsigned char' index = [0, 0, 0] size = [10, 10, 10] # Create image self.image_region = create_itk_image_region(dimension, index, size) self.image = create_itk_image(dimension, pixel_string, self.image_region) # Save image self.nifti_file_name = os.path.join(self.test_dir, 'nifti.nii') self.nifti_gz_file_name = os.path.join(self.test_dir, 'nifti.nii.gz') self.meta_file_name = os.path.join(self.test_dir, 'meta.mhd') self.nrrd_file_name = os.path.join(self.test_dir, 'nrrd.nrrd') self.file_names = [ self.nifti_file_name, self.nifti_gz_file_name, self.meta_file_name, self.nrrd_file_name ] for file_name in self.file_names: itk.imwrite(self.image, file_name) # Fake image for testing self.fake_file_name = os.path.join(self.test_dir, 'fake.file')
def save_as_jpeg(image, out_dir, current_slice): # To save as a jpeg, rescale between 0 and 255 (unsigned char) OutputImageType = itk.Image[itk.UC, OUTPUT_IMAGE_DIMENSION] cast_filter = itk.CastImageFilter[image, OutputImageType].New(image) cast_filter.Update() output_image_filename = os.path.join(out_dir, '%d.jpg' % current_slice) itk.imwrite(cast_filter.GetOutput(), output_image_filename)
def test_stitch_image(self): x = np.arange(0, 23, 1) y = np.arange(20, 40, 1) z = np.arange(0, 27, 1) xx, yy, zz = np.meshgrid(x, y, z) image1 = itk.image_from_array(np.int16(xx)) image1.SetOrigin([7, 3.4, 30]) image1.SetSpacing([2, 2, 2]) x = np.arange(0, 23, 1) y = np.arange(0, 30, 1) z = np.arange(0, 27, 1) xx, yy, zz = np.meshgrid(x, y, z) image2 = itk.image_from_array(np.int16(xx)) image2.SetOrigin([7, 3.4, -10]) image2.SetSpacing([2, 2, 2]) output = stitch_image(image1, image2, dimension=2, pad=0) tmpdirpath = tempfile.mkdtemp() itk.imwrite(output, os.path.join(tmpdirpath, "testStitch.mha")) with open(os.path.join(tmpdirpath, "testStitch.mha"), "rb") as fnew: bytesNew = fnew.read() new_hash = hashlib.sha256(bytesNew).hexdigest() self.assertTrue( "89d8c32d1482b4b582ccfdfe824881ccbdffe5a3dbfca9a8e101b882c79bb41c" == new_hash) shutil.rmtree(tmpdirpath)
def ctvi(exhale, inhale, lung_mask, output, radius_erode_mask, sigma_gauss, radius_median, rho_normalize): ''' Doc todo ''' exhale = itk.imread(exhale) inhale = itk.imread(inhale) lung_mask = itk.imread(lung_mask) # options options = Box() options.ventil_type = 'Kipritidis2015' options.rho_normalize = rho_normalize options.sigma_gauss = sigma_gauss options.radius_median = radius_median options.remove_10pc = False options.mass_corrected_inhale = True if radius_erode_mask != 0: mask = itk.array_view_from_image(lung_mask) mask[mask != 0] = 1 lung_mask = erode_mask(lung_mask, radius_erode_mask) # go ctvi = compute_ctvi(exhale, inhale, lung_mask, options) itk.imwrite(ctvi, output)
def merge_pred(results_folder, ROI_list): # get the list of Task folders tasks_folders = glob.glob(f'{results_folder}/segm_results/Task*') if len(tasks_folders) != 3: print('Not all direction available, no merging was performed') sys.exit() # get the list of labels all_patients = glob.glob( f'{results_folder}/segm_results/{os.path.basename(tasks_folders[0])}/predicted_labels/*' ) merged_labels = f'{results_folder}/segm_results/merged_labels' merged_binaries = f'{results_folder}/segm_results/merged_binaries' maybe_mkdir_p(merged_labels) maybe_mkdir_p(merged_binaries) # loop through the patient for patient in all_patients: label_name = os.path.basename(patient) patient_name = label_name.replace('label_', '') merged_binaries_patient = f'{merged_binaries}/{os.path.splitext(patient_name)[0]}' maybe_mkdir_p(merged_binaries_patient) # load labels in each direction label_d1_img = itk.imread( f'{tasks_folders[0]}/predicted_labels/{label_name}') label_origin = label_d1_img.GetOrigin() label_spacing = label_d1_img.GetSpacing() label_direction = label_d1_img.GetDirection() label_d1 = itk.GetArrayFromImage(label_d1_img) label_d2 = itk.GetArrayFromImage( itk.imread(f'{tasks_folders[1]}/predicted_labels/{label_name}')) label_d3 = itk.GetArrayFromImage( itk.imread(f'{tasks_folders[2]}/predicted_labels/{label_name}')) # get the intersection of every 2 labels intersec1 = np.where(label_d1 == label_d2, label_d1, 0) intersec2 = np.where(label_d1 == label_d3, label_d1, 0) intersec3 = np.where(label_d2 == label_d3, label_d2, 0) # get where 2 labels agree merged_label = np.zeros(label_d1.shape) merged_label = np.where(intersec1 != 0, intersec1, merged_label) merged_label = np.where(intersec2 != 0, intersec2, merged_label) merged_label = np.where(intersec3 != 0, intersec3, merged_label) merged_label_img = itk.GetImageFromArray(merged_label) merged_label_img.SetOrigin(label_origin) merged_label_img.SetSpacing(label_spacing) merged_label_img.SetDirection(label_direction) itk.imwrite(merged_label_img, f'{merged_labels}/{label_name}') segmap_to_binaries(merged_label, merged_binaries_patient, label_origin, label_spacing, label_direction, ROI_list)
def rescaleAndWrite(filter, fileName): caster = itk.RescaleIntensityImageFilter[ InternalImageType, OutputImageType].New( filter, OutputMinimum=0, OutputMaximum=255) itk.imwrite(caster, os.path.join(outputDirectory, fileName))
# See the License for the specific language governing permissions and # limitations under the License. # #==========================================================================*/ # # Example on the use of the MedianImageFilter # import itk from sys import argv input_filename = argv[1] output_filename = argv[2] radius = int(argv[3]) reader = itk.ImageFileReader.IUC2.New(FileName=input_filename) # test the deduction of the template parameter from the input filt = itk.MedianImageFilter.New(reader, Radius=radius) filt.Update() result = filt.GetOutput() watcher = itk.XMLFilterWatcher(filt, "filter") # test the update of the filter with the snake case function # and the setting of parameter inside it result = itk.median_image_filter(reader, radius=radius) # test the write method itk.imwrite(result, output_filename)
extractFilter.SetDirectionCollapseToSubmatrix() # set up the extraction region [one slice] inputRegion = inputImage.GetBufferedRegion() size = inputRegion.GetSize() size[2] = 1 # we extract along z direction start = inputRegion.GetIndex() sliceNumber = int(sys.argv[3]) start[2] = sliceNumber desiredRegion = inputRegion desiredRegion.SetSize(size) desiredRegion.SetIndex(start) extractFilter.SetExtractionRegion(desiredRegion) pasteFilter = itk.PasteImageFilter.New(inputImage) medianFilter = itk.MedianImageFilter.New(extractFilter) pasteFilter.SetSourceImage(medianFilter.GetOutput()) pasteFilter.SetDestinationImage(inputImage) pasteFilter.SetDestinationIndex(start) indexRadius = size indexRadius[0] = 1 # radius along x indexRadius[1] = 1 # radius along y indexRadius[2] = 0 # radius along z medianFilter.SetRadius(indexRadius) medianFilter.UpdateLargestPossibleRegion() medianImage = medianFilter.GetOutput() pasteFilter.SetSourceRegion(medianImage.GetBufferedRegion()) itk.imwrite(pasteFilter.GetOutput(), outputFilename)
# test region s = itk.region(reader) assert s.GetIndex()[0] == s.GetIndex()[1] == 0 assert s.GetSize()[0] == s.GetSize()[1] == 256 s = itk.region(reader.GetOutput()) assert s.GetIndex()[0] == s.GetIndex()[1] == 0 assert s.GetSize()[0] == s.GetSize()[1] == 256 # test range assert itk.range(reader) == (0, 255) assert itk.range(reader.GetOutput()) == (0, 255) # test write itk.imwrite(reader, sys.argv[2]) itk.imwrite(reader, sys.argv[2], True) # test read image=itk.imread(fileName) assert type(image) == itk.Image[itk.RGBPixel[itk.UC],2] image=itk.imread(fileName, itk.F) assert type(image) == itk.Image[itk.F,2] # test search res = itk.search("Index") assert res[0] == "Index" assert res[1] == "index" assert "ContinuousIndex" in res res = itk.search("index", True)
# test region s = itk.region(reader) assert s.GetIndex()[0] == s.GetIndex()[1] == 0 assert s.GetSize()[0] == s.GetSize()[1] == 256 s = itk.region(reader.GetOutput()) assert s.GetIndex()[0] == s.GetIndex()[1] == 0 assert s.GetSize()[0] == s.GetSize()[1] == 256 # test range assert itk.range(reader) == (0, 255) assert itk.range(reader.GetOutput()) == (0, 255) # test write itk.imwrite(reader, sys.argv[2]) itk.write(reader, sys.argv[2]) itk.imwrite(reader, sys.argv[2], True) # test read image=itk.imread(fileName) assert type(image) == itk.Image[itk.RGBPixel[itk.UC],2] image=itk.imread(fileName, itk.F) assert type(image) == itk.Image[itk.F,2] # test search res = itk.search("Index") assert res[0] == "Index" assert res[1] == "index" assert "ContinuousIndex" in res
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import argparse import itk from distutils.version import StrictVersion as VS if VS(itk.Version.GetITKVersion()) < VS("5.0.0"): print("ITK 5.0.0 or newer is required.") sys.exit(1) parser = argparse.ArgumentParser(description='Segment blood vessels.') parser.add_argument('input_image') parser.add_argument('output_image') parser.add_argument('--sigma', type=float, default=1.0) parser.add_argument('--alpha1', type=float, default=0.5) parser.add_argument('--alpha2', type=float, default=2.0) args = parser.parse_args() input_image = itk.imread(args.input_image, itk.ctype('float')) hessian_image = itk.hessian_recursive_gaussian_image_filter(input_image, sigma=args.sigma) vesselness_filter = itk.Hessian3DToVesselnessMeasureImageFilter[itk.ctype('float')].New() vesselness_filter.SetInput(hessian_image) vesselness_filter.SetAlpha1(args.alpha1) vesselness_filter.SetAlpha2(args.alpha2) itk.imwrite(vesselness_filter, args.output_image)
#========================================================================== # # Copyright Insight Software Consortium # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0.txt # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #==========================================================================*/ # # Example on the use of the MeanImageFilter with function calls # import itk from sys import argv image = itk.imread(argv[1]) filtered_image = itk.MeanImageFilter(image, Radius=int(argv[3])) itk.imwrite(filtered_image, argv[2])
def main(): if len(argv) < 10: errMsg = "Missing parameters\n" \ "Usage: %s\n" % (argv[0],) + \ " inputImage outputImage\n" \ " seedX seedY InitialDistance\n" \ " Sigma SigmoidAlpha SigmoidBeta\n" \ " PropagationScaling\n" print(errMsg, file=stderr) return # We're going to build the following pipelines: # 1. reader -> smoothing -> gradientMagnitude -> sigmoid -> FI # 2. fastMarching -> geodesicActiveContour(FI) -> thresholder -> writer # The output of pipeline 1 is a feature image that is used by the # geodesicActiveContour object. Also see figure 9.18 in the ITK # Software Guide. # we wan't to know what is happening # itk.auto_progress(True) InternalPixelType = itk.F Dimension = 2 InternalImageType = itk.Image[InternalPixelType, Dimension] OutputPixelType = itk.UC OutputImageType = itk.Image[OutputPixelType, Dimension] reader = itk.ImageFileReader[InternalImageType].New(FileName=argv[1]) # needed to give the size to the fastmarching filter reader.Update() outputDirectory = os.path.dirname(argv[2]) smoothing = itk.CurvatureAnisotropicDiffusionImageFilter[ InternalImageType, InternalImageType].New( reader, TimeStep=0.125, NumberOfIterations=5, ConductanceParameter=9.0) gradientMagnitude = itk.GradientMagnitudeRecursiveGaussianImageFilter[ InternalImageType, InternalImageType].New( smoothing, Sigma=float(argv[6])) sigmoid = itk.SigmoidImageFilter[InternalImageType, InternalImageType].New( gradientMagnitude, OutputMinimum=0.0, OutputMaximum=1.1, Alpha=float(argv[7]), Beta=float(argv[8])) seedPosition = itk.Index[2]() seedPosition.SetElement(0, int(argv[3])) seedPosition.SetElement(1, int(argv[4])) node = itk.LevelSetNode[InternalPixelType, Dimension]() node.SetValue(-float(argv[5])) node.SetIndex(seedPosition) seeds = itk.VectorContainer[ itk.UI, itk.LevelSetNode[InternalPixelType, Dimension]].New() seeds.Initialize() seeds.InsertElement(0, node) fastMarching = itk.FastMarchingImageFilter[ InternalImageType, InternalImageType].New( sigmoid, TrialPoints=seeds, SpeedConstant=1.0, OutputSize=reader.GetOutput().GetBufferedRegion().GetSize()) geodesicActiveContour = itk.GeodesicActiveContourLevelSetImageFilter[ InternalImageType, InternalImageType, InternalPixelType].New( fastMarching, # it is required to use the explicitly the FeatureImage # - itk segfault without that :-( FeatureImage=sigmoid.GetOutput(), PropagationScaling=float(argv[9]), CurvatureScaling=1.0, AdvectionScaling=1.0, MaximumRMSError=0.02, NumberOfIterations=800) thresholder = itk.BinaryThresholdImageFilter[ InternalImageType, OutputImageType].New( geodesicActiveContour, LowerThreshold=-1000, UpperThreshold=0, OutsideValue=0, InsideValue=255) writer = itk.ImageFileWriter[OutputImageType].New( thresholder, FileName=argv[2]) def rescaleAndWrite(filter, fileName): caster = itk.RescaleIntensityImageFilter[ InternalImageType, OutputImageType].New( filter, OutputMinimum=0, OutputMaximum=255) itk.imwrite(caster, os.path.join(outputDirectory, fileName)) rescaleAndWrite(smoothing, "GeodesicActiveContourImageFilterOutput1.png") rescaleAndWrite( gradientMagnitude, "GeodesicActiveContourImageFilterOutput2.png") rescaleAndWrite(sigmoid, "GeodesicActiveContourImageFilterOutput3.png") rescaleAndWrite( fastMarching, "GeodesicActiveContourImageFilterOutput4.png") writer.Update() print("") print( "Max. no. iterations: %d" % (geodesicActiveContour.GetNumberOfIterations())) print( "Max. RMS error: %.3f" % (geodesicActiveContour.GetMaximumRMSError())) print("") print( "No. elapsed iterations: %d" % (geodesicActiveContour.GetElapsedIterations())) print("RMS change: %.3f" % (geodesicActiveContour.GetRMSChange())) itk.imwrite(fastMarching, os.path.join(outputDirectory, "GeodesicActiveContourImageFilterOutput4.mha")) itk.imwrite(sigmoid, os.path.join(outputDirectory, "GeodesicActiveContourImageFilterOutput3.mha")) itk.imwrite(gradientMagnitude, os.path.join(outputDirectory, "GeodesicActiveContourImageFilterOutput2.mha"))
# # Copyright Insight Software Consortium # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0.txt # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # #==========================================================================*/ # # Example on the use of the SmoothingRecursiveGaussianImageFilter # import itk from sys import argv itk.auto_progress(2) reader = itk.ImageFileReader.IUC2.New(FileName=argv[1]) filter = itk.SmoothingRecursiveGaussianImageFilter.New( reader, Sigma=eval(argv[3])) itk.imwrite(filter, argv[2])
import itk if len(sys.argv) != 6: print('Usage: ' + sys.argv[0] + ' <InputFileName> <OutputFileName> <Alpha> <Beta> <Radius>') sys.exit(1) inputFileName = sys.argv[1] outputFileName = sys.argv[2] alpha = float(sys.argv[3]) beta = float(sys.argv[4]) radiusValue = int(sys.argv[5]) Dimension = 2 PixelType = itk.ctype('unsigned char') ImageType = itk.Image[PixelType, Dimension] reader = itk.ImageFileReader[ImageType].New() reader.SetFileName(inputFileName) histogramEqualization = \ itk.AdaptiveHistogramEqualizationImageFilter.New(reader) histogramEqualization.SetAlpha(alpha) histogramEqualization.SetBeta(beta) radius = itk.Size[Dimension]() radius.Fill(radiusValue); histogramEqualization.SetRadius(radius) itk.imwrite(histogramEqualization, outputFileName)
input_image = itk.imread(args.input_image, itk.F) ImageType = type(input_image) Dimension = input_image.GetImageDimension() HessianPixelType = itk.SymmetricSecondRankTensor[itk.D, Dimension] HessianImageType = itk.Image[HessianPixelType, Dimension] objectness_filter = itk.HessianToObjectnessMeasureImageFilter[HessianImageType, ImageType].New() objectness_filter.SetBrightObject(False) objectness_filter.SetScaleObjectnessMeasure(False) objectness_filter.SetAlpha(0.5) objectness_filter.SetBeta(1.0) objectness_filter.SetGamma(5.0) multi_scale_filter = itk.MultiScaleHessianBasedMeasureImageFilter[ImageType, HessianImageType, ImageType].New() multi_scale_filter.SetInput(input_image) multi_scale_filter.SetHessianToMeasureFilter(objectness_filter) multi_scale_filter.SetSigmaStepMethodToLogarithmic() multi_scale_filter.SetSigmaMinimum(args.sigma_minimum) multi_scale_filter.SetSigmaMaximum(args.sigma_maximum) multi_scale_filter.SetNumberOfSigmaSteps(args.number_of_sigma_steps) OutputPixelType = itk.UC OutputImageType = itk.Image[OutputPixelType, Dimension] rescale_filter = itk.RescaleIntensityImageFilter[ImageType, OutputImageType].New() rescale_filter.SetInput(multi_scale_filter) itk.imwrite(rescale_filter.GetOutput(), args.output_image)