-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from ivadomed/ws/fill-csf-fix
Add script to fill CSF seg for canal
- Loading branch information
Showing
3 changed files
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Installation | ||
Pour utiliser le code de segmentation du canal spinal à partir des segmentations de la moelle et du CSF il est nécessaire d'installer les librairies utilisées. la ligne qui permet d'installer ces librairie est incluse dans celles pour cloner le Github. | ||
Ensuite, il faut cloner le Github à l'aide de la suite de commande suivante : | ||
~~~ | ||
git clone https://github.com/ivadomed/model-csf-seg.git | ||
cd model-csg-seg | ||
pip install -r requirements.txt | ||
~~~ | ||
|
||
# Fonctionnement | ||
À partir de la segmentation de la moelle, le centre de masse est déterminé pour chaque tranche transversale. | ||
- Si il n'y as pas de segmentation du CSF (le CSF n'apparait pas sur l'image), on ne remplace pas l'image. | ||
- Si il n'y as pas de segmentation de la moelle, on met l'image à 0. | ||
- Si le CSF et la moelle on des segmentations sur la tranche, un floodfill est fait à partir du centre de masse déterminé plus haut. | ||
- Le code évalue ensuite si l'image est pleine de 1 (région non fermée lors du floodfill) | ||
- Si l'image est pleine de 1, on reprend l'image de base et on fait une fermeture. | ||
- Le fait de faire la fermeture sur certaines images ne semble pas causée d'ajout de bruit à l'extérieur du CSF selon ce que j'ai observé. | ||
|
||
# Utilisation | ||
Le code prend en entrée 3 arguments | ||
* `-i`: Segmentation du CSF (.nii.gz) | ||
|
||
* `-s`: Segmentation de la moelle épinière (.nii.gz) | ||
|
||
* `-o` Le nom que vous souhaiter donner au fichier (.nii.gz) | ||
|
||
Voici donc un exemple de commande pour utiliser la fonction : | ||
~~~ | ||
python3 fill-csf.py -i <CSF seg> -s <spinal cord seg> -o <output> | ||
~~~ | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#Authors : William Sirois | ||
|
||
# For usage, type: python fill-csf.py -h or in WSL python3 fill-csf.py -h | ||
#J'importe ce dont j'ai besoin | ||
import nibabel as nib | ||
import cv2 as cv | ||
from skimage.morphology import disk | ||
from skimage.segmentation import flood_fill | ||
import scipy as sc | ||
import numpy as np | ||
import argparse | ||
def get_parser(): | ||
parser = argparse.ArgumentParser( | ||
description="Close the segmentation of the CSF to get the segmentation of the canal." ) | ||
parser.add_argument('-i', dest='CSF_seg', required = True, type=str, | ||
help="Input segmentation of the CSF.") | ||
parser.add_argument('-o', dest='Output_name', required = True, type=str, | ||
help="Ouput image name.") | ||
parser.add_argument('-s', dest='Cord_seg', required = True, type=str, | ||
help="Segmentation of the spinal cord ") | ||
|
||
return parser | ||
|
||
def main() : | ||
|
||
parser = get_parser() | ||
args = parser.parse_args() | ||
|
||
#Fonction pour sauvegarder fournis par Sandrine | ||
def save_Nifti1(data, original_image, filename): | ||
empty_header = nib.Nifti1Header() | ||
image = nib.Nifti1Image(data, original_image.affine, empty_header) | ||
nib.save(image, filename) | ||
|
||
#Je load l'image | ||
moelle = nib.load(args.Cord_seg) | ||
moelle_np = moelle.get_fdata() | ||
img = nib.load(args.CSF_seg) | ||
img_np = img.get_fdata() | ||
|
||
#Je copie l'image pour avoir l'original pour la sauvegarder à la fin | ||
img_b = img_np.copy() | ||
moelle_b = moelle_np.copy() | ||
#Image qui sera remplie (besoin pour éviter les floodfill quand ce n'est pas fermé) | ||
img_fill = img_b.copy() | ||
|
||
#Méthode du floodfill avec le centre de masse | ||
imagenbr = img_b.shape[2]#Je prend le nombre de coupe transversale | ||
slice = 0 | ||
h,w = img_b[:, :, 1].shape | ||
|
||
while slice < imagenbr : #J'itère sur les images de coupe | ||
if np.sum(img_b[:,:,slice] == 1) == 0 :#Si il n'y as pas de segmentation sur le csf on ne change rien | ||
img_fill[:, :, slice] = img_b[:, :, slice] | ||
|
||
elif np.sum(moelle_b[:,:,slice] == 1) == 0:#Si il n'y as pas de segmentation sur la moelle je ne change rien et je retire la segmentation du csf | ||
img_fill[:, :, slice] = 0 | ||
|
||
else : | ||
cmmoelle = (sc.ndimage.center_of_mass(moelle_b[:, :, slice])) | ||
cmmoelle = list(cmmoelle) | ||
cmmoelle[0] = int(cmmoelle[0]) | ||
cmmoelle[1] = int(cmmoelle[1]) | ||
img_fill[:,:,slice] = flood_fill(img_fill[:,:,slice], (cmmoelle[0],cmmoelle[1]), 1) | ||
|
||
if np.sum(img_fill[:,:,slice] == 1) == (h*w): #Si ma forme n'est pas fermée je reprend l'image de base et je fais une fermeture | ||
img_fill[:, :, slice] = cv.morphologyEx(img_b[:,:,slice], cv.MORPH_CLOSE,disk(5)) | ||
|
||
slice = slice+1 #Je passe à la prochaine slice | ||
|
||
#Je sauvegarde l'image(Je ne sais pas comment renommer mes images seulement une façon qui ressemble à la votre) | ||
save_Nifti1(img_fill, img, args.Output_name) | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = get_parser() | ||
args = parser.parse_args() | ||
main() | ||
print(f'Segmentation realised and saved in {args.Output_name}') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
nibabel | ||
argparse | ||
opencv-python | ||
scikit-image |