Skip to content

Commit 3874713

Browse files
committed
histogram equalization before hmc
1 parent 3b6961d commit 3874713

File tree

2 files changed

+57
-13
lines changed

2 files changed

+57
-13
lines changed

nipype/workflows/dmri/preprocess/epi.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def hmc_pipeline(name='motion_correct'):
229229
them to one reference image. Finally, the `b`-matrix is rotated accordingly [Leemans09]_
230230
making use of the rotation matrix obtained by FLIRT.
231231
232-
Search angles have been limited to 3.5 degrees, based on results in [Yendiki13]_.
232+
Search angles have been limited to 4 degrees, based on results in [Yendiki13]_.
233233
234234
A list of rigid transformation matrices is provided, so that transforms can be
235235
chained. This is useful to correct for artifacts with only one interpolation process (as
@@ -276,18 +276,24 @@ def hmc_pipeline(name='motion_correct'):
276276
outputnode.out_xfms - list of transformation matrices
277277
278278
"""
279-
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'ref_num', 'in_bvec',
280-
'in_mask']), name='inputnode')
279+
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'ref_num',
280+
'in_bvec', 'in_mask']), name='inputnode')
281281
split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs')
282282
pick_ref = pe.Node(niu.Select(), name='Pick_b0')
283+
enhb0 = pe.Node(niu.Function(input_names=['in_file'],
284+
output_names=['out_file'], function=enhance),
285+
name='B0Equalize')
286+
enhdw = pe.MapNode(niu.Function(input_names=['in_file'],
287+
output_names=['out_file'], function=enhance),
288+
name='DWEqualize', iterfield=['in_file'])
283289
flirt = pe.MapNode(fsl.FLIRT(interp='spline', cost='normmi',
284-
cost_func = 'normmi', dof=6, bins=64, save_log=True,
285-
searchr_x=[-4,4], searchr_y=[-4,4], searchr_z=[-4,4],
290+
cost_func='normmi', dof=6, bins=64, save_log=True,
291+
searchr_x=[-4, 4], searchr_y=[-4, 4], searchr_z=[-4, 4],
286292
fine_search=1, coarse_search=10, padding_size=1),
287293
name='CoRegistration', iterfield=['in_file'])
288294
rot_bvec = pe.Node(niu.Function(input_names=['in_bvec', 'in_matrix'],
289-
output_names=['out_file'], function=rotate_bvecs),
290-
name='Rotate_Bvec')
295+
output_names=['out_file'], function=rotate_bvecs),
296+
name='Rotate_Bvec')
291297
thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'],
292298
name='RemoveNegative')
293299
merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs')
@@ -301,10 +307,12 @@ def hmc_pipeline(name='motion_correct'):
301307
,(split, pick_ref, [('out_files', 'inlist')])
302308
,(inputnode, pick_ref, [(('ref_num', _checkrnum), 'index')])
303309
,(inputnode, flirt, [('in_mask', 'ref_weight')])
304-
,(split, flirt, [('out_files', 'in_file')])
310+
,(pick_ref, enhb0, [('out', 'in_file')])
311+
,(split, enhdw, [('out_files', 'in_file')])
312+
,(enhb0, flirt, [('out_file', 'reference')])
313+
,(enhdw, flirt, [('out_file', 'in_file')])
305314
,(inputnode, rot_bvec, [('in_bvec', 'in_bvec')])
306315
,(flirt, rot_bvec, [('out_matrix_file', 'in_matrix')])
307-
,(pick_ref, flirt, [('out', 'reference')])
308316
,(flirt, thres, [('out_file', 'in_file')])
309317
,(thres, merge, [('out_file', 'in_files')])
310318
,(merge, outputnode, [('merged_file', 'out_file')])

nipype/workflows/dmri/preprocess/utils.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
# vi: set ft=python sts=4 ts=4 sw=4 et:
55
# @Author: oesteban
66
# @Date: 2014-08-30 10:53:13
7-
# @Last Modified by: Oscar Esteban
8-
# @Last Modified time: 2014-09-02 19:52:57
7+
# @Last Modified by: oesteban
8+
# @Last Modified time: 2014-09-03 18:03:47
99
import nipype.pipeline.engine as pe
1010
import nipype.interfaces.utility as niu
1111
from nipype.interfaces import fsl
1212

13+
1314
def cleanup_edge_pipeline(name='Cleanup'):
1415
"""
1516
Perform some de-spiking filtering to clean up the edge of the fieldmap
@@ -20,8 +21,8 @@ def cleanup_edge_pipeline(name='Cleanup'):
2021
outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']),
2122
name='outputnode')
2223

23-
fugue = pe.Node(fsl.FUGUE(save_fmap=True, despike_2dfilter=True, despike_threshold=2.1),
24-
name='Despike')
24+
fugue = pe.Node(fsl.FUGUE(save_fmap=True, despike_2dfilter=True,
25+
despike_threshold=2.1), name='Despike')
2526
erode = pe.Node(fsl.maths.MathsCommand(nan2zeros=True,
2627
args='-kernel 2D -ero'), name='MskErode')
2728
newmsk = pe.Node(fsl.MultiImageMaths(op_string='-sub %s -thr 0.5 -bin'),
@@ -364,6 +365,7 @@ def siemens2rads(in_file, out_file=None):
364365
nb.Nifti1Image(data, im.get_affine(), hdr).to_filename(out_file)
365366
return out_file
366367

368+
367369
def rads2radsec(in_file, delta_te, out_file=None):
368370
"""
369371
Converts input phase difference map to rads
@@ -483,3 +485,37 @@ def copy_hdr(in_file, in_file_hdr, out_file=None):
483485
imref.get_affine(), imref.get_header())
484486
nii.to_filename(out_file)
485487
return out_file
488+
489+
490+
def enhance(in_file, clip_limit=0.015, in_mask=None, out_file=None):
491+
import numpy as np
492+
import nibabel as nb
493+
import os.path as op
494+
from skimage import exposure, img_as_int
495+
496+
if out_file is None:
497+
fname, fext = op.splitext(op.basename(in_file))
498+
if fext == '.gz':
499+
fname, _ = op.splitext(fname)
500+
out_file = op.abspath('./%s_enh.nii.gz' % fname)
501+
502+
im = nb.load(in_file)
503+
imdata = im.get_data()
504+
imshape = im.get_shape()
505+
506+
if in_mask is not None:
507+
msk = nb.load(in_mask).get_data()
508+
msk[msk > 0] = 1
509+
msk[msk < 1] = 0
510+
imdata = imdata * msk
511+
512+
immin = imdata.min()
513+
imdata = (imdata - immin).astype(np.uint16)
514+
515+
adapted = exposure.equalize_adapthist(imdata.reshape(imshape[0], -1),
516+
clip_limit=clip_limit)
517+
518+
nb.Nifti1Image(adapted.reshape(imshape), im.get_affine(),
519+
im.get_header()).to_filename(out_file)
520+
521+
return out_file

0 commit comments

Comments
 (0)