Giter VIP home page Giter VIP logo

liver-segmentation-using-monai-and-pytorch's Introduction

GitHub issues GitHub stars GitHub license GitHub forks PyPI - Python Version YouTube Video Views GitHub watchers

Liver Segmentation Using Monai and PyTorch

You'll find all the Python files you need to accomplish liver segmentation with Monai and PyTorch in this repo, and you can use the same code to segment other organs as well.

Link to the original course here.

Output image

So do this project, you will find some scripts that I wrote by myself and others that I took from Monai's tutorials. For this reason you need to take a look to their original repo and website to get more information.

Cloning the repo

You can start by cloning this repo in your wordspace and then start playing with the function to make your project done.

git clone https://github.com/amine0110/Liver-Segmentation-Using-Monai-and-PyTorch
cd ./Liver-Segmentation-Using-Monai-and-PyTorch

Packages that need to be installed:

pip install monai
pip install -r requirements.txt

Showing a patient from the dataset

Some of the most common queries I had while utilizing medical imaging were regarding how to present a patient. To address this, I created explicit scripts for how to show a patient from the training and testing datasets, which you can see here.

def show_patient(data, SLICE_NUMBER=1, train=True, test=False):
    """
    This function is to show one patient from your datasets, so that you can si if the it is okay or you need 
    to change/delete something.
    `data`: this parameter should take the patients from the data loader, which means you need to can the function
    prepare first and apply the transforms that you want after that pass it to this function so that you visualize 
    the patient with the transforms that you want.
    `SLICE_NUMBER`: this parameter will take the slice number that you want to display/show
    `train`: this parameter is to say that you want to display a patient from the training data (by default it is true)
    `test`: this parameter is to say that you want to display a patient from the testing patients.
    """

    check_patient_train, check_patient_test = data

    view_train_patient = first(check_patient_train)
    view_test_patient = first(check_patient_test)

    
    if train:
        plt.figure("Visualization Train", (12, 6))
        plt.subplot(1, 2, 1)
        plt.title(f"vol {SLICE_NUMBER}")
        plt.imshow(view_train_patient["vol"][0, 0, :, :, SLICE_NUMBER], cmap="gray")

        plt.subplot(1, 2, 2)
        plt.title(f"seg {SLICE_NUMBER}")
        plt.imshow(view_train_patient["seg"][0, 0, :, :, SLICE_NUMBER])
        plt.show()
    
    if test:
        plt.figure("Visualization Test", (12, 6))
        plt.subplot(1, 2, 1)
        plt.title(f"vol {SLICE_NUMBER}")
        plt.imshow(view_test_patient["vol"][0, 0, :, :, SLICE_NUMBER], cmap="gray")

        plt.subplot(1, 2, 2)
        plt.title(f"seg {SLICE_NUMBER}")
        plt.imshow(view_test_patient["seg"][0, 0, :, :, SLICE_NUMBER])
        plt.show()

But before calling this function, you need to do the preprocess to your data, in fact this function will help you to visualize your patients after applying the different transforms so that you will know if you need to change some parameters or not. The function that does the preprocess can be found in the preprocess.py file and in that file you will find the function prepare() that you can use for the preprocess.

Training

After understanding how to do the preprocess you can start import the 3D Unet from monai and defining the parameters of the model (dimensions, input channels, output channels...).

model = UNet(
    dimensions=3,
    in_channels=1,
    out_channels=2,
    channels=(16, 32, 64, 128, 256), 
    strides=(2, 2, 2, 2),
    num_res_units=2,
    norm=Norm.BATCH,
).to(device)

And to run the code, you can use the scripts train.py that will call the train function that I have created using the same principal used in Monai's tutorials.

Testing the model

To test the model, there is the jupyter notebook testing.ipynb file that contains the different codes that you need. You will find the part to plot the training/testing graphs about the loss and the dice coefficient and of course you will find the the part to show the results of one of the test data to see the output of your model.

Output image


Before using the code, I recommend that you watch my course, in which I explain everything in this repo, or at the very least read my blog entries, in which I explain how to use the various scripts so that you don't get confused.

