OscarPellicer / prostate_lesion_detection

Model for the detection, segmentation, and classification of prostate lesions from mpMRI, using ProstateX data and Retina U-Net
MIT License
61 stars 27 forks source link

Classification between benign and malignant #1

Open DrraBL opened 3 years ago

DrraBL commented 3 years ago

Hi @OscarPellicer First of all thank you for your great work. I am working on prostate cancer classification and I am new in this field and i will be thankful if you can help. I want to discriminate the prostate between benign and malignant not detect the gleason grade group, How I can use your code to do that because in your work u did not detect the benign class? Looking hearing from you.

Kind regards,

OscarPellicer commented 3 years ago

Thank you for your interest.

The model does detect the benign class. It classifies each detection in Gleason Grade Groups {0,1,2, 3+}, where GGG0 / GGG1 are typically considered benign, and GGG2 / GGG3+ malignant.

If you want to use it to perform prostate-level classification (aka patient-level), you can do as I explained in Section 2.5 of the paper:

Only predicted Bounding Boxes (BBs) with a predicted GGG equal or above the chosen significance threshold (e.g.: GGG≥2) were considered, and the rest were completely ignored. (...) For patient-level evaluation, the patient score was computed as the highest score from any BB predicted for the patient.

This is all already implemented in the repo.

DrraBL commented 3 years ago

Hi @OscarPellicer thank for your previous reply. but your idea is not clear for me. anyway i will explain you my idea firstly i want to extract radiomic features and then use these features to classify between benign and malignant. I want to use ProstateX dataset, as you used this dataset, I guess that you have idea about the files which included in. so my questions are:

  1. which file represents the segmented files, i mean the true masks to use them with the images in order to extract the features?

  2. if i will use these features to classify the lesion later, so do you think that i need the use lesion mask or prostate mask?

  3. I tried to convert dicom to nrrd via 3d slicer, so for each patient i got multiple nrrd files refer to t2-tra, t2-sag, t2-cor, ADC,... in my case i want to use t2-tra, just i take the t2-tra.nrrd files with the true mask or what i can do to just take the t2 image?

regards,

OscarPellicer commented 3 years ago

Hi @dardaa, I will try to answer your questions:

  1. The prostate masks are in ProstateX_masks.zip, at the root of this repository. The lesions masks must be created automatically by running the first Notebook. They are not perfect though, although for the purposes of feature extraction they might be sufficient.
  2. I do not know what it is exactly that you want to achieve. In general, if you intend to peform per-lesion classification, you will need to use the lesion masks, and if you want to perform whole prostate classification you will need the prostate masks.
  3. I do not understand your question. If you ask about processing medical images and you are using Python, I suggest you take a look at SimpleITK, which allows reading and converting among different formats. You can also take a look at Pydicom if you need to read the DICOM tags of the images.
DrraBL commented 3 years ago

HI @OscarPellicer thank you for your response let's focus in my first request: I will attach to you the structure of each patient in prostatex dataset prostatex you can check there's 10 subfolders refers to different acquisition strategy, in my case I case i want just to use the t2-transversal images. after converting I obtained for each subfolders a nrrd file(see image bellow), so my question here is, i need just to use t2-tra.nrrd ? Screenshot from 2021-05-19 01-15-37

let's say that i took prostatex-0000-t2-tra.nrrd file for patient with ID 0, so the true mask correspondent to this file is prostatex-0000.nrrd in the ProstateX_masks.zip? could you please tell how you got the prostate masks? I appreciate your help.

OscarPellicer commented 3 years ago

Is it as you say. The masks were generated using an automated segmentation model I had previously developed: https://www.mdpi.com/2076-3417/11/2/844

DrraBL commented 3 years ago

Hi @OscarPellicer I appreciate your help sorry if disturb you a lot, but there's two files t2-tse-tra , which one i use? I am trying to reproduce your result, and i met error about 'params.pth', your checkpoints folders does not contains this file however in the predictor.py script uses it. can you tell me from where can i get this file. regards,

OscarPellicer commented 3 years ago

If you look at the folders, there is only one t2-tse-tra, so I don't know how the other one appears, or how you process the data. I suggest visualizing the images in case of doubt, since most times it is obvious which is which just by looking at them. Also, you could ask the people who created that ProstateX dataset if you have doubts about it.

The params.pth files are in the repo at: prostate_lesion_detection/MDT_ProstateX/experiments/exp0/fold_{0,1,2,3,4}/[N]_best_checkpoint/params.pth

DrraBL commented 3 years ago

