示例#1
0
def test_parallel():
    # Only relevant for 3d or 4d inputs

    # Make input data
    input_2d = image_gibbs.copy()
    input_3d = np.stack([input_2d, input_2d], axis=2)
    input_4d = np.stack([input_3d, input_3d], axis=3)

    # Test 3d case
    output_3d_parallel = gibbs_removal(input_3d, inplace=False, num_threads=2)
    output_3d_no_parallel = gibbs_removal(
        input_3d, inplace=False, num_threads=1
    )
    assert_array_almost_equal(output_3d_parallel, output_3d_no_parallel)

    # Test 4d case
    output_4d_parallel = gibbs_removal(input_4d, inplace=False, num_threads=2)
    output_4d_no_parallel = gibbs_removal(
        input_4d, inplace=False, num_threads=1
    )
    assert_array_almost_equal(output_4d_parallel, output_4d_no_parallel)

    # Test num_threads=None case
    output_4d_all_cpu = gibbs_removal(
        input_4d, inplace=False, num_threads=None
    )
    assert_array_almost_equal(output_4d_all_cpu, output_4d_no_parallel)
示例#2
0
def test_swapped_gibbs_2d():
    # 2D case: In this case slice_axis is a dummy variable. Since data is
    # already a single 2D image, to axis swapping is required
    image_cor0 = gibbs_removal(image_gibbs, slice_axis=0, inplace=False)
    assert_array_almost_equal(image_cor0, image_cor)

    image_cor1 = gibbs_removal(image_gibbs, slice_axis=1, inplace=False)
    assert_array_almost_equal(image_cor1, image_cor)

    image_cor2 = gibbs_removal(image_gibbs, slice_axis=2, inplace=False)
    assert_array_almost_equal(image_cor2, image_cor)
示例#3
0
def test_non_square_image():
    # Produce non-square 2D image
    Nori = 32
    img = np.zeros((6 * Nori, 6 * Nori))
    img[Nori: 2 * Nori, Nori: 2 * Nori] = 1
    img[2 * Nori: 3 * Nori, Nori: 3 * Nori] = 1
    img[3 * Nori: 4 * Nori, 2 * Nori: 3 * Nori] = 2
    img[4 * Nori: 5 * Nori, 3 * Nori: 5 * Nori] = 3

    # Corrupt image with gibbs ringing
    c = np.fft.fft2(img)
    c = np.fft.fftshift(c)
    c_crop = c[48:144, :]
    img_gibbs = abs(np.fft.ifft2(c_crop)/2)

    # Produce ground truth
    Nre = 16
    img_gt = np.zeros((6 * Nre, 6 * Nori))
    img_gt[Nre: 2 * Nre, Nori: 2 * Nori] = 1
    img_gt[2 * Nre: 3 * Nre, Nori: 3 * Nori] = 1
    img_gt[3 * Nre: 4 * Nre, 2 * Nori: 3 * Nori] = 2
    img_gt[4 * Nre: 5 * Nre, 3 * Nori: 5 * Nori] = 3

    # Suppressing gibbs artefacts
    img_cor = gibbs_removal(img_gibbs, inplace=False)

    # Correction of gibbs ringing have to be closer to gt than denoised image
    diff_raw = np.mean(abs(img_gibbs - img_gt))
    diff_cor = np.mean(abs(img_cor - img_gt))
    assert_(diff_raw > diff_cor)
示例#4
0
def test_swapped_gibbs_3d():
    image3d = np.zeros((6 * Nre, 2, 6 * Nre))
    image3d[:, 0, :] = image_gibbs
    image3d[:, 1, :] = image_gibbs

    image3d_cor = gibbs_removal(image3d, slice_axis=1)
    assert_array_almost_equal(image3d_cor[:, 0, :], image_cor)
    assert_array_almost_equal(image3d_cor[:, 1, :], image_cor)

    image3d = np.zeros((2, 6 * Nre, 6 * Nre))
    image3d[0, :, :] = image_gibbs
    image3d[1, :, :] = image_gibbs

    image3d_cor = gibbs_removal(image3d, slice_axis=0)
    assert_array_almost_equal(image3d_cor[0, :, :], image_cor)
    assert_array_almost_equal(image3d_cor[1, :, :], image_cor)
