Skip to content

Commit 6dab71d

Browse files
committed
added denoise workflow
1 parent 70993fc commit 6dab71d

File tree

4 files changed

+129
-2
lines changed

4 files changed

+129
-2
lines changed

nipype/workflows/dmri/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import camino, mrtrix, fsl
1+
import camino, mrtrix, fsl, dipy
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# coding: utf-8
2+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3+
# vi: set ft=python sts=4 ts=4 sw=4 et:
4+
5+
from denoise import nlmeans_pipeline

nipype/workflows/dmri/dipy/denoise.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# coding: utf-8
2+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3+
# vi: set ft=python sts=4 ts=4 sw=4 et:
4+
5+
import nipype.pipeline.engine as pe
6+
import nipype.interfaces.utility as niu
7+
from nipype.interfaces import fsl
8+
from nipype.interfaces import dipy
9+
10+
11+
def nlmeans_pipeline(name='Denoise',
12+
params={'patch_radius': 1, 'block_radius': 5}):
13+
"""
14+
Workflow that performs nlmeans denoising
15+
16+
Example
17+
-------
18+
19+
>>> from nipype.workflows.dmri.dipy.denoise import nlmeans_pipeline
20+
>>> denoise = nlmeans_pipeline()
21+
>>> denoise.inputs.inputnode.in_file = 'diffusion.nii'
22+
>>> denoise.inputs.inputnode.in_mask = 'mask.nii'
23+
>>> denoise.run() # doctest: +SKIP
24+
25+
26+
"""
27+
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_mask']),
28+
name='inputnode')
29+
outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']),
30+
name='outputnode')
31+
32+
nmask = pe.Node(niu.Function(input_names=['in_file', 'in_mask'],
33+
output_names=['out_file'], function=bg_mask),
34+
name='NoiseMsk')
35+
nlmeans = pe.Node(dipy.Denoise(**params), name='NLMeans')
36+
37+
wf = pe.Workflow(name=name)
38+
wf.connect([
39+
(inputnode, nmask, [('in_file', 'in_file'),
40+
('in_mask', 'in_mask')])
41+
,(inputnode, nlmeans, [('in_file', 'in_file'),
42+
('in_mask', 'in_mask')])
43+
,(nmask, nlmeans, [('out_file', 'noise_mask')])
44+
,(nlmeans, outputnode, [('out_file', 'out_file')])
45+
])
46+
return wf
47+
48+
49+
def csf_mask(in_file, in_mask, out_file=None):
50+
"""
51+
Artesanal mask of csf in T2w-like images
52+
"""
53+
import nibabel as nb
54+
import numpy as np
55+
from scipy.ndimage import binary_erosion, binary_opening, label
56+
import scipy.ndimage as nd
57+
import os.path as op
58+
59+
if out_file is None:
60+
fname,ext = op.splitext(op.basename(in_file))
61+
if ext == ".gz":
62+
fname,ext2 = op.splitext(fname)
63+
ext = ext2 + ext
64+
out_file = op.abspath("%s_csfmask%s" % (fname, ext))
65+
66+
im = nb.load(in_file)
67+
hdr = im.get_header().copy()
68+
hdr.set_data_dtype(np.uint8)
69+
hdr.set_xyzt_units('mm')
70+
imdata = im.get_data()
71+
msk = nb.load(in_mask).get_data()
72+
msk = binary_erosion(msk,
73+
structure=np.ones((15, 15, 10))).astype(np.uint8)
74+
thres = np.percentile(imdata[msk > 0].reshape(-1), 90.0)
75+
imdata[imdata < thres] = 0
76+
imdata = imdata * msk
77+
imdata[imdata > 0] = 1
78+
imdata = binary_opening(imdata,
79+
structure=np.ones((2, 2, 2))).astype(np.uint8)
80+
81+
label_im, nb_labels = label(imdata)
82+
sizes = nd.sum(imdata, label_im, range(nb_labels + 1))
83+
mask_size = sizes != sizes.max()
84+
remove_pixel = mask_size[label_im]
85+
label_im[remove_pixel] = 0
86+
label_im[label_im > 0] = 1
87+
nb.Nifti1Image(label_im.astype(np.uint8),
88+
im.get_affine(), hdr).to_filename(out_file)
89+
return out_file
90+
91+
92+
def bg_mask(in_file, in_mask, out_file=None):
93+
"""
94+
Rough mask of background from brain masks
95+
"""
96+
import nibabel as nb
97+
import numpy as np
98+
from scipy.ndimage import binary_dilation
99+
import scipy.ndimage as nd
100+
import os.path as op
101+
102+
if out_file is None:
103+
fname,ext = op.splitext(op.basename(in_file))
104+
if ext == ".gz":
105+
fname,ext2 = op.splitext(fname)
106+
ext = ext2 + ext
107+
out_file = op.abspath("%s_bgmask%s" % (fname, ext))
108+
109+
im = nb.load(in_file)
110+
hdr = im.get_header().copy()
111+
hdr.set_data_dtype(np.uint8)
112+
hdr.set_xyzt_units('mm')
113+
imdata = im.get_data()
114+
msk = nb.load(in_mask).get_data()
115+
msk = 1 - binary_dilation(msk,
116+
structure=np.ones((20, 20, 20)))
117+
nb.Nifti1Image(msk.astype(np.uint8),
118+
im.get_affine(), hdr).to_filename(out_file)
119+
return out_file

nipype/workflows/dmri/setup.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
22
# vi: set ft=python sts=4 ts=4 sw=4 et:
3-
def configuration(parent_package='',top_path=None):
3+
4+
5+
def configuration(parent_package='', top_path=None):
46
from numpy.distutils.misc_util import Configuration
57

68
config = Configuration('dmri', parent_package, top_path)
@@ -9,6 +11,7 @@ def configuration(parent_package='',top_path=None):
911
config.add_subpackage('mrtrix')
1012
config.add_subpackage('fsl')
1113
config.add_subpackage('connectivity')
14+
config.add_subpackage('dipy')
1215

1316
return config
1417

0 commit comments

Comments
 (0)