New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adaptive Denoising #1066

Merged
merged 47 commits into from Aug 10, 2016

Conversation

Projects
None yet
5 participants
@riddhishb
Contributor

riddhishb commented May 28, 2016

This branch is for adaptive denoising, currently includes

  1. nlmeans_block.pyx
    for adding a blockwise averaging approach in nlmeans
  2. wavelet.py in dipy.core
  3. ascm.py
    Adaptive soft coefficient matching based denoising

I have also added the keyword to toggle between current voxelwise implementation of nlmeans and the proposed blockwise one.

I am yet to add tests and some examples.

@riddhishb

This comment has been minimized.

Contributor

riddhishb commented May 31, 2016

@Garyfallidis Please have a look at this.

OUTPUT:
y - array x will be shifed by m samples down
along dimension d

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

Hi @riddhishb. Please correct docstring to fit the style of our other docstrings.

def permutationInverse(perm):
'''
Function generating inverse of the permutation

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

permutation_inverse no capitals in function names. Also fix docstring style and explain parameter.

af(:, 2) - highpass filter
d - dimension of filtering (d = 1, 2 or 3)
OUTPUT:
lo, hi - lowpass, highpass subbands

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

Same here!

y = sfb3D_A(lo, hi, sf, d);
sf - synthesis filters
d - dimension of filtering

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

same here

sfi - synthesis filters for dimension i
OUPUT:
y - output array

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

same here

afi(:, 2) - highpass filter
OUTPUT:
lo - lowpass subband
hi[d], d = 1..7 - highpass subbands

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

same here

af - analysis filters
OUTPUT:
w - cell array of wavelet coefficients

This comment has been minimized.

@Garyfallidis
sf - synthesis filters
OUTPUT:
y - output array

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

Same! Correct docstrings everywhere in this file.

def ascm(ima, fimau, fimao, h):
'''
Adaptive Soft Coefficient Matching

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

Start from the first line of docstring.

Combines two filtered 3D-images at different resolutions and the orginal
image. Returns the resulting combined image.
Parameters

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

Leave a line between description and parameters.

if sigX < 0:
T = abs(w3[0][i]).max()
else:
T = (h * h) / (sigX**0.5)

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

add spaces between operators

that explain the rician noise. Note: In P. Coupe et al. the
rician noise was simulated as sqrt((f+x)^2 + (y)^2) where f is
the pixel value and x and y are independent realizations of a
random variable with Normal distribution, with mean=0 and

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

Add a line space before References.

References
----------
[1] "Impact of Rician Adapted Non-Local Means Filtering on HARDI"

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

author names first

np.double(arr),
patch_radius,
block_radius,
sigma[0,0,0],

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

pep8 spaces