示例#5
0
def test_gibbs_3d():

    image3d = np.zeros((6 * Nre, 6 * Nre, 2))
    image3d[:, :, 0] = image_gibbs
    image3d[:, :, 1] = image_gibbs

    image3d_cor = gibbs_removal(image3d, 2)
    assert_array_almost_equal(image3d_cor[:, :, 0], image_cor)
    assert_array_almost_equal(image3d_cor[:, :, 1], image_cor)
示例#6
0
def test_gibbs_2d():

    # Correction of gibbs ringing have to be closer to gt than denoised image
    diff_raw = np.mean(abs(image_gibbs - image_gt))
    diff_cor = np.mean(abs(image_cor - image_gt))
    assert_(diff_raw > diff_cor)

    # Test if gibbs_removal works for 2D data
    image_cor2 = gibbs_removal(image_gibbs, inplace=False)
    assert_array_almost_equal(image_cor2, image_cor)
示例#7
0
def main(iFname, oFname, plot):
    """Main."""

    # load data
    data, affine = load_nifti(iFname)

    """
    Gibbs oscillation suppression of all multi-shell data and all slices
    can be performed in the following way:
    """

    data_corrected = gibbs_removal(data, slice_axis=2, num_threads=None)

    """
    Due to the high dimensionality of diffusion-weighted data, we recommend
    that you specify which is the axis of data matrix that corresponds to different
    slices in the above step. This is done by using the optional parameter
    'slice_axis'.
    
    Below we plot the results for an image acquired with b-value=0:
    """

    if plot:
        fig2, ax = plt.subplots(1, 3, figsize=(12, 6),
                                subplot_kw={'xticks': [], 'yticks': []})

        ax.flat[0].imshow(data[:, :, 0, 0].T, cmap='gray', origin='lower',
                          vmin=0, vmax=max(data))
        ax.flat[0].set_title('Uncorrected b0')
        ax.flat[1].imshow(data_corrected[:, :, 0, 0].T, cmap='gray',
                          origin='lower', vmin=0, vmax=max(data))
        ax.flat[1].set_title('Corrected b0')
        ax.flat[2].imshow(data_corrected[:, :, 0, 0].T - data[:, :, 0, 0].T,
                          cmap='gray', origin='lower', vmin=-500, vmax=500)
        ax.flat[2].set_title('Gibbs residuals')

        # plt.show()
        """
        .. figure:: Gibbs_suppression_b0.png
        :align: center
    
        Uncorrected (left panel) and corrected (middle panel) b-value=0 images. For
        reference, the difference between uncorrected and corrected images is shown
        in the right panel.
        """
        fig2.savefig(oFname+'.png')

        print("Result figure saved to: "+oFname+".png")

    # save as Nii
    nib.save(nib.Nifti1Image(data_corrected, affine), oFname+'.nii.gz')

    print("Ungibbsed dataset saved to: "+oFname+".nii.gz")

    """
示例#8
0
def _unring(vol):

    print('unringing', vol)

    img = load(vol)
    unringed = gibbs_removal(img.get_fdata())

    outPrefix = vol.split('.nii')[0] + '_ur'

    new_image = Nifti1Image(unringed, affine=img.affine, header=img.header)
    new_image.to_filename(outPrefix + '.nii.gz')
示例#9
0
文件: denoise.py 项目: kerkelae/dipy
    def run(self,
            input_files,
            slice_axis=2,
            n_points=3,
            num_processes=1,
            out_dir='',
            out_unring='dwi_unrig.nii.gz'):
        r"""Workflow for applying Gibbs Ringing method.

        Parameters
        ----------
        input_files : string
            Path to the input volumes. This path may contain wildcards to
            process multiple inputs at once.
        slice_axis : int, optional
            Data axis corresponding to the number of acquired slices.
            Could be (0, 1, or 2): for example, a value of 2 would mean the
            third axis.
        n_points : int, optional
            Number of neighbour points to access local TV (see note).
        num_processes : int or None, optional
            Split the calculation to a pool of children processes. Only
            applies to 3D or 4D `data` arrays. Default is 1. If < 0 the maximal
            number of cores minus |num_processes + 1| is used (enter -1 to use
            as many cores as possible). 0 raises an error.
        out_dir : string, optional
            Output directory. (default current directory)
        out_unrig : string, optional
            Name of the resulting denoised volume.

        References
        ----------
        .. [1] Neto Henriques, R., 2018. Advanced Methods for Diffusion MRI
        Data Analysis and their Application to the Healthy Ageing Brain
        (Doctoral thesis). https://doi.org/10.17863/CAM.29356

        .. [2] Kellner E, Dhital B, Kiselev VG, Reisert M. Gibbs-ringing
        artifact removal based on local subvoxel-shifts. Magn Reson Med. 2016
        doi: 10.1002/mrm.26054.

        """
        io_it = self.get_io_iterator()
        for dwi, ounring in io_it:
            logging.info('Unringing %s', dwi)
            data, affine, image = load_nifti(dwi, return_img=True)

            unring_data = gibbs_removal(data,
                                        slice_axis=slice_axis,
                                        n_points=n_points,
                                        num_processes=num_processes)

            save_nifti(ounring, unring_data, affine, image.header)
            logging.info('Denoised volume saved as %s', ounring)
示例#10
0
    def run(self,
            input_files,
            slice_axis=2,
            n_points=3,
            num_threads=1,
            out_dir='',
            out_unring='dwi_unrig.nii.gz'):
        r"""Workflow for applying Gibbs Ringing method.

        Parameters
        ----------
        input_files : string
            Path to the input volumes. This path may contain wildcards to
            process multiple inputs at once.
        slice_axis : int, optional
            Data axis corresponding to the number of acquired slices.
            Default is set to the third axis(2). Could be (0, 1, or 2).
        n_points : int, optional
            Number of neighbour points to access local TV (see note).
            Default is set to 3.
        num_threads : int or None, optional
            Number of threads. Only applies to 3D or 4D `data` arrays. If None
            then all available threads will be used. Otherwise, must be a
            positive integer.
            Default is set to 1.
        out_dir : string, optional
            Output directory (default input file directory)
        out_unrig : string, optional
            Name of the resulting denoised volume (default: dwi_unrig.nii.gz)

        References
        ----------
        .. [1] Neto Henriques, R., 2018. Advanced Methods for Diffusion MRI
        Data Analysis and their Application to the Healthy Ageing Brain
        (Doctoral thesis). https://doi.org/10.17863/CAM.29356

        .. [2] Kellner E, Dhital B, Kiselev VG, Reisert M. Gibbs-ringing
        artifact removal based on local subvoxel-shifts. Magn Reson Med. 2016
        doi: 10.1002/mrm.26054.

        """
        io_it = self.get_io_iterator()
        for dwi, ounring in io_it:
            logging.info('Unringing %s', dwi)
            data, affine, image = load_nifti(dwi, return_img=True)

            unring_data = gibbs_removal(data,
                                        slice_axis=slice_axis,
                                        n_points=n_points,
                                        num_threads=num_threads)

            save_nifti(ounring, unring_data, affine, image.header)
            logging.info('Denoised volume saved as %s', ounring)
示例#11
0
def test_swapped_gibbs_4d():
    image4d = np.zeros((2, 6 * Nre, 6 * Nre, 2))
    image4d[0, :, :, 0] = image_gibbs
    image4d[1, :, :, 0] = image_gibbs
    image4d[0, :, :, 1] = image_gibbs
    image4d[1, :, :, 1] = image_gibbs

    image4d_cor = gibbs_removal(image4d, slice_axis=0)
    assert_array_almost_equal(image4d_cor[0, :, :, 0], image_cor)
    assert_array_almost_equal(image4d_cor[1, :, :, 0], image_cor)
    assert_array_almost_equal(image4d_cor[0, :, :, 1], image_cor)
    assert_array_almost_equal(image4d_cor[1, :, :, 1], image_cor)
示例#12
0
def test_inplace():
    # Make input data
    input_2d = image_gibbs.copy()
    input_3d = np.stack([input_2d, input_2d], axis=2)
    input_4d = np.stack([input_3d, input_3d], axis=3)

    # Test 2d cases
    output_2d = gibbs_removal(input_2d, inplace=False)
    assert_raises(
        AssertionError, assert_array_almost_equal, input_2d, output_2d
    )

    output_2d = gibbs_removal(input_2d, inplace=True)
    assert_array_almost_equal(input_2d, output_2d)

    # Test 3d case
    output_3d = gibbs_removal(input_3d, inplace=False)
    assert_raises(
        AssertionError, assert_array_almost_equal, input_3d, output_3d
    )

    output_3d = gibbs_removal(input_3d, inplace=True)
    assert_array_almost_equal(input_3d, output_3d)

    # Test 4d case
    output_4d = gibbs_removal(input_4d, inplace=False)
    assert_raises(
        AssertionError, assert_array_almost_equal, input_4d, output_4d
    )

    output_4d = gibbs_removal(input_4d, inplace=True)
    assert_array_almost_equal(input_4d, output_4d)
示例#13
0
def test_gibbs_4d():

    image4d = np.zeros((6 * Nre, 6 * Nre, 2, 2))
    image4d[:, :, 0, 0] = image_gibbs
    image4d[:, :, 1, 0] = image_gibbs
    image4d[:, :, 0, 1] = image_gibbs
    image4d[:, :, 1, 1] = image_gibbs

    image4d_cor = gibbs_removal(image4d)
    assert_array_almost_equal(image4d_cor[:, :, 0, 0], image_cor)
    assert_array_almost_equal(image4d_cor[:, :, 1, 0], image_cor)
    assert_array_almost_equal(image4d_cor[:, :, 0, 1], image_cor)
    assert_array_almost_equal(image4d_cor[:, :, 1, 1], image_cor)
示例#14
0
removing high frequencies of the image's Fourier transform.
"""

