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()
예제 #2
0
    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,
        }
예제 #3
0
    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
예제 #4
0
    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(
        )
예제 #5
0
    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()