Ejemplo n.º 1
0
def test_piesno():
    # Values taken from hispeed.OptimalPIESNO with the test data
    # in the package computed in matlab
    test_piesno_data = nib.load(dipy.data.get_data("test_piesno")).get_data()
    sigma = piesno(test_piesno_data, N=8, alpha=0.01, l=1, eps=1e-10,
                   return_mask=False)
    assert_almost_equal(sigma, 0.010749458025559)

    noise1 = (np.random.randn(100, 100, 100) * 50) + 10
    noise2 = (np.random.randn(100, 100, 100) * 50) + 10
    rician_noise = np.sqrt(noise1**2 + noise2**2)
    sigma, mask = piesno(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10,
                         return_mask=True)

    # less than 3% of error?
    assert_(np.abs(sigma - 50) / sigma < 0.03)

    # Test using the median as the initial estimation
    initial_estimation = (np.median(sigma) /
                          np.sqrt(2 * _inv_nchi_cdf(1, 1, 0.5)))

    sigma, mask = _piesno_3D(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10,
                             return_mask=True,
                             initial_estimation=initial_estimation)

    assert_(np.abs(sigma - 50) / sigma < 0.03)

    sigma = _piesno_3D(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10,
                       return_mask=False,
                       initial_estimation=initial_estimation)
    assert_(np.abs(sigma - 50) / sigma < 0.03)

    sigma = _piesno_3D(np.zeros_like(rician_noise), N=1, alpha=0.01, l=1,
                       eps=1e-10, return_mask=False,
                       initial_estimation=initial_estimation)

    assert_(np.all(sigma == 0))

    sigma, mask = _piesno_3D(np.zeros_like(rician_noise), N=1, alpha=0.01, l=1,
                             eps=1e-10, return_mask=True,
                             initial_estimation=initial_estimation)

    assert_(np.all(sigma == 0))
    assert_(np.all(mask == 0))

    # Check if no noise points found in array it exits
    sigma = _piesno_3D(1000*np.ones_like(rician_noise), N=1, alpha=0.01, l=1,
                       eps=1e-10, return_mask=False, initial_estimation=10)
    assert_(np.all(sigma == 10))
Ejemplo n.º 2
0
def test_piesno():
    # Values taken from hispeed.OptimalPIESNO with the test data
    # in the package computed in matlab
    test_piesno_data = nib.load(dpd.get_fnames("test_piesno")).get_data()
    sigma = piesno(test_piesno_data, N=8, alpha=0.01, l=1, eps=1e-10,
                   return_mask=False)
    assert_almost_equal(sigma, 0.010749458025559)

    noise1 = (np.random.randn(100, 100, 100) * 50) + 10
    noise2 = (np.random.randn(100, 100, 100) * 50) + 10
    rician_noise = np.sqrt(noise1**2 + noise2**2)
    sigma, mask = piesno(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10,
                         return_mask=True)

    # less than 3% of error?
    assert_(np.abs(sigma - 50) / sigma < 0.03)

    # Test using the median as the initial estimation
    initial_estimation = (np.median(sigma) /
                          np.sqrt(2 * _inv_nchi_cdf(1, 1, 0.5)))

    sigma, mask = _piesno_3D(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10,
                             return_mask=True,
                             initial_estimation=initial_estimation)

    assert_(np.abs(sigma - 50) / sigma < 0.03)

    sigma = _piesno_3D(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10,
                       return_mask=False,
                       initial_estimation=initial_estimation)
    assert_(np.abs(sigma - 50) / sigma < 0.03)

    sigma = _piesno_3D(np.zeros_like(rician_noise), N=1, alpha=0.01, l=1,
                       eps=1e-10, return_mask=False,
                       initial_estimation=initial_estimation)

    assert_(np.all(sigma == 0))

    sigma, mask = _piesno_3D(np.zeros_like(rician_noise), N=1, alpha=0.01, l=1,
                             eps=1e-10, return_mask=True,
                             initial_estimation=initial_estimation)

    assert_(np.all(sigma == 0))
    assert_(np.all(mask == 0))

    # Check if no noise points found in array it exits
    sigma = _piesno_3D(1000*np.ones_like(rician_noise), N=1, alpha=0.01, l=1,
                       eps=1e-10, return_mask=False, initial_estimation=10)
    assert_(np.all(sigma == 10))