You can read about the tutorial in my blog post series starting by this one.

Conversion tools

For the different preparations that I talked about in the course/blogs I have create a simple GUI that help you to do the conversion in a few clicks, please see more information at this link.

154864750-c55a3129-67c7-438a-8549-e2c45c433048

๐Ÿ“ฉ Newsletter

Stay up-to-date on the latest in computer vision and medical imaging! Subscribe to my newsletter now for insights and analysis on the cutting-edge developments in this exciting field.

https://pycad.co/join-us/

๐Ÿ†• NEW

Learn how to effectively manage and process DICOM files in Python with our comprehensive course, designed to equip you with the skills and knowledge you need to succeed.

https://www.learn.pycad.co/course/dicom-simplified

liver-segmentation-using-monai-and-pytorch's People

Contributors

amine0110 avatar karthikdani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

liver-segmentation-using-monai-and-pytorch's Issues

[Bug] ZeroDivisionError

In utilities.py, at line no. 45 variable name train_step is equal to 0.
While running the code, got a ZeroDivisionError because of line no. 75 which goes as: train_epoch_loss/=train_step.
While running the code, got a ZeroDivisionError because of line no. 80 which goes as: epoch_metric_train/=train_step.

In utilities.py at line no. 93 variable name test_step is equal to 0.
While running the code, got a ZeroDivisionError because of line no. 112 which goes as: test_epoch_loss/=test_step.
While running the code, got a ZeroDivisionError because of line no. 117 which goes as: epoch_metric_test/=test_step.

def train ZeroDivision Error

Hi Amine,
Thanks for the liver segmentation code in Monai it gave me great insights. I am however, experiencing an error in def train, where:

---> 79 train_epoch_loss /= train_step
ZeroDivisionError: float division by zero

Can you please help. Thanks!
Jon

Model Liver

Hi,
could you please share the trained model?

repeat bug in group creation

Hi amine,
I am afraid the create_groups function in preprocess.py has a bug.
It just start from the same slice index when it create a sub-folder.
It might be fixed like this,

num_slices = 65
for patient in glob(input_path+"/*"):
    patient_name = os.path.basename(patient)
    slice_list = sorted(glob(patient+"/*"))
    num_folders = int(len(slice_list)/num_slices)
    for i in range(num_folders):
        output_path_name = os.path.join(output_path, patient_name + f"_{i}")
        os.mkdir(output_path_name)
        for file in slice_list[num_slices*i:num_slices*(i+1)]:
            shutil.copy(file, output_path_name)

[Question] Training and Testing

Hello, @amine0110. I'm a beginner in AI. How did you separated testing and training dataset from the dataset you referred in your Youtube tutorial. If you could explain which files you entered in testing and training part would be great. Thanks in advance

Error on creating Nifti from Dicom_groups

