3

I'm actually work on MRI images using Python. The image format is the NIFTI format I get how to visualise slices on x, y or z axe, but now, I want tu use Sobel filtering on each of them and create a new NIFTI image with those slices.

For that:

  • I load the main .nii.gz image (img = nib.load(im_path))
  • I load again the main .nii.gz image with a new name "img_sobel" (img_sobel = nib.load(im_path))
  • Create a loop for each slice
  • Sobel filtering the slice
  • Replace this slice on the corresponding slice of img_sobel ("img_sobel_data[:, :, sl] == np.hypot(sx, sy)")
  • After the loop, save the img_sobel with the name "image_XXX_Sobel"

Using subplot, I see the sobel filtering work on each slice, but it seems the line "img_sobel_data[:, :, sl] == np.hypot(sx, sy)" don't work, why ?

Here's the lopp section :

    # Name the interested data
    img_data = img.get_fdata()
    img_sobel_data = img_sobel.get_fdata()

    header = img.header
    nb_img = header.get_data_shape()
    nb_img_h = nb_img[2] #Hauteur

    for sl in range(0,nb_img_h):
            slice_h = img_data[:, :, sl]
            #Sobel
            sx = ndimage.sobel(slice_h, axis=0, mode='constant')
            sy = ndimage.sobel(slice_h, axis=1, mode='constant')
            sobel_h = np.hypot(sx, sy)

            img_sobel_data[:, :, sl] = sobel_h #Change the image slice to the sobel one
# Save Sobel:
nib.save(img_sobel,imSobel_path)

What's wrong ? Can't we replace an image slice from another one in Python ? Is there a trick to solve this problem ?

Thank you !

EDIT : OK I get a bit more why I can't do taht so easily : I extracted the slices of the NIFTI image, filtered them, but I wasn't change the NIFTI image itself !!! So my question now : How to change the NIFTI image get from img_sobel.get_fdata() ?

Batfly
  • 33
  • 5

1 Answers1

2

simply because you didn't save your img_sobel_data, with affine and header properly, if you want save Nifti image you have to provide header and affine before to save it img_sobel = nib.Nifti1Image(img_sobel_data, affine=img_sobel_affine, header=header) otherwise you can save the image on other formats using cv2 library with cv2.imwrite to save your image in JPG or PNG extension.

#======================================
# Importing Necessary Libs
#======================================
import nibabel as nib
import numpy as np 
from scipy import ndimage, misc
import matplotlib.pyplot as plt
#==============================
img  = nib.load(Nifti_img_path)
img_sobel  = nib.load(Nifti_img_sobel_path)
#==============================
if True: 
    # Name the interested data  
    img_data = img.get_fdata()
    img_sobel_data = img_sobel.get_fdata()
    img_sobel_affine = img_sobel.affine
    header = img.header
    nb_img = header.get_data_shape()
    nb_img_h = nb_img[2] #Hauteur

    for sl in range(0,nb_img_h):
            slice_h = img_data[:, :, sl]
            #Sobel
            sx = ndimage.sobel(slice_h, axis=0, mode='constant')
            sy = ndimage.sobel(slice_h, axis=1, mode='constant')
            sobel_h = np.hypot(sx, sy)

            img_sobel_data[:, :, sl] = sobel_h #Change the image slice to the sobel one
# Save Sobel:
img_sobel = nib.Nifti1Image(img_sobel_data, affine=img_sobel_affine, header=header)
nib.save(img_sobel,imSobel_path)
#==============================
Bilal
  • 3,191
  • 4
  • 21
  • 49
  • Dang ! I tried the Nifti1Image function but I used it so badly I wasn't get any result (blank image). I used the wrong parameter and put it and the wrong place before to give up. Now it's work, there are just one last problem : the first and last image are not filtered correctly, but I think I can remedy that quickly. Thank you ! – Batfly Mar 03 '20 at 10:40
  • you are welcome, `the first and last image are not filtered correctly` if you can explain with code and images I will try to help. – Bilal Mar 03 '20 at 10:47
  • No thank you, it's ok ^^ I correct that: in fact, it's because I do it with 3 loops. slice_h = img_data[:, :, sl] (hight, slice following Z axe), slice_l = img_data[:, sl, :] (long, slices following Y axe) and slice_L = img_data[sl, :, :] (Large, slices following X axe) . I deleted the 2 others loops because they are useless : changing pixels on all slices from one axe is enought to change all Voxels (Voxels are just pixels with volume due to the slices, so no need any "special change" like that...). – Batfly Mar 03 '20 at 13:40