def test_mesh_to_image(): # Import succeeds from hasi.align import mesh_to_image # Mesh-to-image executes without error images = mesh_to_image([template_mesh, target_mesh]) # Images were generated assert (all([ type(image) == itk.Image[mesh_pixel_type, dimension] for image in images ])) # Images occupy the same physical space assert (all( [itk.spacing(image) == itk.spacing(images[0]) for image in images])) assert (all([itk.size(image) == itk.size(images[0]) for image in images])) assert (all( [itk.origin(image) == itk.origin(images[0]) for image in images])) # Mesh-to-image can run with reference image image_from_reference = mesh_to_image(target_mesh, reference_image=images[0]) # Type and image attributes match previous output assert (type(image_from_reference) == type(images[0])) assert (itk.spacing(image_from_reference) == itk.spacing(images[0])) assert (itk.size(image_from_reference) == itk.size(images[0])) assert (itk.origin(image_from_reference) == itk.origin(images[0]))
def paste_to_common_space(images:list) -> list: image_type = type(images[0]) pixel_type, dimension = itk.template(images[0])[1] resized_images = list() # Verify spacing is equivalent SPACING_TOLERANCE = 1e-7 assert(all([itk.spacing(images[idx])[dim] - itk.spacing(images[0])[dim] < SPACING_TOLERANCE for dim in range(dimension) for idx in range(1,len(images))])) # Get largest common region max_size = itk.size(images[0]) for image in images: max_size = [max(max_size[i], itk.size(image)[i]) for i in range(len(max_size))] # Define paste region for image in images: region = itk.ImageRegion[dimension]() region.SetSize(max_size) region.SetIndex([0] * dimension) new_image = type(images[0]).New(regions=region, spacing=image.GetSpacing()) new_image.Allocate() resized_image = itk.paste_image_filter(source_image=image, source_region=image.GetLargestPossibleRegion(), destination_image=new_image, destination_index=[0] * dimension, ttype=type(image)) resized_images.append(resized_image) return resized_images
def test_downsample_images(): DOWNSAMPLE_RATIO = 2.0 # Import succeeds from hasi.align import mesh_to_image, downsample_images # Downsample succeeds images = downsample_images([target_healthy_image, target_unhealthy_image], DOWNSAMPLE_RATIO) assert (len(images) == 2) # Downsampled image dimensions adjusted by expected ratio assert (itk.size(images[0]) == [ int(itk.size(target_healthy_image)[dim] / DOWNSAMPLE_RATIO) for dim in range(dimension) ]) assert (itk.spacing(images[0]) == [ itk.spacing(target_healthy_image)[dim] * DOWNSAMPLE_RATIO for dim in range(dimension) ]) assert (itk.size(images[1]) == [ int(itk.size(target_unhealthy_image)[dim] / DOWNSAMPLE_RATIO) for dim in range(dimension) ]) assert (itk.spacing(images[1]) == [ itk.spacing(target_unhealthy_image)[dim] * DOWNSAMPLE_RATIO for dim in range(dimension) ])
def enclosing_geometry(img1, img2): """ Does img1 enclose img2? This function could be used to test whether img2 can be used as a reference image for resampling img1. """ if equal_geometry(img1, img2): return True o1 = np.array(itk.origin(img1)) o2 = np.array(itk.origin(img2)) s1 = np.array(itk.spacing(img1)) s2 = np.array(itk.spacing(img2)) n1 = np.array(itk.size(img1)) n2 = np.array(itk.size(img2)) # compute corners lower1 = o1 - 0.5 * s1 lower2 = o2 - 0.5 * s2 upper1 = o1 + (n1 - 0.5) * s1 upper2 = o2 + (n2 - 0.5) * s2 ####################################################################### # for debugging: percentages of img2 that are inside/outside of img1. # ####################################################################### bb1 = bounding_box(img=img1) vol1 = bb1.volume bb2 = bounding_box(img=img2) vol2 = bb2.volume assert (vol2 > 0) bb2.intersect(bb1) overlap = bb2.volume outside = vol2 - bb2.volume overlap_percent = overlap * 100. / vol2 outside_percent = outside * 100. / vol2 logger.debug(f"vol img2={vol1} vol img2={vol2}") logger.debug( f"part of img2 that overlaps with img1: {overlap} or {overlap_percent} percent" ) logger.debug( f"part of img2 that is outside img1: {outside} or {outside_percent} percent" ) ####################################################################### # end debugging section # ####################################################################### # now check the lower corner if (np.logical_not(np.isclose(lower1, lower2)) * (lower1 > lower2)).any(): return False # now check the upper corner if (np.logical_not(np.isclose(upper1, upper2)) * (upper1 < upper2)).any(): return False return True
def test_itk_registration(self): import os os.environ["FOOTSTEPS_NAME"] = "test" import footsteps icon_registration.test_utils.download_test_data() model = icon_registration.pretrained_models.OAI_knees_registration_model( pretrained=True) image_A = itk.imread( str(icon_registration.test_utils.TEST_DATA_DIR / "knees_diverse_sizes" / #"9126260_20060921_SAG_3D_DESS_LEFT_11309302_image.nii.gz") "9487462_20081003_SAG_3D_DESS_RIGHT_11495603_image.nii.gz")) image_B = itk.imread( str(icon_registration.test_utils.TEST_DATA_DIR / "knees_diverse_sizes" / "9225063_20090413_SAG_3D_DESS_RIGHT_12784112_image.nii.gz")) print(image_A.GetLargestPossibleRegion().GetSize()) print(image_B.GetLargestPossibleRegion().GetSize()) print(image_A.GetSpacing()) print(image_B.GetSpacing()) phi_AB, phi_BA = icon_registration.itk_wrapper.register_pair( model, image_A, image_B) assert (isinstance(phi_AB, itk.CompositeTransform)) interpolator = itk.LinearInterpolateImageFunction.New(image_A) warped_image_A = itk.resample_image_filter( image_A, transform=phi_AB, interpolator=interpolator, size=itk.size(image_B), output_spacing=itk.spacing(image_B), output_direction=image_B.GetDirection(), output_origin=image_B.GetOrigin()) plt.imshow( np.array(itk.checker_board_image_filter(warped_image_A, image_B))[40]) plt.colorbar() plt.savefig(footsteps.output_dir + "grid.png") plt.clf() plt.imshow(np.array(warped_image_A)[40]) plt.savefig(footsteps.output_dir + "warped.png") plt.clf() reference = np.load(icon_registration.test_utils.TEST_DATA_DIR / "warped.npy") np.save(footsteps.output_dir + "warped.npy", itk.array_from_image(warped_image_A)[40]) self.assertLess( np.mean( np.abs(reference - itk.array_from_image(warped_image_A)[40])), 1e-6)
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 SetInput(self, Input): """Set the current input image """ import itk img = itk.image( Input ) if img : # Update to try to avoid to exit if a c++ exception is throwed # sadely, it will not prevent the program to exit later... # a real fix would be to wrap c++ exception in vtk img.UpdateOutputInformation() img.Update() # release the previous filters self.clear() itk.pipeline.SetInput( self, img ) # flip the image to get the same representation than the vtk one self.connect( itk.FlipImageFilter[img].New() ) axes = self[0].GetFlipAxes() axes.SetElement(1, True) self[0].SetFlipAxes(axes) # change the spacing while still keeping the ratio to workaround vtk bug # when spacing is very small spacing_ = itk.spacing(img) normSpacing = [] for i in range(0, spacing_.Size()): normSpacing.append( spacing_.GetElement(i) / spacing_.GetElement(0) ) self.connect( itk.ChangeInformationImageFilter[img].New( OutputSpacing=normSpacing, ChangeSpacing=True ) ) # now really convert the data self.connect( itk.ImageToVTKImageFilter[img].New() ) self.widget.SetInput( self[-1].GetImporter() )
def test_paste_to_common_space(): # Import succeeds from hasi.align import mesh_to_image, paste_to_common_space # Paste succeeds resized_images = paste_to_common_space( [target_healthy_image, target_unhealthy_image]) assert (len(resized_images) == 2) # Verify common space TOLERANCE = 1e-6 assert (itk.size(resized_images[0]) == itk.size(resized_images[1])) assert (all([ itk.spacing(resized_images[0])[dim] - itk.spacing(resized_images[1])[dim] < TOLERANCE for dim in range(dimension) ]))
def compareImageHeaders(img1, img2, tolerance=0.00001): print("Comparing headers") sp1 = itk.GetArrayFromVnlVector(itk.spacing(img1).GetVnlVector()) sp2 = itk.GetArrayFromVnlVector(itk.spacing(img2).GetVnlVector()) spVar = np.sum(np.abs(sp2 - sp1)) if (spVar > tolerance): return (False) or1 = itk.GetArrayFromVnlVector(itk.origin(img1).GetVnlVector()) or2 = itk.GetArrayFromVnlVector(itk.origin(img2).GetVnlVector()) orVar = np.sum(np.abs(or2 - or1)) if (orVar > tolerance): return (False) return (True)
def downsample_images(images:list, ratio:float) -> list: assert(ratio > 1.0) downsampled_image_list = list() for image in images: new_spacing = [spacing * ratio for spacing in itk.spacing(image)] new_size = [int(size / ratio) for size in itk.size(image)] downsampled_image = itk.resample_image_filter(image, size=new_size, output_origin=itk.origin(image), output_spacing=new_spacing) downsampled_image_list.append(downsampled_image) return downsampled_image_list
def computeRegion(lo, img): img = itk.output(img) import math transform = lo.GetBinaryPrincipalAxesToPhysicalAxesTransform() invTransform = itk.AffineTransform.D3.New() transform.GetInverse( invTransform ) region = lo.GetRegion() outputSpacing = [min(itk.spacing(img))]*3 dummyImg = itk.Image.UC3.New() dummyImg.SetSpacing( outputSpacing ) idx = region.GetIndex() size = region.GetSize() minPoint = [4294967295L]*3 maxPoint = [-4294967295L]*3 for x in [idx[0], idx[0]+size[0]]: for y in [idx[1], idx[1]+size[1]]: for z in [idx[2], idx[2]+size[2]]: inputPoint = img.TransformIndexToPhysicalPoint( [x,y,z] ) outputPoint = invTransform.TransformPoint( inputPoint ) for i in range(0,3): if minPoint[i] > outputPoint[i]: minPoint[i] = outputPoint[i] if maxPoint[i] < outputPoint[i]: maxPoint[i] = outputPoint[i] minIdx = dummyImg.TransformPhysicalPointToIndex(minPoint) maxIdx = dummyImg.TransformPhysicalPointToIndex(maxPoint) outputIdx = [] outputSize = [] for i in range(0,3): outputIdx.append(int(minIdx[i])) outputSize.append( int(maxIdx[i] - minIdx[i]) ) uabc3 = 1.0 for v in itk.spacing(img): uabc3 *= v for v in lo.GetEquivalentEllipsoidSize(): uabc3 *= v uabc3 = math.pow(uabc3, 1/3.0) spacing2 = [uabc3 / v for v in lo.GetEquivalentEllipsoidSize()] return (outputIdx, outputSize, outputSpacing, spacing2)
def SetInput(self, input): import itk img = itk.image(input) self.__input__ = img if img: # Update to try to avoid to exit if a c++ exception is throwed # sadely, it will not prevent the program to exit later... # a real fix would be to wrap c++ exception in vtk img.UpdateOutputInformation() img.Update() # flip the image to get the same representation than the vtk one self.__flipper__ = itk.FlipImageFilter[img].New(Input=img) axes = self.__flipper__.GetFlipAxes() axes.SetElement(1, True) self.__flipper__.SetFlipAxes(axes) # change the spacing while still keeping the ratio to workaround vtk bug # when spacing is very small spacing_ = itk.spacing(img) normSpacing = [] for i in range(0, spacing_.Size()): normSpacing.append( spacing_.GetElement(i) / spacing_.GetElement(0)) self.__changeInfo__ = itk.ChangeInformationImageFilter[img].New( self.__flipper__, OutputSpacing=normSpacing, ChangeSpacing=True) # now really convert the data self.__itkvtkConverter__ = itk.ImageToVTKImageFilter[img].New( self.__changeInfo__) self.__volumeMapper__.SetInput( self.__itkvtkConverter__.GetOutput()) # needed to avoid warnings # self.__itkvtkConverter__.GetOutput() must be callable import vtk if not self.__outline__: self.__outline__ = vtk.vtkOutlineFilter() self.__outline__.SetInput(self.__itkvtkConverter__.GetOutput()) self.__outlineMapper__ = vtk.vtkPolyDataMapper() self.__outlineMapper__.SetInput(self.__outline__.GetOutput()) self.__outlineActor__ = vtk.vtkActor() self.__outlineActor__.SetMapper(self.__outlineMapper__) self.__ren__.AddActor(self.__outlineActor__) else: self.__outline__.SetInput(self.__itkvtkConverter__.GetOutput()) self.Render()
def SetInput(self, input) : import itk img = itk.output(input) self.__input__ = img if img : # Update to try to avoid to exit if a c++ exception is throwed # sadely, it will not prevent the program to exit later... # a real fix would be to wrap c++ exception in vtk img.UpdateOutputInformation() img.Update() # flip the image to get the same representation than the vtk one self.__flipper__ = itk.FlipImageFilter[img].New(Input=img) axes = self.__flipper__.GetFlipAxes() axes.SetElement(1, True) self.__flipper__.SetFlipAxes(axes) # change the spacing while still keeping the ratio to workaround vtk bug # when spacing is very small spacing_ = itk.spacing(img) normSpacing = [] for i in range(0, spacing_.Size()): normSpacing.append( spacing_.GetElement(i) / spacing_.GetElement(0) ) self.__changeInfo__ = itk.ChangeInformationImageFilter[img].New(self.__flipper__, OutputSpacing=normSpacing, ChangeSpacing=True) # now really convert the data self.__itkvtkConverter__ = itk.ImageToVTKImageFilter[img].New(self.__changeInfo__) self.__volumeMapper__.SetInput(self.__itkvtkConverter__.GetOutput()) # needed to avoid warnings # self.__itkvtkConverter__.GetOutput() must be callable import vtk if not self.__outline__ : self.__outline__ = vtk.vtkOutlineFilter() self.__outline__.SetInput(self.__itkvtkConverter__.GetOutput()) self.__outlineMapper__ = vtk.vtkPolyDataMapper() self.__outlineMapper__.SetInput(self.__outline__.GetOutput()) self.__outlineActor__ = vtk.vtkActor() self.__outlineActor__.SetMapper(self.__outlineMapper__) self.__ren__.AddActor(self.__outlineActor__) else : self.__outline__.SetInput(self.__itkvtkConverter__.GetOutput()) self.Render()
def xarray_from_image(l_image): """Convert an itk.Image to an xarray.DataArray. Origin and spacing metadata is preserved in the xarray's coords. The Direction is set in the `direction` attribute. Dims are labeled as `x`, `y`, `z`, and `c`. This interface is and behavior is experimental and is subject to possible future changes.""" import xarray as xr import itk import numpy as np array_view = itk.array_view_from_image(l_image) l_spacing = itk.spacing(l_image) l_origin = itk.origin(l_image) l_size = itk.size(l_image) direction = np.flip(itk.array_from_matrix(l_image.GetDirection())) spatial_dimension = l_image.GetImageDimension() spatial_dims = ("x", "y", "z") coords = {} for l_index, dim in enumerate(spatial_dims[:spatial_dimension]): coords[dim] = np.linspace( l_origin[l_index], l_origin[l_index] + (l_size[l_index] - 1) * l_spacing[l_index], l_size[l_index], dtype=np.float64, ) dims = list(reversed(spatial_dims[:spatial_dimension])) components = l_image.GetNumberOfComponentsPerPixel() if components > 1: dims.append("c") coords["c"] = np.arange(components, dtype=np.uint64) data_array = xr.DataArray(array_view, dims=dims, coords=coords, attrs={"direction": direction}) return data_array
def conv_3Dto2D(img_3D_filename, label_3D_filename, outputimages_foldername_x, outputimages_foldername_y, outputimages_foldername_z, outputlabels_foldername_x, outputlabels_foldername_y, outputlabels_foldername_z, image_identifier_x, image_identifier_y, image_identifier_z, patient_names_x, patient_names_y, patient_names_z, casenumber_x, casenumber_y, casenumber_z, slice_info_filename_x, slice_info_filename_y, slice_info_filename_z, localtaskfolder_x, localtaskfolder_y, localtaskfolder_z, patient_folder): if outputlabels_foldername_x == '': test_dataset = True images2D_foldername_x = f'{localtaskfolder_x}/2D_testimages_x/' labels2D_foldername_x = f'{localtaskfolder_x}/2D_testlabels_x' labels_nifti_foldername_x = f'{localtaskfolder_x}/2D_testlabels_nii_x' images2D_foldername_y = f'{localtaskfolder_y}/2D_testimages_y/' labels2D_foldername_y = f'{localtaskfolder_y}/2D_testlabels_y' labels_nifti_foldername_y = f'{localtaskfolder_y}/2D_testlabels_nii_y' images2D_foldername_z = f'{localtaskfolder_z}/2D_testimages_z/' labels2D_foldername_z = f'{localtaskfolder_z}/2D_testlabels_z' labels_nifti_foldername_z = f'{localtaskfolder_z}/2D_testlabels_nii_z' outputlabels_foldername_x = labels_nifti_foldername_x outputlabels_foldername_y = labels_nifti_foldername_y outputlabels_foldername_z = labels_nifti_foldername_z else: test_dataset = False images2D_foldername_x = f'{localtaskfolder_x}/2D_trainingimages_x/' labels2D_foldername_x = f'{localtaskfolder_x}/2D_traininglabels_x' labels_nifti_foldername_x = f'{localtaskfolder_x}/2D_traininglabels_nii_x' images2D_foldername_y = f'{localtaskfolder_y}/2D_trainingimages_y/' labels2D_foldername_y = f'{localtaskfolder_y}/2D_traininglabels_y' labels_nifti_foldername_y = f'{localtaskfolder_y}/2D_traininglabels_nii_y' images2D_foldername_z = f'{localtaskfolder_z}/2D_trainingimages_z/' labels2D_foldername_z = f'{localtaskfolder_z}/2D_traininglabels_z' labels_nifti_foldername_z = f'{localtaskfolder_z}/2D_traininglabels_nii_z' maybe_mkdir_p(images2D_foldername_x) maybe_mkdir_p(labels2D_foldername_x) maybe_mkdir_p(labels_nifti_foldername_x) maybe_mkdir_p(images2D_foldername_y) maybe_mkdir_p(labels2D_foldername_y) maybe_mkdir_p(labels_nifti_foldername_y) maybe_mkdir_p(images2D_foldername_z) maybe_mkdir_p(labels2D_foldername_z) maybe_mkdir_p(labels_nifti_foldername_z) img = itk.imread(img_3D_filename) img_spacing = itk.spacing(img) img_origin = itk.origin(img) img_array = itk.GetArrayFromImage(img) if label_3D_filename != '': labelimg = itk.imread(label_3D_filename) label_spacing = itk.spacing(labelimg) label_origin = itk.origin(labelimg) label_array = itk.GetArrayFromImage(labelimg) # x direction # save for each patient the 3d_imagename, the image_identifier, the first slice, last slice, origin, and spacing of the 3d image num_slices = itk.size(img)[0] with open(slice_info_filename_x, "a") as f: f.write( f"{os.path.basename(img_3D_filename)}\t{image_identifier_x}\t{casenumber_x}\t{casenumber_x+num_slices-1}\t{np.array(img_origin)}\t{np.array(img_spacing)}\t{patient_folder}\n" ) for i in range(num_slices): casename = f'{image_identifier_x}_{casenumber_x:04d}' img_2D = itk.GetImageFromArray(img_array[:, :, i]) img_2D.SetSpacing([img_spacing[1], img_spacing[2]]) img_2D.SetOrigin([img_origin[1], img_origin[2]]) # save the 2d image in the 2D folder image2D_filename = f'{images2D_foldername_x}/{casename}.mha' #image2D_filename= (img_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha') itk.imwrite(img_2D, image2D_filename) label_array2D = label_array[:, :, i] label_2D = itk.GetImageFromArray(label_array2D) label_2D.SetSpacing([label_spacing[1], label_spacing[2]]) label_2D.SetOrigin([label_origin[1], label_origin[2]]) #itk.imwrite(label_2D,outputlabel_filename) #print(label_array2D) # save the 2d label in the 2D folder label2D_filename = f'{labels2D_foldername_x}/{casename}.mha' #(label_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha') itk.imwrite(label_2D, label2D_filename) # if the label is empty, don't include the image in the training dataset if np.any(img_2D) & ((test_dataset == True) | np.any(label_array2D)): patient_names_x.append(casename) # save the 2d image as a 3D nifti in the nnunet folder outputimage_filename = f'{outputimages_foldername_x}/{casename}' convert_2d_image_to_nifti(image2D_filename, outputimage_filename, is_seg=False) # save the 2d label as a 3D nifti in the nnunet folder outputlabel_filename = f'{outputlabels_foldername_x}/{casename}' convert_2d_image_to_nifti(label2D_filename, outputlabel_filename, is_seg=True) casenumber_x = casenumber_x + 1 # y direction num_slices = itk.size(img)[1] with open(slice_info_filename_y, "a") as f: f.write( f"{os.path.basename(img_3D_filename)}\t{image_identifier_y}\t{casenumber_y}\t{casenumber_y+num_slices-1}\t{np.array(img_origin)}\t{np.array(img_spacing)}\t{patient_folder}\n" ) for i in range(num_slices): casename = f'{image_identifier_y}_{casenumber_y:04d}' #outputimage_filename= f'{outputimages_foldername}/{casename}_0000.nii.gz' #outputlabel_filename= f'{outputlabels_foldername}/{casename}.nii.gz' img_2D = itk.GetImageFromArray(img_array[:, i, :]) img_2D.SetSpacing([img_spacing[0], img_spacing[2]]) img_2D.SetOrigin([img_origin[0], img_origin[2]]) # save the 2d image in the 2D folder image2D_filename = f'{images2D_foldername_y}/{casename}.mha' #image2D_filename= (img_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha') itk.imwrite(img_2D, image2D_filename) label_array2D = label_array[:, i, :] label_2D = itk.GetImageFromArray(label_array2D) label_2D.SetSpacing([label_spacing[0], label_spacing[2]]) label_2D.SetOrigin([label_origin[0], label_origin[2]]) #itk.imwrite(label_2D,outputlabel_filename) # save the 2d label in the 2D folder label2D_filename = f'{labels2D_foldername_y}/{casename}.mha' #label2D_filename= (label_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha') itk.imwrite(label_2D, label2D_filename) # if the label is empty, don't include the image in the training dataset if np.any(img_2D) & ((test_dataset == True) | np.any(label_array2D)): patient_names_y.append(casename) # save the 2d image as a 3D nifti in the nnunet folder outputimage_filename = f'{outputimages_foldername_y}/{casename}' convert_2d_image_to_nifti(image2D_filename, outputimage_filename, is_seg=False) # save the 2d label as a 3D nifti in the nnunet folder outputlabel_filename = f'{outputlabels_foldername_y}/{casename}' convert_2d_image_to_nifti(label2D_filename, outputlabel_filename, is_seg=True) casenumber_y = casenumber_y + 1 # z direction num_slices = itk.size(img)[2] with open(slice_info_filename_z, "a") as f: f.write( f"{os.path.basename(img_3D_filename)}\t{image_identifier_z}\t{casenumber_z}\t{casenumber_z+num_slices-1}\t{np.array(img_origin)}\t{np.array(img_spacing)}\t{patient_folder}\n" ) for i in range(num_slices): casename = f'{image_identifier_z}_{casenumber_z:04d}' #outputimage_filename= f'{outputimages_foldername}/{casename}_0000.nii.gz' #outputlabel_filename= f'{outputlabels_foldername}/{casename}.nii.gz' img_2D = itk.GetImageFromArray(img_array[i, :, :]) img_2D.SetSpacing([img_spacing[0], img_spacing[1]]) img_2D.SetOrigin([img_origin[0], img_origin[1]]) # save the 2d image in the 2D folder image2D_filename = f'{images2D_foldername_z}/{casename}.mha' #image2D_filename= (img_3D_filename.replace('3D','2D')).replace('.',f'_{i:04d}.') itk.imwrite(img_2D, image2D_filename) label_array2D = label_array[i, :, :] label_2D = itk.GetImageFromArray(label_array2D) label_2D.SetSpacing([label_spacing[0], label_spacing[1]]) label_2D.SetOrigin([label_origin[0], label_origin[1]]) #itk.imwrite(label_2D,outputlabel_filename) # save the 2d label in the 2D folder label2D_filename = f'{labels2D_foldername_z}/{casename}.mha' #label2D_filename= (label_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha') itk.imwrite(label_2D, label2D_filename) # if the image or the label is empty, don't include the image in the training dataset if np.any(img_2D) & ((test_dataset == True) | np.any(label_array2D)): patient_names_z.append(casename) # save the 2d image as a 3D nifti in the nnunet folder outputimage_filename = f'{outputimages_foldername_z}/{casename}' convert_2d_image_to_nifti(image2D_filename, outputimage_filename, is_seg=False) # save the 2d label as a 3D nifti in the nnunet folder outputlabel_filename = f'{outputlabels_foldername_z}/{casename}' convert_2d_image_to_nifti(label2D_filename, outputlabel_filename, is_seg=True) casenumber_z = casenumber_z + 1 return casenumber_x, casenumber_y, casenumber_z, patient_names_x, patient_names_y, patient_names_z
assert itk.image(1) == 1 # test size s = itk.size(reader) assert s[0] == s[1] == 256 s = itk.size(reader.GetOutput()) assert s[0] == s[1] == 256 # test physical size s = itk.physical_size(reader) assert s[0] == s[1] == 256.0 s = itk.physical_size(reader.GetOutput()) assert s[0] == s[1] == 256.0 # test spacing s = itk.spacing(reader) assert s[0] == s[1] == 1.0 s = itk.spacing(reader.GetOutput()) assert s[0] == s[1] == 1.0 # test origin s = itk.origin(reader) assert s[0] == s[1] == 0.0 s = itk.origin(reader.GetOutput()) assert s[0] == s[1] == 0.0 # test index s = itk.index(reader) assert s[0] == s[1] == 0 s = itk.index(reader.GetOutput()) assert s[0] == s[1] == 0
PIXHEIGHT %(pixelHeight)s; RELPOSITION %(sliceSpacing)s; """ # and a line per slice sliceDescriptorTpl = "SLICE %(sliceName)s %(fileName)s;\n" # lets convert all the files for f in sys.argv[2:] : # display the file name, to know on what we are working log( f ) # change the file name reader.SetFileName( f ) numberOfSlices = itk.size( reader )[2] spacing = itk.spacing( reader ) lsmName = f[:-4] descriptorDir = "%s/%s/sdf" % ( destDir, lsmName ) mkdir( descriptorDir ) # set the number of slices for the name generator names.SetEndIndex( numberOfSlices - 1 ) # now iterate over all the channel for c in range( 0, reader.GetNumberOfChannels() ) : channelName = reader.SetChannel( c ) # again, print the channel name to know what is done currently log( channelName )
resampleNucleus(Transform=transform, OutputStartIndex=idx, Size=size, OutputSpacing=spacing) resampleCentromeres(Transform=transform, OutputStartIndex=idx, Size=size, OutputSpacing=spacing) resampleCentromeresInt(Transform=transform, OutputStartIndex=idx, Size=size, OutputSpacing=spacing) unflattenNucleus(OutputSpacing=spacing2) unflattenCentromeres(OutputSpacing=spacing2) unflattenCentromeresInt(OutputSpacing=spacing2) nucleus = nucleusLM()[0].GetLabelObject(flatNucleus.GetLabel()) maskedCentromeres.SetLabel(nucleus.GetLabel()) nucleusSize = nucleus.GetSize() npos = nucleus.GetCentroid() # une simulation pour une analyse globale dans R simCentromeresLM.SetRegions(itk.region(nucleusReader)) simCentromeresLM.SetSpacing(itk.spacing(nucleusReader)) simCentromeresLM.ClearLabels() for i in range(centromeresLM()[0].GetNumberOfLabelObjects()): idx = nucleus.GetIndex(random.randint(0, nucleusSize-1)) simCentromeresLM.SetPixel(idx, 1) simCentromeresLM.GetLabelObject(1).Optimize() cpos = shapeAggrCentromeresLM()[0].GetNthLabelObject(0).GetCentroid() cdist = (npos - cpos).GetNorm() spos = shapeSimCentromeresLM()[0].GetNthLabelObject(0).GetCentroid() sdist = (npos - spos).GetNorm() # realisation dun test par noyau avec plusieurs simulations simCentromeresLM2.SetRegions(itk.region(nucleusReader))
medianCENP, Sigma=0.05) sizeCENP = itk.PhysicalSizeOpeningImageFilter.IUC3IUC3.New( gaussianCENP, Lambda=0.36) subCENP = itk.SubtractImageFilter.IUC3IUC3IUC3.New(gaussianCENP, sizeCENP) size2CENP = itk.PhysicalSizeOpeningImageFilter.IUC3IUC3.New( subCENP, Lambda=0.02) maskCENP = itk.LabelMapMaskImageFilter.LM3IUC3.New( lmNuclei, size2CENP, Label=0) thCENP = itk.BinaryThresholdImageFilter.IUC3IUC3.New( maskCENP, LowerThreshold=35) statsCENP = itk.BinaryImageToStatisticsLabelMapFilter.IUC3IUC3LM3.New( thCENP, subCENP) # create a new image to store the CENP centers, so they can be easily reused to check the distribution cenpSpotsImg = itk.Image.UC3.New( Regions=itk.size(readerNuclei), Spacing=itk.spacing(readerNuclei)) cenpSpotsImg.Allocate() cenpSpotsImg.FillBuffer(0) if opts.visualValidation: # create a new image to store the CENP segmentation cenpImg = itk.LabelMap._3.New( Regions=itk.size(readerNuclei), Spacing=itk.spacing(readerNuclei)) fullCENP = itk.LabelMapToBinaryImageFilter.LM3IUC3.New(cenpImg) dilateCENP = itk.BinaryDilateImageFilter.IUC3IUC3SE3.New( fullCENP, Kernel=itk.strel(3, [10, 10, 3])) borderCENP = itk.BinaryBorderImageFilter.IUC3IUC3.New(dilateCENP) outsideMask = itk.BinaryThresholdImageFilter.IUC3IUC3.New( lm2iNuclei, UpperThreshold=0) relabelCENP = itk.NaryRelabelImageFilter.IUC3IUC3.New( outsideMask, borderCENP)
filename = imgDir+'gml16_dapi_'+nb+'_nuclei.nrrd' print 'Image filename',filename reader.SetFileName(filename) labmap.UpdateLargestPossibleRegion() lmo = labmap.GetOutput() n = lmo.GetNumberOfLabelObjects() print '\t',n,'nuclei' for i in range(n): row = [nb,i+1] nucleus = lmo.GetNthLabelObject(i) centroid = nucleus.GetCentroid() for j in range(3): row.append(centroid[j]) volume = nucleus.GetPhysicalSize() row.append(volume) diameter = 2*math.pow(3*volume/(4*math.pi),1./3) row.append(diameter) surface = nucleus.GetPerimeter() row.append(surface) shape = surface/math.pow(volume,2./3) row.append(shape) elongation = nucleus.GetBinaryElongation() row.append(elongation) row.append(nucleus.GetRegion().GetSize()[2]*itk.spacing(reader)[2]) axes = nucleus.GetBinaryPrincipalAxes().GetVnlMatrix() for j in range(3): row.append(axes.get(0,j)) dataWriter.writerow(row) dataFile.close()
obo3() dilate2 = itk.BinaryDilateImageFilter.IUC3IUC3SE3.New(Kernel=itk.strel(3,[3,3,1]), auto_progress=False) dilate3 = itk.BinaryDilateImageFilter.IUC3IUC3SE3.New(dilate2, Kernel=itk.FlatStructuringElement._3.Cross(1), auto_progress=False) border2 = itk.SubtractImageFilter.IUC3IUC3IUC3.New(dilate3, dilate2, auto_progress=False) obo2 = itk.ObjectByObjectLabelMapFilter.LM3.New(bi2lm, InputFilter=dilate2, OutputFilter=border2, PadSize=6) crop = itk.AutoCropLabelMapFilter.LM3.New(result, CropBorder=[30,30,10]) window = itk.IntensityWindowingImageFilter.IUS3IUS3.New(cenp, OutputMinimum=0, OutputMaximum=255) rescale = itk.CastImageFilter.IUS3IUC3.New(window) # extract = itk.ExtractImageFilter.IUS3IUS3.New(cenp) # rescale = itk.RescaleIntensityImageFilter.IUS3IUC3.New(extract) overlay = itk.LabelMapOverlayImageFilter.LM3IUC3IRGBUC3.New(crop, rescale, NumberOfThreads=1)#, Opacity=0.2) # segmentation result2 = itk.Image.UC3.New(Regions=itk.region(cenp), Spacing=itk.spacing(cenp)) result2.Allocate() result2.FillBuffer(0) for nucleus in lmNuclei[0]: l = nucleus.GetLabel() # select the right nucleus mask.SetLabel(l) # and set the threshold for the cenp spots rmaxRelabel() # oldValue = itk.range(mask)[1]/5 v = int( rmaxRelabel[0].GetLabelObject(22).GetMaximum()/2 ) values = [rmaxRelabel[0].GetLabelObject(i+1).GetMaximum() for i in range(11)] # vmean = mean(values) / 4 # vmedian = median(values) / 4 th.SetLowerThreshold( int(vmedian) )
proj1D = itk.MaximumProjectionImageFilter.IUS2IUS2.New(proj2D, ProjectionDimension=0) # binarize the image th = itk.BinaryThresholdImageFilter.IUS2IUS2.New(proj1D, InsideValue=1) # and count the pixels to get the resolution on the z axis labelShape = itk.LabelShapeImageFilter.IUS2.New(th) # count the object to display a warning label = itk.ConnectedComponentImageFilter.IUS2IUS2.New(th) relabel = itk.RelabelComponentImageFilter.IUS2IUS2.New(label) for f in sys.argv[1:]: reader.SetFileName(f) projz.UpdateLargestPossibleRegion() m, M = itk.range(projz) watershed.SetLevel(m + (M - m) / 2) upperdim.SetNewDimensionSapcing(itk.spacing(reader)[2]) upperdim.SetNewDimensionSize(itk.size(reader)[2]) upperdim.UpdateLargestPossibleRegion() # to get a valid number of labels # store the results so we can compute the mean and the meadian for # all the beads in the image results = [] for l in range(1, wrelabel.GetNumberOfObjects() + 1): selectedLabel.SetUpperThreshold(l) selectedLabel.SetLowerThreshold(l) proj1D.UpdateLargestPossibleRegion() m, M = itk.range(proj1D) th.SetLowerThreshold((M - m) / 2) labelShape.UpdateLargestPossibleRegion()
print( f"Usage: {sys.argv[0]} input_image_file spacing_fraction sigma_fraction output_image_file_label_image_interpolator output_image_file_nearest_neighbor_interpolator" ) sys.exit(1) input_image_file = sys.argv[1] spacing_fraction = float(sys.argv[2]) sigma_fraction = float(sys.argv[3]) output_image_file_label_image_interpolator = sys.argv[4] output_image_file_nearest_neighbor_interpolator = sys.argv[5] input_image = itk.imread(input_image_file) resize_filter = itk.ResampleImageFilter.New(input_image) input_spacing = itk.spacing(input_image) output_spacing = [s * spacing_fraction for s in input_spacing] resize_filter.SetOutputSpacing(output_spacing) input_size = itk.size(input_image) output_size = [ int(s * input_spacing[dim] / spacing_fraction) for dim, s in enumerate(input_size) ] resize_filter.SetSize(output_size) gaussian_interpolator = itk.LabelImageGaussianInterpolateImageFunction.New(input_image) sigma = [s * sigma_fraction for s in output_spacing] gaussian_interpolator.SetSigma(sigma) gaussian_interpolator.SetAlpha(3.0) resize_filter.SetInterpolator(gaussian_interpolator)
# let start, really statisticsLabelMapRobustNuclei.Update() shapeLabelMapNuclei.Update() otsuNuclei.Compute() if opts.visualValidation: padLabels.SetRegion( readerNuclei.GetOutput().GetLargestPossibleRegion() ) if opts.saveSegmentation: itk.write( labelRobustNuclei, readerNuclei.GetFileName()+"-nuclei-segmentation.nrrd", True) # to be reused later spacing = itk.spacing(readerNuclei) # find the labels used - we are not sure to have all the labels in the range because of the attribute openongs ls = [l+1 for l in range(*itk.range(labelRobustNuclei)) if statisticsLabelMapRobustNuclei.GetOutput().HasLabel(l+1)] for l in ls : if opts.verbose: print >> sys.stderr, " nuclei", l # set the label singleMaskNuclei.SetUpperThreshold( l ) singleMaskNuclei.SetLowerThreshold( l ) cropSingleMaskNuclei.SetLabel( l ) cropSingleMaskRobustNuclei.SetLabel( l ) cropSingleMaskNuclei.UpdateLargestPossibleRegion()
if opts.visualValidation: overlayNuclei = itk.LabelOverlayImageFilter.IUC3IUC3IRGBUC3.New(readerNuclei, lm2iNuclei) readerCENP = itk.lsm(channel=1, fileName=inputImageName) medianCENP = itk.MedianImageFilter.IUC3IUC3.New(readerCENP) gaussianCENP = itk.SmoothingRecursiveGaussianImageFilter.IUC3IUC3.New(medianCENP, Sigma=0.05) sizeCENP = itk.PhysicalSizeOpeningImageFilter.IUC3IUC3.New(gaussianCENP, Lambda=0.36) subCENP = itk.SubtractImageFilter.IUC3IUC3IUC3.New(gaussianCENP, sizeCENP) size2CENP = itk.PhysicalSizeOpeningImageFilter.IUC3IUC3.New(subCENP, Lambda=0.02) maskCENP = itk.LabelMapMaskImageFilter.LM3IUC3.New(lmNuclei, size2CENP, Label=0) thCENP = itk.BinaryThresholdImageFilter.IUC3IUC3.New(maskCENP, LowerThreshold=35) statsCENP = itk.BinaryImageToStatisticsLabelMapFilter.IUC3IUC3LM3.New(thCENP, subCENP) # create a new image to store the CENP centers, so they can be easily reused to check the distribution cenpSpotsImg = itk.Image.UC3.New(Regions=itk.size(readerNuclei), Spacing=itk.spacing(readerNuclei)) cenpSpotsImg.Allocate() cenpSpotsImg.FillBuffer(0) if opts.visualValidation: # create a new image to store the CENP segmentation cenpImg = itk.LabelMap._3.New(Regions=itk.size(readerNuclei), Spacing=itk.spacing(readerNuclei)) fullCENP = itk.LabelMapToBinaryImageFilter.LM3IUC3.New(cenpImg) dilateCENP = itk.BinaryDilateImageFilter.IUC3IUC3SE3.New(fullCENP, Kernel=itk.strel(3, [10, 10, 3])) borderCENP = itk.BinaryBorderImageFilter.IUC3IUC3.New(dilateCENP) outsideMask = itk.BinaryThresholdImageFilter.IUC3IUC3.New(lm2iNuclei, UpperThreshold=0) relabelCENP = itk.NaryRelabelImageFilter.IUC3IUC3.New(outsideMask, borderCENP) overlayCENP = itk.LabelOverlayImageFilter.IUC3IUC3IRGBUC3.New(readerCENP, relabelCENP) if 'blasto' in inputImageName: