Example #1
0
def fmri_bmsk_workflow(name='fMRIBrainMask', use_bet=False):
    """Comute brain mask of an fmri dataset"""

    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']),
                        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']),
                         name='outputnode')

    if not use_bet:
        afni_msk = pe.Node(afni.Automask(
            outputtype='NIFTI_GZ'), name='afni_msk')

        # Connect brain mask extraction
        workflow.connect([
            (inputnode, afni_msk, [('in_file', 'in_file')]),
            (afni_msk, outputnode, [('out_file', 'out_file')])
        ])

    else:
        from nipype.interfaces.fsl import BET, ErodeImage
        bet_msk = pe.Node(BET(mask=True, functional=True), name='bet_msk')
        erode = pe.Node(ErodeImage(kernel_shape='box', kernel_size=1.0),
                        name='erode')

        # Connect brain mask extraction
        workflow.connect([
            (inputnode, bet_msk, [('in_file', 'in_file')]),
            (bet_msk, erode, [('mask_file', 'in_file')]),
            (erode, outputnode, [('out_file', 'out_file')])
        ])

    return workflow
Example #2
0
def fmri_bmsk_workflow(name='fMRIBrainMask', use_bet=False):
    """
    Computes a brain mask for the input :abbr:`fMRI (functional MRI)`
    dataset

    .. workflow::

      from mriqc.workflows.functional import fmri_bmsk_workflow
      wf = fmri_bmsk_workflow()


    """

    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']),
                        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']),
                         name='outputnode')

    if not use_bet:
        afni_msk = pe.Node(afni.Automask(outputtype='NIFTI_GZ'),
                           name='afni_msk')

        # Connect brain mask extraction
        workflow.connect([(inputnode, afni_msk, [('in_file', 'in_file')]),
                          (afni_msk, outputnode, [('out_file', 'out_file')])])

    else:
        from nipype.interfaces.fsl import BET, ErodeImage
        bet_msk = pe.Node(BET(mask=True, functional=True), name='bet_msk')
        erode = pe.Node(ErodeImage(), name='erode')

        # Connect brain mask extraction
        workflow.connect([(inputnode, bet_msk, [('in_file', 'in_file')]),
                          (bet_msk, erode, [('mask_file', 'in_file')]),
                          (erode, outputnode, [('out_file', 'out_file')])])

    return workflow
