Compare two NIfTI images: correlation and histograms

I have two NIfTI images that are magnetic field maps (3D) of the same brain obtained from two different pipelines. They are essentially supposed to be identical but they are not. Let’s denote them as ‘ref_img.nii.gz’ and ‘src_img.nii.gz’.

I would like to compare them and find what should be done on the src_img to make it look like the ref_img. I thought I’d first compare the two images and I learned that Nistats has a module called “nistats.reporting.compare_niimgs” that may serve the purpose. However, as I pass the central slices of the two images-- to pass 2D images-- I have not been successful to fix the errors I get as follows:

TypeError: Cannot slice image objects; consider using img.slicer[slice] to generate a sliced image (see documentation for caveats) or slicing image array data with img.dataobj[slice] or img.get_fdata()[slice]

As one of the arguments of compare_niimgs, one has to pass a NiftiMasker. I also don’t know how to obtain this masker. Is this masker the same as the brain mask I can obtain for my images simply by finding their nonzero matrix elements of the images data?

Any help is much appreciated.

Try Learning about nilearn module in order to create a NiftiMasker and also slicing can be done easily using nilearn

Hi MSherafti,

NiftiMasker is a class from Nilearn that is able to mask and unmask (given a specific input mask) your data of interest. If the non-zero elements in your matrix effectively mask your image data, then this can be used as input to NiftiMasker.

The below example from the Nilearn website should help get you started.

https://nilearn.github.io/auto_examples/04_manipulating_images/plot_nifti_simple.html#sphx-glr-auto-examples-04-manipulating-images-plot-nifti-simple-py

Alternatlvely, just code the correlation and overlapping histograms yourself. :slight_smile:

Thank you “petergodin” and “sreenu” for the quick replies.
I have been working on Niftimasker example for the past few hours and understood how it works. However, when I pass any form of the masker or its attributes to the function “compare_niimgs” as the third argument, I get either some errors or it takes forever to spit any output.

In particular, suppose the “masker” is given by:

masker=NiftiMasker(mask_img=MyMask_img, mask_strategy=‘background’, memory_level=1, verbose=0, reports=True),

where “MyMask_img” is a nifti image created off of the ref_img. When I execute:

masker.fit(path2ref_img)
report = masker.generate_report()
report

The NiftiMasker image is created as expected containing my ref_img overlaid by the mask image, MyMask_img, the same as in the Niftimasker example.

Nevertheless, when I pass the above “masker” alone as in

compare_niimgs([src_img], [ref_img], masker, plot_hist=True)

I get the following error:

ValueError: It seems that NiftiMasker has not been fitted. You must call fit() before calling transform().

And, if “masker.fit(path2ref_img)” is passed as in

compare_niimgs([src_img], [ref_img], masker.fit(path2ref_img), plot_hist=True)
it takes forever and I don’t get any outcome:

Please help.

Thanks again.

This looks like a bug. Can you open an issue on Nistats ? And can you provide the images ?
Thx,
Bertrand

You should try to fit the masker beforehand.

masker=NiftiMasker(mask_img=MyMask_img, mask_strategy=‘background’, memory_level=1, verbose=0, reports=True)
masker.fit(path2ref_img)
compare_niimgs(src_img, ref_img, masker, plot_hist=True)

Thank you for your comment. Actually, I did fit the masker before passing it to
compare_niimgs; it takes forever and nothing is computed and I have to restart the Jupyter kernel to kill the execution.

Thank you for your comment. I have never reported anything like this before; could you please let me know what the steps are?

Sorry about the delay, hope this was solved.

If not, could you open an issue here : https://github.com/nistats/nistats/issues

In it please include a minimal script that triggers this error for you, and precise which version you are using.
If possible, share also the images used so that we can run exactly your script. (or a minimal subset of images that trigger the error)

Thank you very much,