Ejemplo n.º 3
0
def _get_piesno_sigma(vol, log, args):
    data = vol.get_data()
    sigma = np.zeros(data.shape[:3], dtype=np.float32)
    mask_noise = np.zeros(data.shape[:3], dtype=np.int16)

    for idx in range(data.shape[-2]):
        log.info('Now processing slice %s out of %s', idx + 1, data.shape[-2])
        sigma[..., idx], mask_noise[..., idx] = \
            piesno(data[..., idx, :], N=args.N, return_mask=True)

    if args.save_piesno_mask is not None:
        nib.save(nib.Nifti1Image(mask_noise, vol.affine, vol.header),
                 args.save_piesno_mask)

    # If the noise mask has few voxels, the detected noise standard
    # deviation can be very low and maybe something went wrong. We
    # check here that at least 1% of noisy voxels were found and warn
    # the user otherwise.
    frac_noisy_voxels = np.sum(mask_noise) / np.size(mask_noise) * 100

    if frac_noisy_voxels < 1.:
        log.warning(
            'PIESNO was used with N={}, but it found only {:.3f}% of voxels '
            'as pure noise with a mean standard deviation of {:.5f}. This is '
            'suspicious, so please check the resulting sigma volume if '
            'something went wrong. In cases where PIESNO is not working, '
            'you might want to try --noise_est basic'.format(
                args.N, frac_noisy_voxels, np.mean(sigma)))
    else:
        log.info('The noise standard deviation from piesno is %s',
                 np.array_str(sigma[0, 0, :]))

    return sigma