Example #3
0
def skullstrip_epi(input,
                   pathFSL=None,
                   roi_size=5,
                   scale=0.75,
                   nerode=2,
                   ndilate=1,
                   savemask=False,
                   cleanup=True):
    """
    Skullstrip input volume by defining an intensity threshold from the inner of the brain volume. 
    From a defined mid-point, a brain mask is grown inside the brain. A binary filling holes 
    algorithm is applied. To reduce remaining skull within the brain mask, the mask is eroded and 
    dilated several times.    
    Inputs:
        *input: input file.
        *pathFSL: path to FSL environment.
        *roi_size: size of cubic roi for image intensity threshold
        *scale: scale image intensity threshold
        *nerode: number of eroding iterations
        *ndilate: number of dilating iterations
        *savemask: save mask time series (boolean).
        *cleanup: delete intermediate files after running.
    
    created by Daniel Haenelt
    Date created: 06-11-2018             
    Last modified: 01-02-2019
    """
    import os
    import numpy as np
    import nibabel as nb
    from nipype.interfaces.fsl import ErodeImage, DilateImage
    from scipy.ndimage.morphology import binary_fill_holes

    # prepare path and filename
    path = os.path.split(input)[0]
    file = os.path.split(input)[1]

    # load data
    data_img = nb.load(os.path.join(path, file))
    data_array = data_img.get_data()

    # calculate mean intensity
    data_mean = data_array.mean()

    # get point within the brain
    inds = np.transpose(np.nonzero(data_array > data_mean))
    x_mean = np.uint8(np.round((np.max(inds[:, 0]) + np.min(inds[:, 0])) / 2))
    y_mean = np.uint8(np.round((np.max(inds[:, 1]) + np.min(inds[:, 1])) / 2))
    z_mean = np.uint8(np.round((np.max(inds[:, 2]) + np.min(inds[:, 2])) / 2))

    # initialise mask
    mask_array = np.zeros_like(data_array)
    mask_temp_array = np.zeros_like(data_array)
    mask_array[x_mean, y_mean, z_mean] = 1
    mask_temp_array[x_mean, y_mean, z_mean] = 1

    # compute threshold
    roi = np.zeros((2 * roi_size, 2 * roi_size, 2 * roi_size), dtype='uint16')
    roi = data_array[
        np.uint8(np.round(x_mean - roi_size /
                          2)):np.uint8(np.round(x_mean + roi_size - 1 / 2)),
        np.uint8(np.round(y_mean - roi_size /
                          2)):np.uint8(np.round(y_mean + roi_size - 1 / 2)),
        np.uint8(np.round(z_mean - roi_size /
                          2)):np.uint8(np.round(z_mean + roi_size - 1 / 2))]
    roi_mean = roi.mean()

    # grow mask
    while True:

        coords = np.transpose(np.nonzero(mask_array > 0))

        coords = coords[coords[:, 0] > 0, :]
        coords = coords[coords[:, 1] > 0, :]
        coords = coords[coords[:, 2] > 0, :]
        coords = coords[coords[:, 0] < np.size(data_array, 0) - 1]
        coords = coords[coords[:, 1] < np.size(data_array, 1) - 1]
        coords = coords[coords[:, 2] < np.size(data_array, 2) - 1]

        # calculate neighbour coordinate
        mask_temp_array[coords[:, 0] - 1, coords[:, 1], coords[:, 2]] = 1
        mask_temp_array[coords[:, 0], coords[:, 1] - 1, coords[:, 2]] = 1
        mask_temp_array[coords[:, 0], coords[:, 1], coords[:, 2] - 1] = 1
        mask_temp_array[coords[:, 0] + 1, coords[:, 1], coords[:, 2]] = 1
        mask_temp_array[coords[:, 0], coords[:, 1] + 1, coords[:, 2]] = 1
        mask_temp_array[coords[:, 0], coords[:, 1], coords[:, 2] + 1] = 1

        # delete all old mask elements
        mask_temp_array = mask_temp_array - mask_array
        mask_temp_array[data_array < scale * roi_mean] = 0

        # reinitialise mask_temp
        mask_array = mask_array + mask_temp_array

        # check break condition
        coords = np.transpose(np.nonzero(mask_temp_array == True))
        if len(coords) == 0:
            break

    # flood filling on brain mask
    mask_array = binary_fill_holes(mask_array, structure=np.ones((2, 2, 2)))

    # write mask (intermediate)
    newimg = nb.Nifti1Image(mask_array, data_img.affine, data_img.header)
    newimg.header['dim'][0] = 3
    nb.save(newimg, os.path.join(path, 'temp.nii'))

    # erode mask
    for i in range(nerode):
        erode = ErodeImage()
        #erode.inputs.environ['PATH'] = pathFSL
        erode.inputs.in_file = os.path.join(path, 'temp.nii')
        erode.inputs.output_type = 'NIFTI'
        erode.inputs.out_file = os.path.join(path, 'temp.nii')
        erode.run()

    # dilate mask
    for i in range(ndilate):
        dilate = DilateImage()
        #dilate.inputs.environ['PATH'] = pathFSL
        dilate.inputs.in_file = os.path.join(path, 'temp.nii')
        dilate.inputs.operation = 'mean'
        dilate.inputs.output_type = 'NIFTI'
        dilate.inputs.out_file = os.path.join(path, 'temp.nii')
        dilate.run()

    # load final mask
    temp_img = nb.load(os.path.join(path, 'temp.nii'))
    mask_array = temp_img.get_data()

    # write masked image
    data_masked_array = data_array * mask_array
    output = nb.Nifti1Image(data_masked_array, data_img.affine,
                            data_img.header)
    nb.save(output, os.path.join(path, 'p' + file))

    # write final output
    if savemask is True:
        newimg = nb.Nifti1Image(mask_array, data_img.affine, data_img.header)
        nb.save(newimg, os.path.join(path, 'mask_' + file))

    # clear output
    if cleanup is True:
        os.remove(os.path.join(path, 'temp.nii'))