Thank you for your reply. just to confirm you that after downloading the repository, the folder prostate_lesion_detection/MDT_ProstateX/experiments/exp0/fold_{0,1,2,3,4}/[N]_best_checkpoint/ contains two files as shown in the attached image: Screenshot from 2021-05-21 15-46-13 I will download the missing files from repository again. I appreciate your help.

kind regards,

OscarPellicer commented 3 years ago

That is extrange. I have checked again and the files you are missing are indeed in the repo, so re-downloading might be a good idea.

DrraBL commented 3 years ago

Hi @OscarPellicer I tied to run the code on google colab but I met the following error. bug1

i tried to use some solutions from github such as : import sys sys.setrecursionlimit(100000) please let me know if you have idea.

OscarPellicer commented 3 years ago

Just from the image it is very difficult to tell where the error might be...

You should focus on the piece of code that fails: p_df = p_df[p_df.pid.isin(subset_pids)] and try to work out what p_df contains, what subset_pids contains, and whether both are sensible. Maybe it is a bug with pandas, but I doubt so. More likely your inputs are not as expected.

Please bear in mind that I did not test the Repo on Colab, so it might missbehave in some unexpected way. For inference you should be able to run the CNN at a reasonable speed even without a GPU, so I would suggest starting from a local installation, and once everything is up and running, moving it to Colab.

DrraBL commented 2 years ago

Hi Oscar Many thanks for your previous replies. I wanted to use retina unet to detect the region of interest from prostate MRI but I want to know how can I get the results as medical files such as nrrd or dicom?

OscarPellicer commented 2 years ago

I am not really sure what you want to achieve, can you give a specific example?

Retina UNet outputs detection boxes (with labels and scores associated with them), and segmentations. The boxes cannot really be exported as a medical image because they are just boxes, and the segmentations could be easily exported, but they are meaningless without the boxes...

If you just want to save the results plots, you can save a slice by providing the save_as = 'whatever.png' parameter to plot

DrraBL commented 2 years ago

I know that the outputs of retina Unet are detection boxes with their scores. I don't need the boxes but my question here is if I use retina Unet to detect the region of interest and then save each slice result separately as you mentioned above then it's possible to merge all the slices to get a medical image?

OscarPellicer commented 2 years ago

Ok, I get what you need now! It was already possible to build a volumetric medical image for use outside Jupyter (in Slicer, ImageJ, etc.), but it was a bit cumbersome and had to be done manually. In any case, since this might be generally useful, I have included the option to save as a medical image in plot_lib. Now there is a new parameter to plot: save_as_volume='volume.nii.gz'

You first must update plot_lib:

cd PATH_TO_LOCAL_PLOT_LIB_REPO
git pull https://github.com/OscarPellicer/plot_lib.git

Then, you can see examples of usage in the Saving images section of the example Notebook: https://github.com/OscarPellicer/plot_lib/blob/main/Introduction%20to%20plot_lib.ipynb

Hope it helps!

Abbas009 commented 2 years ago

Hello Dear Oscar, Thank you for your great work. I want to ask if I want to classify only ProsatateX-2 patients (112) lesions and have to perform Gleason grading into 1,2,3,4,5. Then what changes do I have to make? Or where have to make changes? Have you done any experiment like that, if yes how much Kappa value have you got? Thanks

OscarPellicer commented 2 years ago

Hi,

I want to ask if I want to classify only ProsatateX-2 patients (112) lesions and have to perform Gleason grading into 1,2,3,4,5. Then what changes do I have to make? Or where have to make changes? Have you done any experiment like that, if yes how much Kappa value have you got?

I tried to classify into all those classes initially, but it is very unlikely to work because it is a very unbalanced problem, with very few patients in classes 4 and 5. I have no kappa value though.

Regarding what changes to make, you should go to the config file and alter the lines:

#Custom dict preprocessing function to transform classes 10,1 -> 0, 2,3,4,5 -> 1, 20 -> 20
#Please note that class 20 is a very special class for which bce loss is masked!
#correspondance_dict= {0:0, 10:0, 1:0, 2:1, 3:1, 4:1, 5:1, 20:20}
correspondance_dict= {0:0, 10:0, 1:1, 2:2, 3:3, 4:3, 5:3, 20:20} 
def modify_class_target(class_targets):
    return [correspondance_dict[target] for target in class_targets]
self.modify_class_target_fn = modify_class_target

This function is then used by the data loader to build the final classes.

In general, you should take a look at all instances of that file where class is mentioned, so that you can understand everything that is going on.

Regards, Oscar