Extract ROI voxels using nilearn's NiftiMasker

Hi all, I’m completely new to nilearn and can’t get nilearn’s NiftiMasker class to work properly according to my needs. I want to extract ROI voxels from a 4D niimg object, where the 4th dimension represents different subjects. I also have one single niimg-object which serves as a template for the mask. I already set up a binary niimg mask object telling which voxels should be ‘cut out’ from each subjects 3D matrix and which can be ‘ignored’. I wrote the following code which solves the problem but is only a temporary solution since I actually wanted to use nilearn’s NiftiMasker (I want to stick as much as possible to nilearn’s build-in functions and want to avoid self-made solutions whenever possible). So this is my working code:

def cut(nifti_imgs,nifti_mask):
    
    # get mask labels
    nifti_mask_data = nifti_mask.get_data()
    
    # set output variable
    # FIXME: It would be better to already set up an 'empty' 4D nifti image object
    #        https://nipy.org/nibabel/reference/nibabel.nifti1.html#nibabel.nifti1.Nifti1Image
    roi_nifti_imgs = list()
    
    # iterate through each subject's 3D array and apply mask
    # FIXME: Is  image.iter_img() the fasted method when iterating over 4D nifti file?
    for img in image.iter_img(nifti_imgs):
        img_data = img.get_data()
        roi_nifti_data = np.where(nifti_mask_data == 1,img_data,0)
        roi_nifti_img = image.new_img_like(img,roi_nifti_data)
        roi_nifti_imgs.append(roi_nifti_img)
    
    # concatente list of 3D objects to one 4D object
    roi_nifti_imgs = image.concat_imgs(roi_nifti_imgs)
    
    return roi_nifti_imgs

I read the article Computing a Region of Interest (ROI) mask manually from nilearn’s User Guide and thought maybe I could use NiftiLabelsMasker like in the article only that in my case I only have a binary iimg mask (instead of ROI labels 1,2,3,…) and the 4th dimension does not represent a time series but different subjects. So I wrote the following code, which doesn’t work but returns a n_subjects * 1 array:

def masker_cut(nifti_imgs,nifti_mask):
    
    # create NiftiLabelsMasker instance and call .fit() method
    # FIXME: Use only needed arguments (masker's job is ONLY to cut out,
    # not to transform data!)
    masker = NiftiLabelsMasker(nifti_mask)
    masker.fit()
    
    roi_nifti_imgs = masker.transform(nifti_imgs)
    
    return roi_nifti_imgs

Did I just make a coding mistake here or am I using the NiftiLabelsMasker class wrong? Is there any other Nifti*Masker class which serves my needs? Any help is much appreciated!

have you tried NiftiMasker?

I would suggest to play with this example. http://nilearn.github.io/auto_examples/04_manipulating_images/plot_nifti_simple.html#sphx-glr-auto-examples-04-manipulating-images-plot-nifti-simple-py

NiftiMasker has an argument called mask_img.

Initialize the object

masker = NiftiMasker(mask_img=nifti_mask)

Use for loop to extract values from ROI on each subject.
signals = masker.fit_transform(img)

HTH

This will not work since the NiftiMasker instance asks for a 4D-array. So the use of a for-loop is not necessary in this case.

Thank you all for your quick answers. jeromedocks provided the right solution. NiftLabelsMasker was simply not the right solution for my case since it doesn’t ‘cut out’ voxels but returns a 2-dimensional array (number of scans, number of elements), where each element represents one ‘signal’ calculated from a 3D-array. It’s still not clear for me how this signal is computed (just a simple average of all voxels?) but this is another question which is not related to my post. NiftiMasker does the right job.