def _run(self): dimension = self._fixed.sitk.GetDimension() if self._use_fixed_mask: fixed_itk_mask = self._fixed.itk_mask else: fixed_itk_mask = None if self._use_moving_mask: moving_itk_mask = self._moving.itk_mask else: moving_itk_mask = None # Blur moving image with oriented Gaussian prior to the registration if self._use_oriented_psf: image_type = itk.Image[self._pixel_type, dimension] # Get oriented Gaussian covariance matrix cov_HR_coord = psf.PSF( ).get_covariance_matrix_in_reconstruction_space( self._fixed, self._moving) itk_gaussian_interpolator = itk.OrientedGaussianInterpolateImageFunction[ image_type, self._pixel_type].New() itk_gaussian_interpolator.SetCovariance(cov_HR_coord.flatten()) itk_gaussian_interpolator.SetAlpha(self._alpha_cut) else: itk_gaussian_interpolator = None self._registration_method = \ simplereg.wrap_itk_registration.WrapItkRegistration( dimension=dimension, fixed_itk=self._fixed.itk, moving_itk=self._moving.itk, fixed_itk_mask=fixed_itk_mask, moving_itk_mask=moving_itk_mask, registration_type=self._registration_type, interpolator=self._interpolator, metric=self._metric, # metric_params=self._metric_params, optimizer=self._optimizer, optimizer_params=self._optimizer_params, initializer_type=self._initializer_type, use_multiresolution_framework=self._use_multiresolution_framework, # optimizer_scales=self._scales_estimator, shrink_factors=self._shrink_factors, smoothing_sigmas=self._smoothing_sigmas, verbose=self._use_verbose, itk_oriented_gaussian_interpolate_image_filter=itk_gaussian_interpolator, ) self._registration_method.run() self._registration_transform_sitk = \ self._registration_method.get_registration_transform_sitk()
def __init__(self, deconvolution_mode="full_3D", predefined_covariance=None, alpha_cut=3, image_type=itk.Image.D3, default_pixel_type=0.0, ): self._deconvolution_mode = deconvolution_mode # In case only diagonal entries are given, create diagonal matrix if predefined_covariance is not None: if predefined_covariance.size is 3: self._predefined_covariance = np.diag( np.array(predefined_covariance)) else: self._predefined_covariance = np.array(predefined_covariance) self._psf = psf.PSF() # Allocate and initialize Oriented Gaussian Interpolate Image Filter self._filter_oriented_gaussian = \ itk.OrientedGaussianInterpolateImageFilter[ image_type, image_type].New() self._filter_oriented_gaussian.SetDefaultPixelValue(default_pixel_type) self._filter_oriented_gaussian.SetAlpha(alpha_cut) # Allocate and initialize Adjoint Oriented Gaussian Interpolate Image # Filter self._filter_adjoint_oriented_gaussian = \ itk.AdjointOrientedGaussianInterpolateImageFilter[ image_type, image_type].New() self._filter_adjoint_oriented_gaussian.SetDefaultPixelValue( default_pixel_type) self._filter_adjoint_oriented_gaussian.SetAlpha(alpha_cut) # Allocate and initialize masking image filter self._masking = itk.MultiplyImageFilter[ image_type, image_type, image_type].New() self._get_covariance = { "full_3D": self._get_covariance_full_3d, "only_in_plane": self._get_covariance_only_in_plane, "predefined_covariance": self._get_covariance_predefined, }
def _get_interpolator(self, stack_slice): if self._interpolator == "OrientedGaussian": # Get oriented PSF covariance matrix cov = psf.PSF().get_covariance_matrix_in_reconstruction_space( stack_slice, self._reference) # Specify oriented Gaussian interpolator interpolator_itk = itk.OrientedGaussianInterpolateImageFunction[ self._image_type, self._pixel_type].New() interpolator_itk.SetCovariance(cov.flatten()) interpolator_itk.SetAlpha(self._alpha_cut) else: interpolator_itk = eval( "itk.%sInterpolateImageFunction" "[self._image_type, self._pixel_type].New()" % self._interpolator) return interpolator_itk
def _run_registration_inplane_similarity_3D(self, id, endl=" \\\n"): if self._fixed is None or self._moving is None: raise ValueError("Error: Fixed and moving image not specified") if self._use_verbose: verbose = "1" else: verbose = "0" # Clean output directory first os.system("rm -rf " + self._dir_tmp + "*") moving_str = "RegistrationITK_moving_" + id + self._moving.get_filename( ) fixed_str = "RegistrationITK_fixed_" + id + self._fixed.get_filename() moving_mask_str = "RegistrationITK_moving_mask_" + id + self._moving.get_filename( ) fixed_mask_str = "RegistrationITK_fixed_mask_" + id + self._fixed.get_filename( ) registration_transform_str = "RegistrationITK_transform_" + id + \ self._fixed.get_filename() + "_" + self._moving.get_filename() # Write images to HDD # if not os.path.isfile(self._dir_tmp + moving_str + ".nii.gz"): sitkh.write_nifti_image_sitk(self._moving.sitk, self._dir_tmp + moving_str + ".nii.gz") # if not os.path.isfile(self._dir_tmp + fixed_str + ".nii.gz"): sitkh.write_nifti_image_sitk(self._fixed.sitk, self._dir_tmp + fixed_str + ".nii.gz") # if not os.path.isfile(self._dir_tmp + moving_mask_str + ".nii.gz") # and self._use_moving_mask: sitkh.write_nifti_image_sitk( self._moving.sitk_mask, self._dir_tmp + moving_mask_str + ".nii.gz") # if not os.path.isfile(self._dir_tmp + fixed_mask_str + ".nii.gz") and # self._use_fixed_mask: sitkh.write_nifti_image_sitk( self._fixed.sitk_mask, self._dir_tmp + fixed_mask_str + ".nii.gz") # Prepare command for execution cmd = DIR_CPP_BUILD + "/bin/itkInplaneSimilarity3DReg" + endl cmd += "--f " + self._dir_tmp + fixed_str + ".nii.gz" + endl cmd += "--m " + self._dir_tmp + moving_str + ".nii.gz" + endl if self._use_fixed_mask: cmd += "--fmask " + self._dir_tmp + fixed_mask_str + ".nii.gz" + endl if self._use_moving_mask: cmd += "--mmask " + self._dir_tmp + moving_mask_str + ".nii.gz" + endl cmd += "--tout " + self._dir_tmp + registration_transform_str + ".txt" + endl cmd += "--useAffine " + \ str(int(self._registration_type is "Affine")) + endl cmd += "--useMultires " + \ str(int(self._use_multiresolution_framework)) + endl cmd += "--metric " + self._metric + endl cmd += "--scalesEst " + self._scales_estimator + endl cmd += "--interpolator " + self._interpolator + endl cmd += "--ANTSrad " + str(self._ANTSradius) + endl # cmd += "--translationScale " + str(self._translation_scale) + endl cmd += "--verbose " + verbose + endl # Compute oriented Gaussian PSF if desired if self._interpolator in ["OrientedGaussian"]: if self._cov is None: # Get oriented Gaussian covariance matrix cov_HR_coord = psf.PSF().\ get_covariance_matrix_in_reconstruction_space( self._moving, self._fixed).flatten() else: cov_HR_coord = self._cov.flatten() cmd += "--cov " + "'" + ' '.join(cov_HR_coord.astype("|S12")) + "'" # if self._use_verbose: ph.execute_command(cmd) # Read transformation file params_all = np.loadtxt(self._dir_tmp + registration_transform_str + ".txt") ## (center_x, center_y, center_z, direction_fixed_image_flattened_0, ..., direction_fixed_image_flattened_8) self._parameters_fixed = params_all[0:-7] ## (versor_0, versor_1, versor_2, translation_x, translation_y, translation_z, scale) self._parameters = params_all[-7:] # Get affine registration transform T(x) = R D Lambda D^{-1} (x-c) + t # + c self._registration_transform_sitk = self._get_affine_transform_from_similarity_registration( )
def _run_registration_rigid_affine(self, id, endl=" \\\n"): if self._fixed is None or self._moving is None: raise ValueError("Error: Fixed and moving image not specified") if self._use_verbose: verbose = "1" else: verbose = "0" moving_str = "RegistrationITK_moving_" + id + self._moving.get_filename( ) fixed_str = "RegistrationITK_fixed_" + id + self._fixed.get_filename() moving_mask_str = "RegistrationITK_moving_mask_" + id + self._moving.get_filename( ) fixed_mask_str = "RegistrationITK_fixed_mask_" + id + self._fixed.get_filename( ) registration_transform_str = "RegistrationITK_transform_" + id + \ self._fixed.get_filename() + "_" + self._moving.get_filename() # Write images to HDD # if not os.path.isfile(self._dir_tmp + moving_str + ".nii.gz"): sitkh.write_nifti_image_sitk(self._moving.sitk, self._dir_tmp + moving_str + ".nii.gz") # if not os.path.isfile(self._dir_tmp + fixed_str + ".nii.gz"): sitkh.write_nifti_image_sitk(self._fixed.sitk, self._dir_tmp + fixed_str + ".nii.gz") # if not os.path.isfile(self._dir_tmp + moving_mask_str + ".nii.gz") # and self._use_moving_mask: sitkh.write_nifti_image_sitk( self._moving.sitk_mask, self._dir_tmp + moving_mask_str + ".nii.gz") # if not os.path.isfile(self._dir_tmp + fixed_mask_str + ".nii.gz") and # self._use_fixed_mask: sitkh.write_nifti_image_sitk( self._fixed.sitk_mask, self._dir_tmp + fixed_mask_str + ".nii.gz") # Prepare command for execution # cmd = "/Users/mebner/UCL/UCL/Software/Volumetric\ Reconstruction/build/cpp/bin/itkReg " cmd = DIR_CPP_BUILD + "/bin/itkReg" + endl cmd += "--f " + self._dir_tmp + fixed_str + ".nii.gz" + endl cmd += "--m " + self._dir_tmp + moving_str + ".nii.gz" + endl if self._use_fixed_mask: cmd += "--fmask " + self._dir_tmp + fixed_mask_str + ".nii.gz" + endl if self._use_moving_mask: cmd += "--mmask " + self._dir_tmp + moving_mask_str + ".nii.gz" + endl cmd += "--tout " + self._dir_tmp + registration_transform_str + ".txt" + endl cmd += "--useAffine " + \ str(int(self._registration_type is "Affine")) + endl cmd += "--useMultires " + \ str(int(self._use_multiresolution_framework)) + endl cmd += "--metric " + self._metric + endl cmd += "--scalesEst " + self._scales_estimator + endl cmd += "--interpolator " + self._interpolator + endl cmd += "--ANTSrad " + str(self._ANTSradius) + endl cmd += "--verbose " + verbose + endl # Compute oriented Gaussian PSF if desired if self._interpolator in ["OrientedGaussian"]: if self._cov is None: # Get oriented Gaussian covariance matrix cov_HR_coord = psf.PSF().\ get_covariance_matrix_in_reconstruction_space( self._moving, self._fixed).flatten() else: cov_HR_coord = self._cov.flatten() cmd += "--cov " + "'" + ' '.join(cov_HR_coord.astype("|S12")) + "'" ph.execute_command(cmd, verbose=0) # Read transformation file params_all = np.loadtxt(self._dir_tmp + registration_transform_str + ".txt") if self._registration_type in ["Rigid"]: self._parameters_fixed = params_all[0:4] self._parameters = params_all[4:] self._registration_transform_sitk = sitk.Euler3DTransform() else: self._parameters_fixed = params_all[0:3] self._parameters = params_all[3:] self._registration_transform_sitk = sitk.AffineTransform(3) self._registration_transform_sitk.SetParameters(self._parameters) self._registration_transform_sitk.SetFixedParameters( self._parameters_fixed)
def test_run_simulation_view(self): filename_HR_volume = "HR_volume_postmortem" HR_volume = st.Stack.from_filename( os.path.join(self.dir_test_data, filename_HR_volume + ".nii.gz"), os.path.join(self.dir_test_data, filename_HR_volume + "_mask.nii.gz")) # 1) Test for Nearest Neighbor Interpolator slice_acquistion = sa.SliceAcqusition(HR_volume) slice_acquistion.set_interpolator_type("NearestNeighbor") slice_acquistion.set_motion_type("NoMotion") slice_acquistion.run_simulation_view_1() slice_acquistion.run_simulation_view_2() slice_acquistion.run_simulation_view_3() stacks_simulated = slice_acquistion.get_simulated_stacks() for i in range(0, len(stacks_simulated)): HR_volume_resampled_sitk = sitk.Resample( HR_volume.sitk, stacks_simulated[i].sitk, sitk.Euler3DTransform(), sitk.sitkNearestNeighbor, 0.0, stacks_simulated[i].sitk.GetPixelIDValue()) self.assertEqual( np.round(np.linalg.norm( sitk.GetArrayFromImage(stacks_simulated[i].sitk - HR_volume_resampled_sitk)), decimals=self.accuracy), 0) # 2) Test for Linear Interpolator slice_acquistion = sa.SliceAcqusition(HR_volume) slice_acquistion.set_interpolator_type("Linear") slice_acquistion.set_motion_type("NoMotion") slice_acquistion.run_simulation_view_1() slice_acquistion.run_simulation_view_2() slice_acquistion.run_simulation_view_3() stacks_simulated = slice_acquistion.get_simulated_stacks() for i in range(0, len(stacks_simulated)): HR_volume_resampled_sitk = sitk.Resample( HR_volume.sitk, stacks_simulated[i].sitk, sitk.Euler3DTransform(), sitk.sitkLinear, 0.0, stacks_simulated[i].sitk.GetPixelIDValue()) self.assertEqual( np.round(np.linalg.norm( sitk.GetArrayFromImage(stacks_simulated[i].sitk - HR_volume_resampled_sitk)), decimals=self.accuracy), 0) # 3) Test for Oriented Gaussian Interpolator alpha_cut = 3 slice_acquistion = sa.SliceAcqusition(HR_volume) slice_acquistion.set_interpolator_type("OrientedGaussian") slice_acquistion.set_motion_type("NoMotion") slice_acquistion.set_alpha_cut(alpha_cut) slice_acquistion.run_simulation_view_1() slice_acquistion.run_simulation_view_2() slice_acquistion.run_simulation_view_3() stacks_simulated = slice_acquistion.get_simulated_stacks() resampler = itk.ResampleImageFilter[image_type, image_type].New() resampler.SetDefaultPixelValue(0.0) resampler.SetInput(HR_volume.itk) interpolator = itk.OrientedGaussianInterpolateImageFunction[ image_type, pixel_type].New() interpolator.SetAlpha(alpha_cut) resampler.SetInterpolator(interpolator) PSF = psf.PSF() for i in range(0, len(stacks_simulated)): resampler.SetOutputParametersFromImage(stacks_simulated[i].itk) # Set covariance based on oblique PSF Cov_HR_coord = PSF.get_covariance_matrix_in_reconstruction_space( stacks_simulated[i], HR_volume) interpolator.SetCovariance(Cov_HR_coord.flatten()) resampler.UpdateLargestPossibleRegion() resampler.Update() HR_volume_resampled_itk = resampler.GetOutput() HR_volume_resampled_sitk = sitkh.get_sitk_from_itk_image( HR_volume_resampled_itk) self.assertEqual( np.round(np.linalg.norm( sitk.GetArrayFromImage(stacks_simulated[i].sitk - HR_volume_resampled_sitk)), decimals=self.accuracy), 0)
def test_ground_truth_affine_transforms_with_motion_OrientedGaussian(self): filename_HR_volume = "HR_volume_postmortem" HR_volume = st.Stack.from_filename( os.path.join(self.dir_test_data, filename_HR_volume + ".nii.gz"), os.path.join(self.dir_test_data, filename_HR_volume + "_mask.nii.gz")) alpha_cut = 3 # Run simulation for Oriented Gaussian interpolation, hence more # "realistic" case slice_acquistion = sa.SliceAcqusition(HR_volume) slice_acquistion.set_interpolator_type("OrientedGaussian") # slice_acquistion.set_interpolator_type("NearestNeighbor") # slice_acquistion.set_interpolator_type("Linear") slice_acquistion.set_motion_type("Random") # slice_acquistion.set_motion_type("NoMotion") slice_acquistion.set_alpha_cut(alpha_cut) slice_acquistion.run_simulation_view_1() slice_acquistion.run_simulation_view_2() slice_acquistion.run_simulation_view_3() # Get simulated stack of slices + corresponding ground truth affine # transforms indicating the correct acquisition of the slice # within the volume stacks_simulated = slice_acquistion.get_simulated_stacks() affine_transforms_ground_truth, rigid_motion_transforms_ground_truth = slice_acquistion.get_ground_truth_data( ) resampler = itk.ResampleImageFilter[image_type, image_type].New() resampler.SetDefaultPixelValue(0.0) resampler.SetInput(HR_volume.itk) interpolator = itk.OrientedGaussianInterpolateImageFunction[ image_type, pixel_type].New() interpolator.SetAlpha(alpha_cut) # interpolator = itk.LinearInterpolateImageFunction[image_type, pixel_type].New() # interpolator = itk.NearestNeighborInterpolateImageFunction[image_type, pixel_type].New() resampler.SetInterpolator(interpolator) PSF = psf.PSF() for i in range(0, len(stacks_simulated)): stack = stacks_simulated[i] slices = stack.get_slices() N_slices = stack.get_number_of_slices() for j in range(0, N_slices): # print("Stack %s: Slice %s/%s" %(i,j,N_slices-1)) slice = slices[j] slice.update_motion_correction( rigid_motion_transforms_ground_truth[i][j]) # Get covariance based on oblique PSF Cov_HR_coord = PSF.get_covariance_matrix_in_reconstruction_space( slice, HR_volume) # Update resampler interpolator.SetCovariance(Cov_HR_coord.flatten()) resampler.SetOutputParametersFromImage(slice.itk) resampler.UpdateLargestPossibleRegion() resampler.Update() HR_volume_resampled_slice_itk = resampler.GetOutput() HR_volume_resampled_slice_sitk = sitkh.get_sitk_from_itk_image( HR_volume_resampled_slice_itk) # HR_volume_resampled_slice_sitk = sitk.Resample( # HR_volume.sitk, slice.sitk, sitk.Euler3DTransform(), sitk.sitkNearestNeighbor, 0.0, slice.sitk.GetPixelIDValue() # ) norm_diff = np.linalg.norm( sitk.GetArrayFromImage(slice.sitk - HR_volume_resampled_slice_sitk)) # try: self.assertEqual(np.round(norm_diff, decimals=self.accuracy), 0)
def _run(self): if self._use_fixed_mask: fixed_sitk_mask = self._fixed.sitk_mask else: fixed_sitk_mask = None if self._use_moving_mask: moving_sitk_mask = self._moving.sitk_mask else: moving_sitk_mask = None # Blur moving image with oriented Gaussian prior to the registration if self._use_oriented_psf: # Get oriented Gaussian covariance matrix cov_HR_coord = psf.PSF( ).get_covariance_matrix_in_reconstruction_space( self._fixed, self._moving) # Create recursive YVV Gaussianfilter image_type = itk.Image[itk.D, self._fixed.sitk.GetDimension()] gaussian_yvv = itk.SmoothingRecursiveYvvGaussianImageFilter[ image_type, image_type].New() # Feed Gaussian filter with axis aligned covariance matrix sigma_axis_aligned = np.sqrt(np.diagonal(cov_HR_coord)) print("Oriented PSF blurring with (axis aligned) sigma = " + str(sigma_axis_aligned)) print("\t(Based on computed covariance matrix = ") for i in range(0, 3): print("\t\t" + str(cov_HR_coord[i, :])) print("\twith square root of diagonal " + str(np.diagonal(cov_HR_coord)) + ")") gaussian_yvv.SetInput(self._moving.itk) gaussian_yvv.SetSigmaArray(sigma_axis_aligned) gaussian_yvv.Update() moving_itk = gaussian_yvv.GetOutput() moving_itk.DisconnectPipeline() moving_sitk = sitkh.get_sitk_from_itk_image(moving_itk) else: moving_sitk = self._moving.sitk self._registration_method = \ simplereg.simple_itk_registration.SimpleItkRegistration( fixed_sitk=self._fixed.sitk, moving_sitk=moving_sitk, fixed_sitk_mask=fixed_sitk_mask, moving_sitk_mask=moving_sitk_mask, registration_type=self._registration_type, interpolator=self._interpolator, metric=self._metric, metric_params=self._metric_params, optimizer=self._optimizer, optimizer_params=self._optimizer_params, initializer_type=self._initializer_type, use_multiresolution_framework=self._use_multiresolution_framework, optimizer_scales=self._scales_estimator, shrink_factors=self._shrink_factors, smoothing_sigmas=self._smoothing_sigmas, verbose=self._use_verbose, ) self._registration_method.run() self._registration_transform_sitk = \ self._registration_method.get_registration_transform_sitk()