AIM-Harvard / pyradiomics

Open-source python package for the extraction of Radiomics features from 2D and 3D images and binary masks. Support: https://discourse.slicer.org/c/community/radiomics
http://pyradiomics.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.14k stars 493 forks source link

2D-feature extraction #242

Closed HIN0209 closed 5 years ago

HIN0209 commented 7 years ago

In FAQs/"What modalities does PyRadiomics support?", 2D-feature extraction was explained as follows: 3D or slice: Although PyRadiomics supports single slice (2D) feature extraction, the input is still required to have 3 dimensions (where in case of 2D, a dimension may be of size 1). http://pyradiomics.readthedocs.io/en/latest/faq.html

Could someone describe more clearly what needs to be done? I plan to extract texture features from a single ultrasound image and its mask (directly from jpg or tiff format).

fedorov commented 7 years ago

@HIN0209 it should "just work" automatically. When your input is a 2d image, it should be read as a 3d image with the 3rd dimension size 1.

HIN0209 commented 7 years ago

Thank you for the reply. So far, it did not work.

Here are how I did. (1) convert a tif image to the nrrd format by slicer (2) The dimension of the nrrd mask file was confirmed as (580,420,1) (as suggested here. https://groups.google.com/forum/#!topic/pyradiomics/ThUaJz9Mzto) (3) "pyradiomics Path/to/inputFile Path/to/maskFile" caused the following error: pyradiomics:error:unrecognized arguments: Path/to/maskFile.nrrd

Is this error anything to do with 2D mask or an incorrect nrdd file created by slicer?

JoostJM commented 7 years ago

@HIN0209, @fedorov, I think that if you load a .jpg of a .tiff image with SimpleITK.ReadImage(), it will create a truly 2D image object (i.e. only 2 dimensions). PyRadiomics does not accept this. You can check the number and size of the dimensions by calling GetSize() on the image object (which is returned by SimpleITK.ReadImage()).

@fedorov, do you know of a SimpleITK Image filter to expand dims? Otherwise it would be possible through the numpy array:

import SimpleITK as sitk
import numpy as np
im = sitk.ReadImage('path/to/image.jpg')
im_arr = sitk.GetArrayFromImage(im)
im_arr = np.expand_dims(im_arr, axis=0)
im3d = sitk.GetImageFromArray(im_arr)

However, note that with .jpg, no information is present on voxel spacing, direction, origin, etc. Therefore, no shape descriptors should be calculated. Also, this is not tested and not standard use of PyRadiomics, so exceptions are possible. If you receive errors, please report them so we can look at potentially fixing them.

JoostJM commented 7 years ago

@HIN0209, what does the "pyradiomics --help" show as output? specifically the "usage" part. It appears to be a problem in the argument parsing.

Some possible causes:

HIN0209 commented 7 years ago

Thanks. pyradiomics --help returned the following: Usage: pyradiomics image mask [Options]

JoostJM commented 7 years ago

Does the script work when using in combination with a testcase and mask (contained in the "data" directory)?

HIN0209 commented 7 years ago

It works completely fine with the combination of brain1_image and brain1_label in the provided data folder.

JoostJM commented 7 years ago

@HIN0209 try enclosing the path in quotes

HIN0209 commented 7 years ago

Yes, I put my own files separated from where pyradiomics was located. Then, I moved my own image and mask files to the pyradiomics/data folder, the following was shown.

C:\Users\NAME>pyradiomics C:\pyradiomics\data\10_1.nrrd C:\pyradiomics\data\10_1_mask.nrrd FEATURE EXTRACTION FAILED Traceback (most recent call last): File "c:\users\NAME\anaconda3\lib\site-packages\pyradiomics-0+unknown-py3.5-win-amd64.egg\radiomics\scripts\commandline.py", line 80, in main featureVector.update(extractor.execute(args.image, args.mask, args.label)) File "c:\users\NAME\anaconda3\lib\site-packages\pyradiomics-0+unknown-py3.5-win-amd64.egg\radiomics\featureextractor.py", line 402, in execute boundingBox = imageoperations.checkMask(image, mask, *self.kwargs) File "c:\users\NAME\anaconda3\lib\site-packages\pyradiomics-0+unknown-py3.5-win-amd64.egg\radiomics\imageoperations.py", line 198, in checkMask lsif.Execute(imageNode, maskNode) File "c:\users\NAME\anaconda3\lib\site-packages\SimpleITK\SimpleITK.py", line 42566, in Execute return _SimpleITK.LabelStatisticsImageFilter_Execute(self, args) RuntimeError: Exception thrown in SimpleITK LabelStatisticsImageFilter_Execute: C:\d\vs14-64-pkg\SimpleITK-build\SimpleITK-build\Code\BasicFilters\src\sitkLabelStatisticsImageFilter.cxx:134: sitk::ERROR: Both images for LabelStatisticsImageFilter don't match type or dimension!

fedorov commented 7 years ago

@JoostJM I found the answer!

image3d = sitk.JoinSeries(image2d)
HIN0209 commented 7 years ago

I checked the dimension of the test image and was (580,420,120), different from (580,420,1) in the mask. It could be due to slicer, so I try the image3d option and see how it works.

JoostJM commented 7 years ago

@HIN0209 Indeed, the difference in shape is the cause of your error here. Maybe try @fedorov's approach?

fedorov commented 7 years ago

@HIN0209 if you generate your mask in Slicer, why don't you try using SlicerRadiomics extension? It should help take care of this kind of issues. Have you tried it?

How did you create and save mask in Slicer?

HIN0209 commented 7 years ago

Thank you both for great advises!

With Slicer, I loaded a (580,420) tif file. In the “add data into the scene”, Description is “Volume” (default). Hit OK. In “Save scene and unsaved data”, change the file format to NRRD (.nrrd) and save.

fedorov commented 7 years ago

If you are loading a single (580,420) TIFF file, but its dimensions show up as (580,420,120), this probably means you loaded 120 slices. In the "Add data" dialog check "Single file" checkbox in options to make sure only one file is loaded. image

HIN0209 commented 7 years ago

Thank you! I did not notice the Slicer option. It worked just fine. Also, "sitk.JoinSeries()" works to me (Win10).

Installation of SlicerRadiomics extension is a little bit too much, with so many processes to build from source, such that I can stick with the above two options.

fedorov commented 7 years ago

Installation of SlicerRadiomics extension is a little bit too much, with so many processes to build from source, such that I can stick with the above two options.

Very soon we will integrate SlcierRadiomics as a packaged extension, so you will be able to install it without having to build anything. Stay tuned!

durgeshkdwivedi commented 5 years ago

Hi Joost and Andrey, I'm also having a similar issue. I'm extracting the radiomics feature from DICOM images and it's a 2D MR image (just a single slice with 10 mm thickness, and one ROI on the image). All features were extracted except the 'shape based 2D' features. However, as usual by default 'shape based 3D' features were extracted in my dataset Do I need to extract 2D shape based separately (which is not easy as I'm not able to Force turned on 2D)? Or for a single slice the 3D shape based features are providing pretty much the same information as 2D shape based, therefore we can proceed with the 3D shape based features?