c = np.fft.fft2(t1_slice)
c = np.fft.fftshift(c)
N = c.shape[0]
c_crop = c[64: 192, 64: 192]
N = c_crop.shape[0]
t1_gibbs = abs(np.fft.ifft2(c_crop)/4)

"""
Gibbs oscillation suppression of this single data slice can be performed by
running the following command:
"""

t1_unring = gibbs_removal(t1_gibbs, inplace=False)

"""
Let’s plot the results:
"""

fig1, ax = plt.subplots(1, 3, figsize=(12, 6),
                        subplot_kw={'xticks': [], 'yticks': []})

ax.flat[0].imshow(t1_gibbs, cmap="gray", vmin=100, vmax=400)
ax.flat[0].annotate('Rings', fontsize=10, xy=(81, 70),
                    color='red',
                    xycoords='data', xytext=(30, 0),
                    textcoords='offset points',
                    arrowprops=dict(arrowstyle="->",
                                    color='red'))
示例#15
0
suppression algorithm, Gibbs artefacts are artificially introduced by
removing high frequencies of the image's Fourier transform.
"""

c = np.fft.fft2(t1_slice)
c = np.fft.fftshift(c)
N = c.shape[0]
c_crop = c[64:192, 64:192]
N = c_crop.shape[0]
t1_gibbs = abs(np.fft.ifft2(c_crop) / 4)
"""
Gibbs oscillation suppression of this single data slice can be performed by
running the following command:
"""

t1_unring = gibbs_removal(t1_gibbs)
"""
Let’s plot the results:
"""

fig1, ax = plt.subplots(1,
                        3,
                        figsize=(12, 6),
                        subplot_kw={
                            'xticks': [],
                            'yticks': []
                        })

ax.flat[0].imshow(t1_gibbs, cmap="gray", vmin=100, vmax=400)
ax.flat[0].annotate('Rings',
                    fontsize=10,
示例#16
0
def denoise_pick(data,
                 affine,
                 hdr,
                 outpath,
                 mask,
                 type_denoise='macenko',
                 processes=1,
                 savedenoise=True,
                 verbose=False,
                 forcestart=False,
                 datareturn=False,
                 display=None):
    allowed_strings = ['mpca', 'yes', 'all', 'gibbs', 'none', 'macenko']
    string_inclusion(type_denoise, allowed_strings, "type_denoise")

    if type_denoise == 'macenko' or type_denoise == 'mpca' or type_denoise == 'yes' or type_denoise == 'all':
        type_denoise = '_mpca_'
    if type_denoise == 'gibbs':
        type_denoise = "_gibbs"
    if type_denoise is None or type_denoise == 'none':
        type_denoise = "_"

    outpath_denoise = outpath + type_denoise + 'dwi.nii.gz'
    if os.path.exists(outpath_denoise) and not forcestart:
        if verbose:
            txt = "Denoising already done at " + outpath_denoise
            print(txt)
        if datareturn:
            data = load_nifti(outpath_denoise)
    else:
        if type_denoise == '_mpca_':
            # data, snr = marcenko_denoise(data, False, verbose=verbose)
            t = time()
            denoised_arr, sigma = mppca(data,
                                        patch_radius=2,
                                        return_sigma=True,
                                        processes=processes,
                                        verbose=verbose)
            save_nifti(outpath_denoise, denoised_arr, affine, hdr=hdr)
            if verbose:
                txt = ("Saved image at " + outpath_denoise)
                print(txt)
            mask = np.array(mask, dtype=bool)
            mean_sigma = np.mean(sigma[mask])
            b0 = denoised_arr[..., 0]

            mean_signal = np.mean(b0[mask])

            snr = mean_signal / mean_sigma
            if verbose:
                print("Time taken for local MP-PCA ", -t + time())
                print("The SNR of the b0 image appears to be at " + str(snr))
            if display:
                denoise_fig(data, denoised_arr, type='macenko')
            data = denoised_arr

        if type_denoise == 'gibbs':
            outpath_denoise = outpath + '_gibbs.nii.gz'
            if os.path.exists(outpath_denoise) and not forcestart:
                if verbose:
                    txt = "Denoising already done at " + outpath_denoise
                    print(txt)
                if datareturn:
                    data = load_nifti(outpath_denoise)
            t = time()
            data_corrected = gibbs_removal(data, slice_axis=2)
            save_nifti(outpath_denoise, denoised_arr, affine, hdr=hdr)
            if verbose:
                print("Time taken for the gibbs removal ", -t + time())
            if display:
                denoise_fig(data, data_corrected, type='gibbs')

            data = data_corrected

        if type_denoise == "_":
            print('No denoising was done')
            save_nifti(outpath_denoise, data, affine, hdr=hdr)

    return data, outpath_denoise
示例#17
0
Since the diffusion kurtosis models involves the estimation of a large number
of parameters [TaxCMW2015]_ and since the non-Gaussian components of the
diffusion signal are more sensitive to artefacts [NetoHe2012]_, it might be
favorable to suppress the effects of noise and artefacts before diffusion
kurtosis fitting. In this example the effects of noise are suppressed using the
Marcenko-Pastur PCA denoising algorithm (:ref:`example-denoise-mppca`) and
the Gibbs artefact suppression algorithm (:ref:`example-denoise-gibbs`). Due
to the dataset's large number of diffusion-weighted volumes, these algorithm
might take some hours to process.
"""

print("Denoising")
den, sig = mppca(data, patch_radius=4, return_sigma=True)

print("Removing Gibbs artifacts")
deng = gibbs_removal(den, slice_axis=2)

# img = nib.load('denoised_mppca.nii.gz')
# img = nib.load('data_mppca_gibbs.nii.gz')
# deng = img.get_fdata()
""" Before carrying on with dki processing, I will just visually inspect the
quality of data and preprocessing step. In the figure below, I am ploting a
slice of the raw and denoised + gibbs suppressed data (upper panels).  Lower
left panel show the difference between raw and denoised data - this difference
map does not present anatomicaly information, indicating that PCA denoising
suppression noise with minimal low of anatomical information. Lower right map
shows the noise std estimate. Lower noise std values are underestimated in
background since noise in background appraoches a Rayleigh distribution.
"""

axial_slice = 10