コード例 #1
0
    def compute_slice_projections(self):

        linear_operators = lin_op.LinearOperators()
        self._slice_projections = [None] * len(self._stacks)

        for i_stack, stack in enumerate(self._stacks):
            slices = stack.get_slices()

            N_slices = self._get_original_number_of_slices(stack)

            self._slice_projections[i_stack] = [self._init_value] * N_slices

            if self._verbose:
                ph.print_info("Stack %d/%d: Compute slice projections ... " %
                              (i_stack + 1, len(self._stacks)),
                              newline=False)

            # Compute slice projections based on assumed slice acquisition
            # protocol
            for slice in slices:
                i_slice = slice.get_slice_number()
                self._slice_projections[i_stack][i_slice] = linear_operators.A(
                    self._reference, slice)

            if self._verbose:
                print("done")
コード例 #2
0
    def test_forward_operator_stack(self):

        data_reader = dr.MultipleImagesReader(self.paths_to_filenames,
                                              suffix_mask=self.suffix_mask)
        data_reader.read_data()
        stacks = data_reader.get_data()
        stack = stacks[0]

        reconstruction = st.Stack.from_filename(self.path_to_recon,
                                                self.path_to_recon_mask)

        linear_operators = lin_op.LinearOperators()
        simulated_stack = linear_operators.A(reconstruction,
                                             stack,
                                             interpolator_mask="Linear")
        simulated_stack.set_filename(stack.get_filename() + "_sim")

        # sitkh.show_stacks([stack, simulated_stack])
        # simulated_stack.show(1)
        # reconstruction.show(1)
        # stack.show(1)

        filename_reference = "IC_N4ITK_HASTE_exam_3.5mm_800ms_3_simulated"
        reference_simulated_stack = st.Stack.from_filename(
            os.path.join(self.dir_data, "result-comparison",
                         filename_reference + ".nii.gz"),
            os.path.join(self.dir_data, "result-comparison",
                         filename_reference + self.suffix_mask + ".nii.gz"))

        # Error simulated stack
        difference_sitk = simulated_stack.sitk - \
            reference_simulated_stack.sitk
        error = np.linalg.norm(sitk.GetArrayFromImage(difference_sitk))
        self.assertAlmostEqual(error, 0, places=self.precision)

        # Error propagated mask
        difference_sitk = simulated_stack.sitk_mask - \
            reference_simulated_stack.sitk_mask
        error = np.linalg.norm(sitk.GetArrayFromImage(difference_sitk))
        self.assertAlmostEqual(error, 0, places=self.precision)
コード例 #3
0
    def test_forward_operator_stack(self):

        stack = st.Stack.from_filename(self.path_to_file)
        reconstruction = st.Stack.from_filename(self.path_to_recon,
                                                self.path_to_recon_mask)

        linear_operators = lin_op.LinearOperators()
        simulated_stack = linear_operators.A(reconstruction,
                                             stack,
                                             interpolator_mask="Linear")
        simulated_stack.set_filename(stack.get_filename() + "_sim")

        # sitkh.show_stacks(
        #     [stack, simulated_stack], segmentation=simulated_stack)

        filename_reference = os.path.join(self.dir_data, "recon_projections",
                                          "stack",
                                          "%s_sim.nii.gz" % self.filename)
        filename_reference_mask = os.path.join(
            self.dir_data, "recon_projections", "stack",
            "%s_sim%s.nii.gz" % (self.filename, self.suffix_mask))

        reference_simulated_stack = st.Stack.from_filename(
            filename_reference, filename_reference_mask)

        # Error simulated stack
        difference_sitk = simulated_stack.sitk - \
            reference_simulated_stack.sitk
        error = np.linalg.norm(sitk.GetArrayFromImage(difference_sitk))
        self.assertAlmostEqual(error, 0, places=self.precision)

        # Error propagated mask
        difference_sitk = simulated_stack.sitk_mask - \
            reference_simulated_stack.sitk_mask
        error = np.linalg.norm(sitk.GetArrayFromImage(difference_sitk))
        self.assertAlmostEqual(error, 0, places=self.precision)
