I’m trying to write a function that moves the values of all the voxels in the left hemisphere to the right hemisphere.
nilearn
has a swap_img_hemispheres
function which swaps the left hemisphere voxels to the right hemisphere, but also moves the right hemisphere voxels to the left hemisphere.
Is there a way to move just the voxel values in one of the hemispheres?
If what you want is to mirror the left hemisphere you could try concatenating your image (Ll,Rr) with its swapped version (Rl,Lr), such that you’d have (Rl, Lr, Ll, Rr), then extracting the middle image (Lr, Ll) and cirshifting it (Ll, Lr). Not the most computationally efficient solution, but requires 0 effort.
from nilearn import image
import numpy as np
# Load image
img = image.load_img("data3d.nii.gz")
# Reorder is called implicitly by swap_img_hemispheres, so we want to do the same.
data_rllr = np.stack([image.swap_img_hemispheres(img).get_data(),
image.reorder_img(img).get_data()], 0)
# Get the ll data and circshift it to account for positioning in the FOV.
data_ll = data_rllr[data_rllr.shape[0]//4:data_rllr.shape[0]//4+img.shape[0], :, :]
data_ll = np.roll(data_ll, data_ll.shape[0]//2, 0)
# Place it into a new NifTI object
img_ll = image.new_img_like(img, data_ll, img.affine, copy_header=True)
I suppose this should be robust to even/odd number of voxels, but haven’t tested.
Thanks @dangom, your code did not give any errors, but the final image looks exactly the same as the original image. Maybe I’m wrong but it seems that there is something missing in this command, isn’t there?:
data_ll = data_rllr[data_rllr.shape[0]//4:data_rllr.shape[0]//4+img.shape[0], :, :]
yes, it should’ve been np.concatenate
instead of np.stack
.
Again, I did not test this, so if you use this in real applications make sure to test it on some toy data with 1s and 0s.
from nilearn import image
import numpy as np
def duplicate_img_left_hemisphere(path):
# Load image
img = image.load_img(path)
# Reorder is called implicitly by swap_img_hemispheres, so we want to do the same.
data_rllr = np.concatenate(
[image.swap_img_hemispheres(img).get_data(),
image.reorder_img(img).get_data()],
0,
)
# Get the ll data and circshift it to account for positioning in the FOV.
data_ll = data_rllr[
data_rllr.shape[0] // 4 : data_rllr.shape[0] // 4 + img.shape[0], :, :
]
data_ll = np.roll(data_ll, data_ll.shape[0] // 2, 0)
# Place it into a new NifTI object
img_ll = image.new_img_like(img, data_ll, img.affine, copy_header=True)
return img_ll
Yes - thanks @dangom I just tried your solution with binary images and it works! It copies all the 1s in the left hemisphere to the right hemisphere. However how can I change the values in the left hemisphere to 0 after they have been copied to the right hemisphere, so that only the right hemisphere has 1s?
Thanks!
I don’t see how this would differ from swap_img_hemispheres
.
@dangom, say my binary image looks like this:
Right Left
1 0 0 1 0 0 0 1
0 0 1 0 0 1 0 0
0 0 0 0 0 1 1 1
swap_img_hemispheres
does this:
Right Left
0 0 0 1 1 0 0 1
0 1 0 0 0 0 1 0
0 1 1 1 0 0 0 0
your code does this:
Right Left
1 0 0 1 0 0 0 1
0 1 1 0 0 1 0 0
0 1 1 1 0 1 1 1
and I’m looking for a way to do this:
Right Left
1 0 0 1 0 0 0 0
0 1 1 0 0 0 0 0
0 1 1 1 0 0 0 0
Sorry I misunderstood @dangom’s code. What it does is it creates a mirror image of the left hemisphere in the right hemisphere.
So if this is the original data:
Right Left
1 0 0 1 0 0 0 1
0 0 1 0 0 1 0 0
0 0 0 0 0 1 1 1
dangom’s code does this:
Right Left
1 0 0 0 0 0 0 1
0 0 1 0 0 1 0 0
1 1 1 0 0 1 1 1
How can I change the duplicate_img_left_hemisphere
function above such that all left voxels equal zero?, like this:
Right Left
1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
1 1 1 0 0 0 0 0