Ejemplo n.º 1
0
def get_registered_image(nii_path, registration_dir, logging, overwrite=False):
    # get binaries
    nifty_reg_binaries_folder = source_files.get_niftyreg_binaries()
    program_path = get_binary(nifty_reg_binaries_folder, PROGRAM_NAME)

    # get file paths
    basedir = os.path.split(nii_path)[0]
    output_filename = os.path.join(
        basedir,
        "{}_transformed.nii".format(os.path.split(nii_path)[1].split(".")[0]),
    )
    if os.path.isfile(output_filename) and not overwrite:
        run = False
    else:
        run = True

    if run:
        destination_image = os.path.join(registration_dir, default_atlas_name)
        control_point_file = os.path.join(registration_dir,
                                          DEFAULT_CONTROL_POINT_FILE)

        log_file_path = os.path.join(basedir, "registration_log.txt")
        error_file_path = os.path.join(basedir, "registration_err.txt")

        reg_cmd = prepare_segmentation_cmd(
            program_path,
            nii_path,
            output_filename,
            destination_image,
            control_point_file,
        )
        logging.info("Running registration")
        try:
            safe_execute_command(reg_cmd, log_file_path, error_file_path)
        except SafeExecuteCommandError as err:
            raise RegistrationError("Registration failed; {}".format(err))
    else:
        logging.info("Skipping registration as output file already exists")

    return brainio.load_any(output_filename)
Ejemplo n.º 2
0
    def __get_binary(self, program_type):
        """
        Get the path to the registration (from nifty_reg) program
        based on the type

        :param str program_type:
        :return: The program path
        :rtype: str
        """
        from amap.config.config import get_binary

        program_names = {
            "affine": "reg_aladin",
            "freeform": "reg_f3d",
            "segmentation": "reg_resample",
            "transform": "reg_transform",
        }
        program_name = program_names[program_type]
        nifty_reg_binaries_folder = get_niftyreg_binaries()

        program_path = get_binary(nifty_reg_binaries_folder, program_name)

        return program_path
Ejemplo n.º 3
0
def transform_rois(
    roi_file,
    source_image_filename,
    destination_image_filename,
    control_point_file,
    output_filename,
    temp_output_filename,
    log_file_path,
    error_file_path,
    roi_reference_image=None,
    selem_size=15,
    nii_scale=None,
    transformation_matrix=None,
    debug=False,
    print_value_round_decimals=2,
    z_filter_padding=2,
):
    """
    Using a source image (e.g. downsampled stack), transform an ImageJ
    zipped collection of ROIs into the coordinate space of a
    destination image (e.g. an atlas), using the inverse control point file
    from an existing niftyreg registration

    :param roi_file: .zip collection of ImageJ ROIs
    :param source_image_filename: Image that the ROIs are defined in
    :param destination_image_filename: Image in the destination coordinate space
    :param control_point_file: Transformation from source to destination
    :param output_filename: output filename for the resulting nifti file
    :param temp_output_filename: Temporary file for registration
    :param log_file_path: Path to save niftyreg logs
    :param error_file_path: Path to save niftyreg errors
    :param roi_reference_image: Image on which the ROIs are defined (if not the
    downsampled image in the registration directory)
    :param selem_size: Structure element size for closing
    :param nii_scale: Scaling to correctly save the temporary nifti image
    :param transformation_matrix: Affine transform for the temporary nifti
    image
    :param print_value_round_decimals: How many decimal places to round
    values printed to console.
    :param z_filter_padding: Size of the filter in z when correcting for
    unlabled slices.
    :param debug: If True, don't delete temporary files
    """

    print("Loading ROIs")
    rois = read_roi_zip(roi_file)
    number_rois = len(rois)
    print(f"{number_rois} rois found")
    x = []
    y = []
    z = []
    for key in rois:
        for position in range(0, len(rois[key]["x"])):
            x.append(rois[key]["x"][position])
            y.append(rois[key]["y"][position])
            z.append(rois[key]["position"])

    print("Loading downsampled image image")
    downsampled_source_image = brainio.load_any(str(source_image_filename))

    print(f"Source image size: "
          f"x:{downsampled_source_image.shape[0]}, "
          f"y:{downsampled_source_image.shape[1]}, "
          f"y:{downsampled_source_image.shape[2]}")

    downsampled_source_image[:] = 0

    if roi_reference_image is not None:
        print("Reference image flag used. Loading reference image")
        reference_image_shape = brainio.get_size_image_from_file_paths(
            roi_reference_image)

        print(f"Reference image shape is "
              f"x:{reference_image_shape['x']}, "
              f"y:{reference_image_shape['y']}, "
              f"z:{reference_image_shape['z']}")

        x_downsample_factor = (reference_image_shape["x"] /
                               downsampled_source_image.shape[0])
        y_downsample_factor = (reference_image_shape["y"] /
                               downsampled_source_image.shape[1])
        z_downsample_factor = (reference_image_shape["z"] /
                               downsampled_source_image.shape[2])

        print(f"ROIs will be downsampled by a factor of "
              f"x:{round(x_downsample_factor, print_value_round_decimals)}, "
              f"y:{round(y_downsample_factor, print_value_round_decimals)}, "
              f"z:{round(z_downsample_factor, print_value_round_decimals)}")

    # TODO: optimise this
    print("Creating temporary ROI image")
    for position in range(0, len(x)):
        if roi_reference_image is None:
            downsampled_source_image[x[position], y[position], z[position]] = 1
        else:
            x_scale = int(round(x[position] / x_downsample_factor))
            y_scale = int(round(y[position] / y_downsample_factor))
            z_scale = int(round(z[position] / z_downsample_factor))
            downsampled_source_image[x_scale, y_scale, z_scale] = 1

    print("Cleaning up ROI image")
    # TODO speed this up - parallelise?
    selem = morphology.selem.square(selem_size)
    for plane in tqdm(range(0, downsampled_source_image.shape[2])):
        tmp = morphology.binary.binary_closing(downsampled_source_image[:, :,
                                                                        plane],
                                               selem=selem)
        tmp = morphology.convex_hull_object(tmp)
        downsampled_source_image[:, :,
                                 plane] = morphology.binary.binary_closing(
                                     tmp, selem=selem)

    if roi_reference_image is not None:
        if z_downsample_factor < 1:
            print("ROI was defined at a lower z-resolution than the atlas. "
                  "Correcting with a maximum filter")
            z_filter_size = int(round(1 / z_scale)) + z_filter_padding
            downsampled_source_image = maximum_filter1d(
                downsampled_source_image, z_filter_size, axis=2)

    print(f"Saving temporary ROI image at: {temp_output_filename}")
    brainio.to_nii(
        downsampled_source_image,
        str(temp_output_filename),
        scale=nii_scale,
        affine_transform=transformation_matrix,
    )

    print("Preparing ROI registration")
    nifty_reg_binaries_folder = get_niftyreg_binaries()
    program_path = get_binary(nifty_reg_binaries_folder, PROGRAM_NAME)

    reg_cmd = prepare_segmentation_cmd(
        program_path,
        temp_output_filename,
        output_filename,
        destination_image_filename,
        control_point_file,
    )
    print("Running ROI registration")
    try:
        safe_execute_command(reg_cmd, log_file_path, error_file_path)
    except SafeExecuteCommandError as err:
        raise RegistrationError("ROI registration failed; {}".format(err))

    print(f"Registered ROI image can be found at {output_filename}")

    if not debug:
        print("Deleting temporary files")
        remove(temp_output_filename)
        remove(log_file_path)
        remove(error_file_path)