How to use pyradiomics without mask?

1,354 views
Skip to first unread message

Diana Marín

unread,
Sep 18, 2018, 7:57:23 PM9/18/18
to pyradiomics
 Hello, 

I am trying to use pyradiomics in my own MRI dataset, but I do not have mask file because I only have ROIs. I tried generating masks in different ways, such as zeros or ones masks equal to ROI size, but it did not work, I am getting an empty dictionary. 

I am using the next code 
.


from radiomics import featureextractor
import os
import six
import sys
import nrrd


dataDir = 'C:/Users/usuario/Desktop/pyradiomics-master/data'
dataDir2 = 'C:/Users/usuario/Desktop/pyradiomics-master'

testCase = 'Mama1'
imageName = os.path.join(dataDir, testCase + "_image.nrrd")
maskName = os.path.join(dataDir, testCase + "_label.nrrd")

params = os.path.join(dataDir2, "examples", "exampleSettings", "Params.yaml")


extractor = featureextractor.RadiomicsFeaturesExtractor(params)
result = extractor.execute(imageName, maskName)

for key, val in six.iteritems(result):
  print("\t%s: %s" %(key, val))





Thanks in advance



Diana Marín 

Joost van Griethuysen

unread,
Sep 19, 2018, 4:11:13 AM9/19/18
to pyradiomics
Hello Diana,

What do you mean that you do not have a mask file, but you do have the ROI? In what format is your ROI stored?
Can you enable logging? That might give you more insight into what goes wrong. See here.

Regards,

Joost

Op woensdag 19 september 2018 01:57:23 UTC+2 schreef Diana Marín:

Zhenwei Shi

unread,
Sep 19, 2018, 4:51:05 AM9/19/18
to pyradiomics
Hi, Diana

If you have DICOM image and DICOM-RT, you could consider some method to create the binary mask.

Best,
Zhenwei

Diana Marín

unread,
Sep 19, 2018, 4:58:43 PM9/19/18
to pyradiomics
Hello Joost,

I meant to say that I have a 3D ROI in a numpy array and I converted it in a nrrd file, but I tried to create the mask saving a zeros array with the same shape of ROI in nrrd format and it did not work. However, now I am reading nrrd files using sitk and the process shown in "Using feature classes directly"  and it works. 

This is the new code 


from radiomics import firstorder, glcm, imageoperations, shape, glrlm, glszm, getTestCase
import SimpleITK as sitk
import six
import sys, os

#testCase = 'AEDC'

testCase='AEDC'

dataDir= '/home/dianamarin/Descargas/pyradiomics-master'

dataDir2= '/home/dianamarin/Descargas/pyradiomics-master/data'

imageName = os.path.join(dataDir2, testCase + "_image.nrrd")
maskName = os.path.join(dataDir2, testCase + "_label.nrrd")

image = sitk.ReadImage(imageName)
mask = sitk.ReadImage(maskName)


firstOrderFeatures = firstorder.RadiomicsFirstOrder(image,mask)
firstOrderFeatures.enableAllFeatures()  
firstOrderFeatures.calculateFeatures()



Thanks for your suggestion

Diana Marín

unread,
Sep 19, 2018, 5:00:56 PM9/19/18
to pyradiomics
Zhenwei, Thanks for your suggestion

Joost van Griethuysen

unread,
Sep 20, 2018, 5:23:38 AM9/20/18
to pyradiomics
Hello Diana,

I'd still suggest to run the normal workflow with logging to see what's going wrong. Off the top of my head, there are 3 potential issues:

1) If you create a mask using numpy.zeros, it will indeed not work, as '0' represents background. Try numpy.ones instead.
2) If you already have your ROI in a numpy array, what is the value indicating the segmented voxels? That should match the value in the `label` parameter.
3) Remember that you also have to copy the geometric information, as otherwise it is possible there is a geometric mismatch

The reason why it does work when you are using the feature classes directly, is because a lot of preprocessing and validation is skipped, including the checks for geometric alignment!.
Additionally, this way, you cannot apply resampling, resegmentation or filters.

Regards,

Joost

Op woensdag 19 september 2018 22:58:43 UTC+2 schreef Diana Marín:

Diana Marín

unread,
Sep 20, 2018, 8:39:23 PM9/20/18
to pyradiomics
Hello Joost


It is my first time using radiomics and I have some questions. So, I am going to explain to you the structure of the data. 

I have studies of breast magnetic resonance for different patients. These are composed of different sequences (diffusion, T1, T2....).  I have the suspect regions marked with a point in each one of these sequences but I have no a segmentation of these. I cropped ROIs based on this point, taking a radio that covers the suspect region. For this, I used Matlab and finally, I got a .mat structure with all cropped ROIs. 



WhatsApp Image 2018-09-20 at 6.44.35 PM.jpeg
















WhatsApp Image 2018-09-20 at 7.20.58 PM.jpeg













Then, I read the .mat structure in python with  scipy.io library and get a numpy array to each ROI, which I saved in .nrrd format and generated the mask with numpy.ones.

Finally, I used the up code and I got an empty OrderDict. Also when I compared my .nrrd files with the toolbox's example I realized that information is missing. 