Hi,
I followed your youtube video on converting equal amount of dicom_groups into Nifti but came into the following error: (I've made sure that each folder in dicom_groups only contain 65 images and nothing less or more).

in_path = '/Users/Task03_Liver/dicom_file/images'
out_path = '/Users/Task03_Liver/dicom_groups/images'

from glob import glob
import shutil
import os
import dicom2nifti
import nibabel as nib
import numpy as np

for patient in glob(in_path + '/*'):
    patient_name = os.path.basename(os.path.normpath(patient))
    number_folders = int(len(glob(patient+'/*'))/64)
    
    for i in range(number_folders):
        output_path_name = os.path.join(out_path, patient_name + '_' + str(i))
        os.mkdir(output_path_name)
        for i, file in enumerate(glob(patient+'/*')):
            if i == 64 + 1:
                break
            shutil.move(file, output_path_name)

in_path_images = '/Users/Task03_Liver/dicom_groups/images/*'
in_path_labels = '/Users/Task03_Liver/dicom_groups/labels/*'
out_path_images = '/Users/Task03_Liver/nifti_files/images'
out_path_labels = '/Users/Task03_Liver/nifti_files/labels'

list_images = glob(in_path_images)
list_labels = glob(in_path_labels)

for patient in list_images:
    patient_name = os.path.basename(os.path.normpath(patient))
    dicom2nifti.dicom_series_to_nifti(patient, os.path.join(out_path_images, patient_name + '.nii.gz'))```

---------------------------------------------------------------------------
ConversionValidationError                 Traceback (most recent call last)
Cell In[62], line 3
      1 for patient in list_images:
      2     patient_name = os.path.basename(os.path.normpath(patient))
----> 3     dicom2nifti.dicom_series_to_nifti(patient, os.path.join(out_path_images, patient_name + '.nii.gz'))

File [~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/convert_dicom.py:77](https://file+.vscode-resource.vscode-cdn.net/Users/~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/convert_dicom.py:77), in dicom_series_to_nifti(original_dicom_directory, output_file, reorient_nifti)
     73     shutil.copytree(original_dicom_directory, dicom_directory)
     75     dicom_input = common.read_dicom_directory(dicom_directory)
---> 77     return dicom_array_to_nifti(dicom_input, output_file, reorient_nifti)
     79 except AttributeError as exception:
     80     raise exception

File [~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/convert_dicom.py:117](https://file+.vscode-resource.vscode-cdn.net/Users/~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/convert_dicom.py:117), in dicom_array_to_nifti(dicom_list, output_file, reorient_nifti)
    114 vendor = _get_vendor(dicom_list)
    116 if vendor == Vendor.GENERIC:
--> 117     results = convert_generic.dicom_to_nifti(dicom_list, output_file)
    118 elif vendor == Vendor.SIEMENS:
    119     results = convert_siemens.dicom_to_nifti(dicom_list, output_file)

File [~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/convert_generic.py:132](https://file+.vscode-resource.vscode-cdn.net/Users/~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/convert_generic.py:132), in dicom_to_nifti(dicom_input, output_file)
    129 slice_increment_inconsistent = False
    130 if settings.validate_slice_increment:
    131     # validate that all slices have a consistent slice increment
--> 132     common.validate_slice_increment(dicom_input)
    133 elif common.is_slice_increment_inconsistent(dicom_input):
    134     slice_increment_inconsistent = True

File [~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/common.py:890](https://file+.vscode-resource.vscode-cdn.net/Users/~/miniconda3/envs/monai/lib/python3.10/site-packages/dicom2nifti/common.py:890), in validate_slice_increment(dicoms)
    888         logger.warning('Instance Number: %s' % dicom_.InstanceNumber)
    889     logger.warning('---------------------------------------------------------')
--> 890     raise ConversionValidationError('SLICE_INCREMENT_INCONSISTENT')
    891 previous_image_position = current_image_position

ConversionValidationError: SLICE_INCREMENT_INCONSISTENT

UNet error

Traceback (most recent call last):
File "d:\liver_seg_github\Liver-Segmentation-Using-Monai-and-PyTorch\train.py", line 15, in
model = UNet(
^^^^^
TypeError: UNet.init() got an unexpected keyword argument 'dimensions'

test_outputs = test_outputs > 0.53

hey dude,

thanks for your awesome tutorials.

I use some of your code and everything works great. However, the only thing I did not understand, is using test_outputs = test_outputs > 0.53 in your testing.ipynb. I know, why you use it, to just plot the elements inside the array of predictions above a threshold, but why 0.53, and not, say, 0.5?

Cheers!

Evaluation using different metrics

Thanks dear for your support

Could you please include evaluation using different metrics for example: hausdorff and IoU?

I tried by writing the following codes:

HD= compute_hausdorff_distance(test_outputs,test_label)

IoU = MeanIoU(test_outputs, test_label)

But I was not able to print the values. The Monai documentation is not clear for me.

Thanks

Different Output

Screenshot 2024-01-25 153623

i follow the same process and the same data but it gives me different output.
and also can you tell me which data you used for training and testing and what is the meaning of epoch.

AddChannel removed

Thank you for the complete ML segmentation code. Compiling the preprocess.py gave me:

ImportError: cannot import name 'AddChanneld' from 'monai.transforms'.

It seems AddChannel has been removed in recent Monai. How to adjust the code you provided for the removed AddChannel?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.