Ejemplo n.º 4
0
def local_piesno(data, N, size=5, return_mask=True):

    m_out = np.zeros(data.shape[:-1], dtype=np.bool)
    reshaped_maps = sliding_window(data, (size, size, size, data.shape[-1]))

    sigma = np.zeros(reshaped_maps.shape[0], dtype=np.float32)
    mask = np.zeros((reshaped_maps.shape[0], size**3), dtype=np.bool)

    for i in range(reshaped_maps.shape[0]):
        cur_map = reshaped_maps[i].reshape(size**3, 1, -1)
        sigma[i], m = piesno(cur_map, N=N, return_mask=True)
        mask[i] = np.squeeze(m)

    s_out = sigma.reshape(data.shape[0] // size, data.shape[1] // size, data.shape[2] // size)

    for n, i in enumerate(np.ndindex(s_out.shape)):
        i = np.array(i) * size
        j = i + size
        m_out[i[0]:j[0], i[1]:j[1], i[2]:j[2]] = mask[n].reshape(size, size, size)

    interpolated = np.zeros_like(data[..., 0], dtype=np.float32)
    x, y, z = np.array(s_out.shape) * size
    interpolated[:x, :y, :z] = zoom(s_out, size, order=1)

    if return_mask:
        return interpolated, m_out
    return interpolated
Ejemplo n.º 5
0
def local_piesno(data, N, size=5, return_mask=True):

    m_out = np.zeros(data.shape[:-1], dtype=np.bool)
    reshaped_maps = sliding_window(data, (size, size, size, data.shape[-1]))

    sigma = np.zeros(reshaped_maps.shape[0], dtype=np.float32)
    mask = np.zeros((reshaped_maps.shape[0], size**3), dtype=np.bool)

    for i in range(reshaped_maps.shape[0]):
        cur_map = reshaped_maps[i].reshape(size**3, 1, -1)
        sigma[i], m = piesno(cur_map, N=N, return_mask=True)
        mask[i] = np.squeeze(m)

    s_out = sigma.reshape(data.shape[0] // size, data.shape[1] // size,
                          data.shape[2] // size)

    for n, i in enumerate(np.ndindex(s_out.shape)):
        i = np.array(i) * size
        j = i + size
        m_out[i[0]:j[0], i[1]:j[1],
              i[2]:j[2]] = mask[n].reshape(size, size, size)

    interpolated = np.zeros_like(data[..., 0], dtype=np.float32)
    x, y, z = np.array(s_out.shape) * size
    interpolated[:x, :y, :z] = zoom(s_out, size, order=1)

    if return_mask:
        return interpolated, m_out
    return interpolated
Ejemplo n.º 6
0
def test_piesno_type():
    # This is testing if the `sum_m2` cast is overflowing
    data = np.ones((10, 10, 10), dtype=np.int16)
    for i in range(10):
        data[:, i, :] = i * 26

    sigma = piesno(data, N=2, alpha=0.01, l=1, eps=1e-10, return_mask=False)
    assert_almost_equal(sigma, 79.970003117424739)
Ejemplo n.º 7
0
def test_piesno_type():
    # This is testing if the `sum_m2` cast is overflowing
    data = np.ones((10, 10, 10), dtype=np.int16)
    for i in range(10):
        data[:, i, :] = i * 26

    sigma = piesno(data, N=2, alpha=0.01, l=1, eps=1e-10, return_mask=False)
    assert_almost_equal(sigma, 79.970003117424739)
Ejemplo n.º 8
0
def execution(self, context):

    data_vol = aims.read(self.dwi_data.fullPath())
    header = data_vol.header()
    data = vol_to_array(data_vol)
    sigma = piesno(data, self.coil_number, alpha=self.alpha, l=self.trials, itermax=ITERMAX, eps=EPS, return_mask=False)
    sigma_arr = sigma*np.ones(data.shape[:-1], dtype=np.float32)
    sigma_vol = array_to_vol(sigma_arr, header=header)
    aims.write(sigma_vol, self.sigma.fullPath())
Ejemplo n.º 9
0
def test_piesno():
    # Values taken from hispeed.OptimalPIESNO with the test data
    # in the package computed in matlab
    test_piesno_data = nib.load(dipy.data.get_data("test_piesno")).get_data()
    sigma = piesno(test_piesno_data,
                   N=8,
                   alpha=0.01,
                   l=1,
                   eps=1e-10,
                   return_mask=False)
    assert_almost_equal(sigma, 0.010749458025559)
Ejemplo n.º 10
0
def main(fname_in, freedom_degree,file_output):

    img = nib.load(fname_in)
    data = img.get_data()

    sigma, mask = piesno(data, N=freedom_degree, return_mask=True)

    sct.printv('\nWrite NIFTI volumes...')
    output_name = file_output
    nib.save(nib.Nifti1Image(mask, img.get_affine(), img.get_header()), output_name)
    sct.printv('\n.. The noise standard deviation is sigma = ' + str(sigma))
def main(fname_in, freedom_degree, file_output):

    img = nib.load(fname_in)
    data = img.get_data()

    sigma, mask = piesno(data, N=freedom_degree, return_mask=True)

    sct.printv('\nWrite NIFTI volumes...')
    output_name = file_output
    nib.save(nib.Nifti1Image(mask, img.get_affine(), img.get_header()), output_name)
    sct.printv('\n.. The noise standard deviation is sigma = ' + str(sigma))
Ejemplo n.º 12
0
def test_piesno():
    # Values taken from hispeed.OptimalPIESNO with the test data
    # in the package computed in matlab
    test_piesno_data = nib.load(dipy.data.get_data("test_piesno")).get_data()
    sigma = piesno(test_piesno_data, N=8, alpha=0.01, l=1, eps=1e-10, return_mask=False)
    assert_almost_equal(sigma, 0.010749458025559)

    noise1 = (np.random.randn(100, 100, 100) * 50) + 10
    noise2 = (np.random.randn(100, 100, 100) * 50) + 10
    rician_noise = np.sqrt(noise1**2 + noise2**2)
    sigma, mask = piesno(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10, return_mask=True)

    # less than 3% of error?
    assert_almost_equal(np.abs(sigma - 50) / sigma < 0.03, True)

    # Test using the median as the initial estimation
    initial_estimation = np.median(sigma) / np.sqrt(2 * _inv_nchi_cdf(1, 1, 0.5))
    sigma, mask = _piesno_3D(rician_noise, N=1, alpha=0.01, l=1, eps=1e-10, return_mask=True,
                             initial_estimation=initial_estimation)
    assert_almost_equal(np.abs(sigma - 50) / sigma < 0.03, True)
Ejemplo n.º 13
0
def main():
    parser = buildArgsParser()
    args = parser.parse_args()

    if args.savename is None:
        temp, ext = str.split(os.path.basename(args.input), '.', 1)
        filename = os.path.dirname(os.path.realpath(args.input)) + '/' + temp

    else:
        filename = args.savename

    # If the file already exists, check if the user want to overwrite it. If not, simply exit.
    filename += '_denoised.nii.gz'

    print("Now denoising", os.path.realpath(args.input))

    vol = nib.load(args.input)
    affine = vol.get_affine()
    data = vol.get_data()

    if args.std is 0:
        print("Compute sigma with piesno")
        sigma = piesno(data, N=1, return_mask=False)
        print("sigma is: ", sigma)
        sigma = np.mean(sigma)
        print("sigma is: ", sigma)

    else:
        print("Sigma is: ", args.std)
        sigma = args.std

    if args.mask is None:
        print("No mask.. you should")
    else:
        print("Mask is: ", args.mask)
        img_mask = nib.load(args.mask)
        mask_t1 = img_mask.get_data()

    img_denoised = nlmeans(data, sigma, mask=mask_t1)

    nib.save(nib.Nifti1Image(img_denoised, affine), filename)
    print("Denoised file was saved as", filename)
Ejemplo n.º 14
0
fetch_sherbrooke_3shell()
img, gtab = read_sherbrooke_3shell()
data = img.get_data()
"""
Now that we have fetched a dataset, we must call PIESNO with the right number
of coils used to acquire this dataset. It is also important to know what
was the parallel reconstruction algorithm used. Here, the data comes from a
GRAPPA reconstruction, was acquired with a 12-elements head coil available on
the Tim Trio Siemens, for which the 12 coil elements are combined into 4 groups
of 3 coil elements each. The signal is therefore received through 4 distinct
groups of receiver channels, yielding N = 4. Had we used a GE acquisition, we
would have used N=1 even if multiple channel coils are used because GE uses a
SENSE reconstruction, which has a Rician noise nature and thus N is always 1.
"""

sigma, mask = piesno(data, N=4, return_mask=True)

axial = data[:, :, data.shape[2] // 2, 0].T
axial_piesno = mask[:, :, data.shape[2] // 2].T

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 2)
ax[0].imshow(axial, cmap='gray', origin='lower')
ax[0].set_title('Axial slice of the b=0 data')
ax[1].imshow(axial_piesno, cmap='gray', origin='lower')
ax[1].set_title('Background voxels from the data')
for a in ax:
    a.set_axis_off()

plt.savefig('piesno.png', bbox_inches='tight')
"""
Ejemplo n.º 15
0
def main():
    parser = buildArgsParser()
    args = parser.parse_args()

    vol = nib.load(args.input)
    data = vol.get_data()
    affine = vol.get_affine()

    if args.mask is None:
        mask = np.ones(data.shape[:-1], dtype=np.bool)
    else:
        mask = nib.load(args.mask).get_data().astype(np.bool)

    N = args.N

    if args.n_cores is None:
        n_cores = cpu_count()
    else:
        if args.n_cores > cpu_count():
            n_cores = cpu_count()
        else:
            n_cores = args.n_cores

    noise_method = args.noise_method
    smooth_method = args.smooth_method
    filename = args.output

    if noise_method == 'noise_map':
        if args.noise_maps is None:
            raise ValueError(
                'You need to supply --noise_map path_to_file to use --noise_est noise_map'
            )

        noise_maps = nib.load(args.noise_maps).get_data()

    # Since negatives are allowed, convert uint to int
    if data.dtype.kind == 'u':
        dtype = data.dtype.name[1:]
    else:
        dtype = data.dtype

    logging.info("Estimating m_hat with method " + smooth_method)

    if smooth_method == 'local_mean':
        m_hat = np.zeros_like(data, dtype=np.float32)
        size = (3, 3, 3)
        k = np.ones(size) / np.sum(size)
        conv_out = np.zeros_like(data[..., 0], dtype=np.float64)

        for idx in range(data.shape[-1]):
            convolve(data[..., idx], k, mode='reflect', output=conv_out)
            m_hat[..., idx] = conv_out

    elif smooth_method == 'nlmeans':
        nlmeans_sigma = estimate_sigma(data)
        m_hat = nlmeans(data, nlmeans_sigma, rician=False, mask=mask)

    elif smooth_method == 'no_smoothing':
        m_hat = np.array(data, copy=True, dtype=np.float32)

    elif smooth_method == 'sh_smooth':
        bvals, bvecs = read_bvals_bvecs(args.bvals, args.bvecs)
        gtab = gradient_table(bvals, bvecs)
        m_hat = sh_smooth(data, gtab, sh_order=4)

    logging.info("Estimating noise with method " + noise_method)

    if noise_method == 'piesno':
        sigma = np.zeros_like(data, dtype=np.float32)
        mask_noise = np.zeros(data.shape[:-1], dtype=np.int16)

        for idx in range(data.shape[-2]):
            logging.info("Now processing slice", idx + 1, "out of",
                         data.shape[-2])
            sigma[..., idx, :], mask_noise[..., idx] = piesno(data[...,
                                                                   idx, :],
                                                              N=N,
                                                              return_mask=True)

        if args.save_piesno_mask is not None:
            nib.save(nib.Nifti1Image(mask_noise.astype(np.int16), affine),
                     args.save_piesno_mask)

    elif noise_method == 'local_std':
        sigma_3D = local_standard_deviation(data, n_cores=n_cores)

        # Compute the corrected value for each 3D volume
        sigma = corrected_sigma(m_hat,
                                np.repeat(sigma_3D[..., None],
                                          data.shape[-1],
                                          axis=-1),
                                np.repeat(mask[..., None],
                                          data.shape[-1],
                                          axis=-1),
                                N,
                                n_cores=n_cores)

    elif noise_method == 'noise_map':

        # Local piesno works on 4D, so we need to broadcast before
        if noise_maps.ndim == 3:
            noise_maps = noise_maps[..., None]

        sigma, mask_noise = local_piesno(noise_maps, N=N, return_mask=True)
        sigma = np.repeat(sigma[..., None], data.shape[-1], axis=-1)

        if args.save_piesno_mask is not None:
            nib.save(nib.Nifti1Image(mask_noise.astype(np.int16), affine),
                     args.save_piesno_mask)

    nib.save(nib.Nifti1Image(sigma, affine), args.sigma)

    logging.info("Now performing stabilisation")

    pool = Pool(processes=n_cores)
    arglist = [(data[..., idx, :], m_hat[..., idx, :],
                np.repeat(mask[..., idx, None], data.shape[-1],
                          axis=-1), sigma[..., idx, :], N_vox)
               for idx, N_vox in zip(range(data.shape[-2]), repeat(N))]

    data_out = pool.map(multiprocess_stabilisation, arglist)
    pool.close()
    pool.join()

    data_stabilized = np.empty(data.shape, dtype=dtype)

    for idx in range(len(data_out)):
        data_stabilized[..., idx, :] = data_out[idx]

    nib.save(nib.Nifti1Image(data_stabilized, affine), filename)
Ejemplo n.º 16
0
def test_piesno():
    # Values taken from hispeed.OptimalPIESNO with the test data
    # in the package computed in matlab
    test_piesno_data = nib.load(dipy.data.get_data("test_piesno")).get_data()
    sigma = piesno(test_piesno_data, N=8, alpha=0.01, l=1, eps=1e-10, return_mask=False)
    assert_almost_equal(sigma, 0.010749458025559)
Ejemplo n.º 17
0
img, gtab = read_sherbrooke_3shell()
data = img.get_data()

"""
Now that we have fetched a dataset, we must call PIESNO with the right number
of coils used to acquire this dataset. It is also important to know what
was the parallel reconstruction algorithm used. Here, the data comes from a
GRAPPA reconstruction, was acquired with a 12-elements head coil available on
the Tim Trio Siemens, for which the 12 coil elements are combined into 4 groups
of 3 coil elements each. The signal is therefore received through 4 distinct
groups of receiver channels, yielding N = 4. Had we used a GE acquisition, we
would have used N=1 even if multiple channel coils are used because GE uses a
SENSE reconstruction, which has a Rician noise nature and thus N is always 1.
"""

sigma, mask = piesno(data, N=4, return_mask=True)

axial = data[:, :, data.shape[2] // 2, 0].T
axial_piesno = mask[:, :, data.shape[2] // 2].T

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 2)
ax[0].imshow(axial, cmap='gray', origin='lower')
ax[0].set_title('Axial slice of the b=0 data')
ax[1].imshow(axial_piesno, cmap='gray', origin='lower')
ax[1].set_title('Background voxels from the data')
for a in ax:
    a.set_axis_off()

plt.savefig('piesno.png', bbox_inches='tight')
Ejemplo n.º 18
0
def getBackgroundIdxUsingPIESNO(data):
    _, mask = piesno(data, N=1, return_mask=True)
    return np.nonzero(mask)