1) Example's information (brain1.nrrd)

OrderedDict([('type', 'int'),
             ('dimension', 3),
             ('space', 'left-posterior-superior'),
             ('sizes', array([256, 256,  25])),
             ('space directions', array([[ 0.78125,  0.     ,  0.     ],
                     [ 0.     , -0.78125,  0.     ],
                     [ 0.     ,  0.     ,  6.5    ]])),
             ('kinds', ['domain', 'domain', 'domain']),
             ('endian', 'little'),
             ('encoding', 'gzip'),
             ('space origin', array([-99.609375,  99.609375, -78.      ]))])

2)  My .nrrd information 

OrderedDict([('type', 'double'),
             ('dimension', 3),
             ('sizes', array([20, 12,  5])),
             ('endian', 'little'),
             ('encoding', 'gzip')])



Regard to the third suggestion, I did not understand what did you refer with geometric information. 

I really appreciate your help, thanks in advance. 

greetings, 

cam cushingc

unread,
Sep 20, 2018, 11:17:20 PM9/20/18
to dianam...@gmail.com, pyrad...@googlegroups.com
Hi Diana -

I've been watching this conversation and have a question for you. Why are you using square/cubic ROI's? Biology rarely is nice and square. Perhaps it would be worth your while to open your data sets in Slicer and draw contours/ROIs in there. Slicer will automatically save the ROI in NRRD or NIFTI format for you. It can be bit of work, but paper reviewers will like 'contours drawn by a clinician' (if you're not a clinician, get one to check your contours) more than 'square ROI's were drawn.' I've been getting my contours checked by a clinical for my study. Better yet is if you have access to the clinical contours. It is admittedly some work when the tumor is 120 slices.... but the results have been worth it.

Hope this helps,
Cam

--
You received this message because you are subscribed to the Google Groups "pyradiomics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyradiomics...@googlegroups.com.
To post to this group, send email to pyrad...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyradiomics/2caaef2f-24bc-4384-89d0-d507417f38f5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Cameron Cushing

Joost van Griethuysen

unread,
Sep 21, 2018, 4:31:58 AM9/21/18
to pyradiomics
Hi Diana,

I agree with Cam, it's the same workflow we use in our team. Still, if that is not possible, you can use your square ROIs. However, I'd suggest a slightly different approach (which you can can do in Python).
The are some slight problems with your current approach:

You have a mask of numpy.ones, but it's dimensions are different from the image ((20, 12, 5) vs (256, 256, 25)), and no geometric information (origin, spacing and direction). Therefore, your computer cannot know where to put your square ROI in the image.
Even if you were to copy the image's geometric information, the ROI would end up in the corner of your original image, hardly near the point of interest. PyRadiomics would be able to extract features, but these would be meaningless.

So if you have an image and want to draw a square box around a point for which you have index x, y, z (index, so starting at 0), you can use the following code to build a mask NRRD file:

import SimpleITK as sitk
import numpy as np

im = sitk.ReadImage(r'path/to/image')
point = (x, y, z)  # fill in the index of your point here
roi_size = (19, 11, 5)  # x, y, z; uneven to ensure the point is really the center of your ROI

im_size = im.GetSize()[::-1]  # size in z, y, x, needed because the arrays obtained from the image are oriented in z, y, x

ma_arr = np.zeros(im_size, dtype='uint8')

# Compute lower and upper bound of the ROI
L_x = point[0] - int((roi_size[0] - 1) / 2)
L_y = point[1] - int((roi_size[1] - 1) / 2)
L_z = point[2] - int((roi_size[2] - 1) / 2)

U_x = point[0] + int((roi_size[0] - 1) / 2)
U_y = point[1] + int((roi_size[1] - 1) / 2)
U_z = point[2] + int((roi_size[2] - 1) / 2)

# ensure the ROI stays within the image bounds
L_x = max(0, L_x)
L_y = max(0, L_y)
L_z = max(0, L_z)

U_x = min(im_size[2] - 1, U_x)
U_y = min(im_size[1] - 1, U_y)
U_z = min(im_size[0] - 1, U_z)

# 'segment' the mask
ma_arr[L_z:U_z + 1, L_y:U_y + 1, L_x:U_x+1] = 1  # Add + 1 to each slice, as slicing is done from lower bound to, but not including, upper bound. Because we do want to include our upper bound, add + 1

ma = sitk.GetImageFromArray(ma_arr)
ma.CopyInformation(im)  # This copies the geometric information, ensuring image and mask are aligned. This works, because image and mask have the same size of the pixel array

sitk.WriteImage(ma, r'path/to/mask.nrrd', True)  # don't forget the extension!, True specifies it can be compressed for storage (only used for masks)

Regards,

Joost

Op vrijdag 21 september 2018 05:17:20 UTC+2 schreef cam cushingc:
To unsubscribe from this group and stop receiving emails from it, send an email to pyradiomics+unsubscribe@googlegroups.com.

To post to this group, send email to pyrad...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyradiomics/2caaef2f-24bc-4384-89d0-d507417f38f5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Cameron Cushing
Reply all
Reply to author
Forward
0 new messages