def resample_mri(
    target,
    header=None,
    image_spacing=None,
    template_spacing=(1, 1, 1),
    dim_init=None,
    dim_result=None,
    spline_order=3,
):
    """ Resample mri data into standard 1mm spacing or wanted dimension

    :param target: nibabel type data
    :param header: nifti1 header data
    :param tuple image_spacing: provide image spacing
    :param tuple template_spacing: provide template image spacing
    :param tuple dim_init: Initial dimension
    :param tuple dim_result: Targeted dimension
    :param int spline_order: spline order of resampling
    :returns: resampled nibabel type data
    """

    # we use deepcopy of an object to prevent pointer overwriting
    mri = copy.deepcopy(target)

    data = mri.get_data()

    if image_spacing is None:
        image_spacing = mri.header.get_zooms()

    if dim_init is not None:
        if dim_result is not None:
            image_spacing = np.divide(dim_result, dim_init)
            if template_spacing is None:
                template_spacing = mri.header.get_zooms() / image_spacing

    image_resized = ndimage.interpolation.zoom(
        data, zoom=image_spacing, order=spline_order
    )
    affine = affine_correction(mri.affine, image_spacing)

    if header is not None:
        resampled = cat.Nifti1Image(image_resized, affine, header=header)
        for letter in ["b", "c", "d"]:
            resampled.header["quatern_{}".format(letter)] = np.copy(
                header["quatern_{}".format(letter)]
            )
        resampled.header["qform_code"] = np.copy(header["qform_code"])

    else:
        resampled = cat.Nifti1Image(image_resized, affine, header=mri.header)

    resampled.header.set_zooms(template_spacing)
    return resampled
def n4_bias_correction(mri, mask_image=None, shrink_factor=(4, 4, 4)):
    """ process n4 bias-field correction to mri subject.

    :param mri: nibabel mri instance
    :param mask_image: array of mri mask
    :param shrink_factor: factor of shrink
    :returns: returns bias-field corrected nibabel instance
    """
    from tinycat.label import gen_mask
    import SimpleITK as sitk

    mri_data = mri.get_data()
    mri_image = sitk.GetImageFromArray(mri_data)
    mri_image = sitk.Cast(mri_image, sitk.sitkFloat32)

    if mask_image is None:
        mask_image = sitk.OtsuThreshold(mri_image, 1)
    else:
        mask_image = sitk.GetImageFromArray(mask_image)

    # Shrink image to minimize computation cost
    mri_image_sh = sitk.Shrink(mri_image, shrink_factor)
    mask_image_sh = sitk.Shrink(mask_image, shrink_factor)
    corrector = sitk.N4BiasFieldCorrectionImageFilter()

    # Default parameters for slicer 3D
    corrector.SetSplineOrder = 3
    corrector.SetConvergenceThreshold = 0.0001
    corrector.SetMaximumNumberOfIterations = [50, 50, 50]
    corrector.SetWienerFilterNoise = 0
    corrector.SetNumberOfHistogramBins = 0
    corrector.SetBiasFieldFullWidthAtHalfMaximum = 0.15

    # Calculate bias-field filter
    n4_output = corrector.Execute(mri_image_sh, mask_image_sh)
    n4_filter = sitk.Subtract(n4_output, mri_image_sh)

    # Apply bias-field filter to masked original data
    n4_array = ndimage.interpolation.zoom(
        sitk.GetArrayFromImage(n4_filter), zoom=shrink_factor, order=3
    )
    mri_data = sitk.GetArrayFromImage(mri_image)
    semi_mask = mri_data >= mri_data.mean()
    mask = gen_mask(semi_mask)
    mri_data[mask] = mri_data[mask] - n4_array[mask]

    return cat.Nifti1Image(mri_data, mri.affine, mri.header)
def convert_image_coordinates(image, out_axcodes):
    """convert image coordinates based on nibabel orientations

    Args:
        image (nib.Nifti1Image): nibabel image
        out_axacodes (tuple): tuple of axcode

    Returns:
        nib.Nifti1Image: transformed image
    """

    in_axcodes = nib.aff2axcodes(image.affine)
    in_ornt = nib.orientations.axcodes2ornt(in_axcodes)
    out_ornt = nib.orientations.axcodes2ornt(out_axcodes)
    transformed_ornt = nib.orientations.ornt_transform(in_ornt, out_ornt)
    transformed_array = nib.orientations.apply_orientation(
        image.dataobj, transformed_ornt
    )
    transformed_image = cat.Nifti1Image(
        transformed_array, image.affine, header=image.header
    )
    return transformed_image
def convert_aseg_to_9_v1_and_save(directory="./",
                                  result_filename="converted.nii.gz"):
    aparc_aseg = cat.load(os.path.join(directory, ASEG_FILENAME))
    converted = convert_aseg_to_9_v1(aparc_aseg.get_data())
    cat.Nifti1Image(converted, aparc_aseg.affine,
                    header=aparc_aseg.header).to_filename(result_filename)
def convert_104_v1_to_104_v2_and_save(aqua_104_v1_filename,
                                      result_filename="converted.nii.gz"):
    aqua_104_v1 = cat.load(aqua_104_v1_filename)
    converted = convert_104_v1_to_104_v2(aqua_104_v1.get_data())
    cat.Nifti1Image(converted, aqua_104_v1.affine,
                    header=aqua_104_v1.header).to_filename(result_filename)