Thanks, Durgesh

fedorov commented 5 years ago

I think if your image has just one slice, it should be the same, but I can't tell for sure.

To force 2D extraction, you can use force2D setting, see https://github.com/Radiomics/pyradiomics/blob/master/examples/exampleSettings/exampleMR_NoResampling.yaml#L68-L72.

Does this answer your question?

durgeshkdwivedi commented 5 years ago

I think so. Thanks Andrey!

JoostJM commented 5 years ago

@durgeshkdwivedi, there are some marked differences in the formulas. most notably the sphericity etc, in 3D, it is compared to a sphere, in 2D to a circle.

For example, if you have a ROI of a perfect sphere in 2D, the shape 2D will reflect is as being most compact. In 3D, the ROI is interpreted as a sort of flat disc, which is less compact than a sphere.

Sahusues commented 1 year ago

Hello

I am trying to use Py radiomics library to compute GLSZM features on 2D images of rocks. I am facing problem to extract features using 2D images. It always gives an error attached below:

Thanks Pallavi

~\anaconda3\envs\py35\lib\site-packages\radiomics\shape.py in init(self, inputImage, inputMask, kwargs) 39 40 def init(self, inputImage, inputMask, kwargs): ---> 41 assert inputMask.GetDimension() == 3, 'Shape features are only available in 3D. If 2D, use shape2D instead' 42 super(RadiomicsShape, self).init(inputImage, inputMask, **kwargs) 43

AssertionError: Shape features are only available in 3D. If 2D, use shape2D instead