else:
for i in range(arr.shape[-1]):
denoised_arr[...,
i] = nlmeans_3d(arr[...,

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

This indentation here can be improved. Too many lines used.

@@ -0,0 +1,358 @@
cimport cython

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

This file seems not optimized properly.
Use

cython -a nlmeans_block.pyx
google-chrome nlmeans_block.html

to see which areas are not optimized.
Look for functions inside loops that are still yellow.

def _average_block(double[:, :, :] ima, int x, int y, int z,
double[:, :, :] average, double weight):

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

Add docstrings in cython functions.

return ss / 27.0
def _local_variance(double[:, :, :] ima, double mean, int x, int y, int z):

This comment has been minimized.

@Garyfallidis

Garyfallidis Jun 17, 2016

Member

no docstrings in most functions of this file.

den_final = np.array(ascm(data, den_small, den_large, sigma[0]))
print("total time", time() - t)

This comment has been minimized.

@RafaelNH

RafaelNH Aug 8, 2016

Contributor

I think this timer is useless because it depends as fast users run the lines of the example

print("Saving the entire denoised output in denoised_ascm.nii.gz")
"""
The comparision between the ascm output and the non-local-means.

This comment has been minimized.

@RafaelNH

RafaelNH Aug 8, 2016

Contributor

The examples should be a smooth continuous flow and simple explanation of the technique. Remove this title is breaking the flow...

riddhishb added some commits Aug 8, 2016

@coveralls

This comment has been minimized.

coveralls commented Aug 8, 2016

Coverage Status

Changes Unknown when pulling c3df90d on riddhishb:adap_denoise into * on nipy:master*.

@coveralls

This comment has been minimized.

coveralls commented Aug 8, 2016

Coverage Status

Changes Unknown when pulling c3df90d on riddhishb:adap_denoise into * on nipy:master*.

t = time()
"""
The ``ascm`` function takes two denoised inputs, one more smooth than the

This comment has been minimized.

@RafaelNH

RafaelNH Aug 8, 2016

Contributor

First sentence has repeated information.

"""
The ``ascm`` function takes two denoised inputs, one more smooth than the
other, for generating these inputs we will use the ``non_local_means``
denoising. In order to call ``non_local_means`` first you need to estimate

This comment has been minimized.

@RafaelNH

RafaelNH Aug 8, 2016

Contributor

You can just say: 'In order to compute the two required pre-denoised versions of the data, first you need to estimate the ...'

riddhishb added some commits Aug 8, 2016

@coveralls

This comment has been minimized.

coveralls commented Aug 8, 2016

Coverage Status

Changes Unknown when pulling 05dbed8 on riddhishb:adap_denoise into * on nipy:master*.

@coveralls

This comment has been minimized.

coveralls commented Aug 8, 2016

Coverage Status

Changes Unknown when pulling 05dbed8 on riddhishb:adap_denoise into * on nipy:master*.

The adaptive soft coefficient matching (ASCM) as described in [Coupe11]_ is a
improved extension of non-local means (NLMEANS) denoising. ASCM gives a better
denoised images from two standard non-local means denoised versions of the
original data with different degrees sharp feature preserved. Here, one

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

Replace this with '... original data with different degrees of sharpness. Here, one... '

less smoothing.
This way ASCM gives us a well denoised output while preserving the sharpness
of the image features, which is the primary goal in any denoising algorithm.

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

I would remove ', which is the primary goal in any denoising algorithm' - we are stating the obvious!

"""
Non-local means with a smaller patch size which implies less smoothing, more
sharpness

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

How about? - 'To produce a denoised version with sharper features preserved, we process the original data using the non-local means filter with a smaller patch size'

rician=True)
"""
Non-local means with larger patch size which implies more smoothing, less

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

'For the denoised version of the original data that implies more smoothing, we run the non-local means with a larger patch size'. Does this sound better?

print("total time", time() - t)
"""
Plot the axial slice of the data, it's denoised output and the residual

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

To access the quality of this denoising procedure, we plot the an axial slice of the original data, it's denoised output and residuals.

print("Saving the entire denoised output in denoised_ascm.nii.gz")
"""

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

Add here a comment about the figure - what is the take home message of this figure? Perhaps mention that from the uniform noise profile of the residual one can see that data is being denoised without the lost of image features.

print("Saving the entire denoised output in denoised_ascm.nii.gz")
"""
We would like to compare the outputs of the ``non_local_means`` (both with the

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

'For comparison propose we also plot the outputs of the ''non_local_means'' (both with ... ) together with the ASCM output'

and how the corresponding DIPY function ``adaptive_soft_matching``. We observe
that combining the information of two pre-denoised versions of the raw data,
ASCM outperforms standard non-local means in supressing noise and preserving
feature sharpness

This comment has been minimized.

@RafaelNH

RafaelNH Aug 9, 2016

Contributor

replace this paragraph with: 'For the above figure, we can observe that the information of two pre-denoised versions of the raw data, ASCM outperforms standard non-local means in supressing noise and preserving feature sharpness.'

This in my opinion is enough for the last paragraph of the example, and will make the example easier to read.

@Garyfallidis Garyfallidis changed the title from WIP: Adaptive Denoising to Adaptive Denoising Aug 9, 2016

riddhishb added some commits Aug 9, 2016

@coveralls

This comment has been minimized.

coveralls commented Aug 9, 2016

Coverage Status

Changes Unknown when pulling 13da3b9 on riddhishb:adap_denoise into * on nipy:master*.

@coveralls

This comment has been minimized.

coveralls commented Aug 9, 2016

Coverage Status

Changes Unknown when pulling 13da3b9 on riddhishb:adap_denoise into * on nipy:master*.

@RafaelNH

This comment has been minimized.

Contributor

RafaelNH commented Aug 9, 2016

I haven't any further comments on the documentation - for me this can be merged! Please let me know asap if anyone have any comments to this PR. We are planning to merge this at the end of this day!

@RafaelNH RafaelNH merged commit b0b74d6 into nipy:master Aug 10, 2016

4 checks passed

codecov/patch 94.46% of diff hit (target 81.02%)
Details
codecov/project 81.02% (+0.17%) compared to e309c15
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
coverage/coveralls First build on master at 83.086%
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment