4646 --output <path/to/denoised_dwi.nii.gz> \\
4747 --b0-denoise
4848
49+ # With Gibbs ringing removal
50+ micaflow denoise \\
51+ --input <path/to/dwi.nii.gz> \\
52+ --bval <path/to/dwi.bval> \\
53+ --bvec <path/to/dwi.bvec> \\
54+ --output <path/to/denoised_dwi.nii.gz> \\
55+ --gibbs
56+
4957Python API Usage:
5058----------------
5159>>> from micaflow.scripts.denoise import run_denoise
6775... output="denoised_dwi.nii.gz",
6876... b0_denoising=True
6977... )
78+ >>>
79+ >>> # With Gibbs ringing removal
80+ >>> output = run_denoise(
81+ ... moving="raw_dwi.nii.gz",
82+ ... moving_bval="dwi.bval",
83+ ... moving_bvec="dwi.bvec",
84+ ... output="denoised_dwi.nii.gz",
85+ ... gibbs=True
86+ ... )
7087
7188Pipeline Integration:
7289--------------------
118135import os
119136import numpy as np
120137from dipy .denoise .patch2self import patch2self
138+ from dipy .denoise .gibbs import gibbs_removal
121139from dipy .io .gradients import read_bvals_bvecs
122140from colorama import init , Fore , Style
123141
@@ -158,6 +176,8 @@ def print_help_message():
158176 { CYAN } { BOLD } ─────────────────── OPTIONAL ARGUMENTS ───────────────────{ RESET }
159177 { YELLOW } --b0-denoise{ RESET } : Denoise b0 volumes separately (default: False)
160178 { MAGENTA } Experimental - not recommended for most cases{ RESET }
179+ { YELLOW } --gibbs{ RESET } : Apply Gibbs ringing removal after denoising
180+ { YELLOW } --threads{ RESET } : Number of threads for Gibbs removal (default: 1)
161181
162182 { CYAN } { BOLD } ──────────────────── EXAMPLE USAGE ──────────────────────{ RESET }
163183
@@ -176,6 +196,14 @@ def print_help_message():
176196 { YELLOW } --output{ RESET } denoised_dwi.nii.gz \\
177197 { YELLOW } --b0-denoise{ RESET }
178198
199+ { BLUE } # With Gibbs ringing removal{ RESET }
200+ micaflow denoise \\
201+ { YELLOW } --input{ RESET } raw_dwi.nii.gz \\
202+ { YELLOW } --bval{ RESET } dwi.bval \\
203+ { YELLOW } --bvec{ RESET } dwi.bvec \\
204+ { YELLOW } --output{ RESET } denoised_dwi.nii.gz \\
205+ { YELLOW } --gibbs{ RESET }
206+
179207 { CYAN } { BOLD } ────────────────── PATCH2SELF ALGORITHM ──────────────────{ RESET }
180208
181209 { GREEN } How it works:{ RESET }
@@ -226,7 +254,7 @@ def print_help_message():
226254 print (help_text )
227255
228256
229- def run_denoise (moving , moving_bval , moving_bvec , output , b0_denoising = False ):
257+ def run_denoise (moving , moving_bval , moving_bvec , output , b0_denoising = False , gibbs = False , threads = 1 ):
230258 """
231259 Denoise diffusion-weighted images using the Patch2Self algorithm.
232260
@@ -251,6 +279,10 @@ def run_denoise(moving, moving_bval, moving_bvec, output, b0_denoising=False):
251279 b0_denoising : bool, optional
252280 If True, denoise b0 volumes separately. Default: False.
253281 Standard practice is to exclude b0 volumes from denoising.
282+ gibbs : bool, optional
283+ If True, apply Gibbs ringing removal after denoising. Default: False.
284+ threads : int, optional
285+ Number of threads to use for Gibbs ringing removal. Default: 1.
254286
255287 Returns
256288 -------
@@ -293,6 +325,15 @@ def run_denoise(moving, moving_bval, moving_bvec, output, b0_denoising=False):
293325 ... output="denoised_dwi.nii.gz",
294326 ... b0_denoising=True
295327 ... )
328+ >>>
329+ >>> # With Gibbs ringing removal
330+ >>> output = run_denoise(
331+ ... moving="raw_dwi.nii.gz",
332+ ... moving_bval="dwi.bval",
333+ ... moving_bvec="dwi.bvec",
334+ ... output="denoised_dwi.nii.gz",
335+ ... gibbs=True
336+ ... )
296337 """
297338 # Validate input files exist
298339 for filepath , name in [(moving , "Input DWI" ),
@@ -334,7 +375,18 @@ def run_denoise(moving, moving_bval, moving_bvec, output, b0_denoising=False):
334375 b0_threshold = 50 ,
335376 b0_denoising = b0_denoising ,
336377 )
378+ env = os .environ .copy ()
379+ env ["OPENBLAS_NUM_THREADS" ] = "1"
380+ env ["OMP_NUM_THREADS" ] = "1"
381+ env ["MKL_NUM_THREADS" ] = "1"
382+ env ["VECLIB_MAXIMUM_THREADS" ] = "1"
383+ env ["NUMEXPR_NUM_THREADS" ] = "1"
384+ os .environ .update (env )
337385
386+ if gibbs :
387+ print (f"\n { CYAN } Applying Gibbs ringing removal...{ RESET } " )
388+ gibbs_removal (denoised , slice_axis = 2 , n_points = 3 , inplace = True , num_processes = threads )
389+
338390 print (f"\n { CYAN } Saving denoised image...{ RESET } " )
339391 nib .save (nib .Nifti1Image (denoised , moving_image .affine ), output )
340392
@@ -380,6 +432,17 @@ def run_denoise(moving, moving_bval, moving_bvec, output, b0_denoising=False):
380432 action = 'store_true' ,
381433 help = "Denoise b0 volumes separately (experimental, default: False)."
382434 )
435+ parser .add_argument (
436+ "--gibbs" ,
437+ action = 'store_true' ,
438+ help = "Apply Gibbs ringing removal after denoising."
439+ )
440+ parser .add_argument (
441+ "--threads" ,
442+ type = int ,
443+ default = 1 ,
444+ help = "Number of threads for Gibbs removal (default: 1)."
445+ )
383446
384447 args = parser .parse_args ()
385448
@@ -389,7 +452,9 @@ def run_denoise(moving, moving_bval, moving_bvec, output, b0_denoising=False):
389452 args .bval ,
390453 args .bvec ,
391454 args .output ,
392- args .b0_denoise
455+ args .b0_denoise ,
456+ args .gibbs ,
457+ args .threads
393458 )
394459
395460 print (f"\n { GREEN } { BOLD } Denoising successfully completed!{ RESET } " )
0 commit comments