コード例 #4
0
def main():

    input_parser = InputArgparser(
        description="Simulate stacks from obtained reconstruction. "
        "Script simulates/projects the slices at estimated positions "
        "within reconstructed volume. Ideally, if motion correction was "
        "correct, the resulting stack of such obtained projected slices, "
        "corresponds to the originally acquired (motion corrupted) data.",
    )
    input_parser.add_filenames(required=True)
    input_parser.add_filenames_masks()
    input_parser.add_dir_input_mc(required=True)
    input_parser.add_reconstruction(required=True)
    input_parser.add_dir_output(required=True)
    input_parser.add_suffix_mask(default="_mask")
    input_parser.add_prefix_output(default="Simulated_")
    input_parser.add_option(
        option_string="--copy-data",
        type=int,
        help="Turn on/off copying of original data (including masks) to "
        "output folder.",
        default=0)
    input_parser.add_option(
        option_string="--reconstruction-mask",
        type=str,
        help="If given, reconstruction image mask is propagated to "
        "simulated stack(s) of slices as well",
        default=None)
    input_parser.add_interpolator(
        option_string="--interpolator-mask",
        help="Choose the interpolator type to propagate the reconstruction "
        "mask (%s)." % (INTERPOLATOR_TYPES),
        default="NearestNeighbor")
    input_parser.add_log_config(default=0)
    input_parser.add_verbose(default=0)
    input_parser.add_slice_thicknesses(default=None)

    args = input_parser.parse_args()
    input_parser.print_arguments(args)

    if args.interpolator_mask not in ALLOWED_INTERPOLATORS:
        raise IOError(
            "Unknown interpolator provided. Possible choices are %s" % (
                INTERPOLATOR_TYPES))

    if args.log_config:
        input_parser.log_config(os.path.abspath(__file__))

    # Read motion corrected data
    data_reader = dr.MultipleImagesReader(
        file_paths=args.filenames,
        file_paths_masks=args.filenames_masks,
        suffix_mask=args.suffix_mask,
        dir_motion_correction=args.dir_input_mc,
        stacks_slice_thicknesses=args.slice_thicknesses,
    )
    data_reader.read_data()
    stacks = data_reader.get_data()

    reconstruction = st.Stack.from_filename(
        args.reconstruction, args.reconstruction_mask, extract_slices=False)

    linear_operators = lin_op.LinearOperators()

    for i, stack in enumerate(stacks):

        # initialize image data array(s)
        nda = np.zeros_like(sitk.GetArrayFromImage(stack.sitk))
        nda[:] = np.nan

        if args.reconstruction_mask:
            nda_mask = np.zeros_like(sitk.GetArrayFromImage(stack.sitk_mask))

        slices = stack.get_slices()
        kept_indices = [s.get_slice_number() for s in slices]

        # Fill stack information "as if slice was acquired consecutively"
        # Therefore, simulated stack slices correspond to acquired slices
        # (in case motion correction was correct)
        for j in range(nda.shape[0]):
            if j in kept_indices:
                index = kept_indices.index(j)
                simulated_slice = linear_operators.A(
                    reconstruction,
                    slices[index],
                    interpolator_mask=args.interpolator_mask
                )
                nda[j, :, :] = sitk.GetArrayFromImage(simulated_slice.sitk)

                if args.reconstruction_mask:
                    nda_mask[j, :, :] = sitk.GetArrayFromImage(
                        simulated_slice.sitk_mask)

        # Create nifti image with same image header as original stack
        simulated_stack_sitk = sitk.GetImageFromArray(nda)
        simulated_stack_sitk.CopyInformation(stack.sitk)

        if args.reconstruction_mask:
            simulated_stack_sitk_mask = sitk.GetImageFromArray(nda_mask)
            simulated_stack_sitk_mask.CopyInformation(stack.sitk_mask)
        else:
            simulated_stack_sitk_mask = None

        simulated_stack = st.Stack.from_sitk_image(
            image_sitk=simulated_stack_sitk,
            image_sitk_mask=simulated_stack_sitk_mask,
            filename=args.prefix_output + stack.get_filename(),
            extract_slices=False,
            slice_thickness=stack.get_slice_thickness(),
        )

        if args.verbose:
            sitkh.show_stacks([
                stack, simulated_stack],
                segmentation=stack)

        simulated_stack.write(
            args.dir_output,
            write_mask=False,
            write_slices=False,
            suffix_mask=args.suffix_mask)

        if args.copy_data:
            stack.write(
                args.dir_output,
                write_mask=True,
                write_slices=False,
                suffix_mask="_mask")

    return 0
コード例 #5
0
    def __init__(
        self,
        stacks,
        reconstruction,
        alpha_cut,
        alpha,
        iter_max,
        minimizer,
        x_scale,
        data_loss,
        data_loss_scale,
        huber_gamma,
        deconvolution_mode,
        predefined_covariance,
        verbose,
        image_type=itk.Image.D3,
        use_masks=True,
    ):

        # Initialize variables
        self._stacks = stacks
        self._reconstruction = reconstruction

        # Cut-off distance for Gaussian blurring filter
        self._alpha_cut = alpha_cut

        self._deconvolution_mode = deconvolution_mode
        self._predefined_covariance = predefined_covariance
        self._linear_operators = lin_op.LinearOperators(
            deconvolution_mode=self._deconvolution_mode,
            predefined_covariance=self._predefined_covariance,
            alpha_cut=self._alpha_cut,
            image_type=image_type)

        # Settings for solver
        self._alpha = alpha
        self._iter_max = iter_max

        self._use_masks = use_masks

        self._minimizer = minimizer
        self._data_loss = data_loss
        self._data_loss_scale = data_loss_scale

        if x_scale == "max":
            self._x_scale = sitk.GetArrayFromImage(reconstruction.sitk).max()

            # Avoid zero in case zero-image is given
            if self._x_scale == 0:
                self._x_scale = 1
        else:
            self._x_scale = x_scale

        self._huber_gamma = huber_gamma

        self._verbose = verbose

        # Allocate variables containing information about statistics of
        # reconstruction
        self._computational_time = None
        self._residual_ell2 = None
        self._residual_prior = None

        # Create PyBuffer object for conversion between NumPy arrays and ITK
        # images
        self._itk2np = itk.PyBuffer[image_type]

        # -----------------------------Set helpers-----------------------------
        self._N_stacks = len(self._stacks)

        # Compute total amount of pixels for all slices
        self._N_total_slice_voxels = 0
        for i in range(0, self._N_stacks):
            N_stack_voxels = np.array(self._stacks[i].sitk.GetSize()).prod()
            self._N_total_slice_voxels += N_stack_voxels

        # Extract information ready to use for itk image conversion operations
        self._reconstruction_shape = sitk.GetArrayFromImage(
            self._reconstruction.sitk).shape

        # Compute total amount of voxels of x:
        self._N_voxels_recon = np.array(
            self._reconstruction.sitk.GetSize()).prod()