pyradiomics icon indicating copy to clipboard operation
pyradiomics copied to clipboard

[BUG] featureextractor.RadiomicsFeatureExtractor.execute reports error when using a mask of all ones

Open qiancao opened this issue 2 years ago • 2 comments

Describe the bug I didn't find clarification on this problem in the forums, and I don't think this is expected behavior, so I'm filing it under "bug". As the subject line states, RadiomicsFeatureExtractor.execute does not work when I have a mask of all ones (compute features using all voxels in the image).

The error thrown is: ValueError: No labels found in this mask (i.e. nothing is segmented)!

A hacky way to deal with this is to set a corner voxel to background, then it runs without issues.

To Reproduce Steps to reproduce the behavior (Scenario 1 fails and Scenario 2 works, albeit leaving out a single voxel from the calculation):

import numpy as np
import SimpleITK as sitk
from radiomics import featureextractor

# Extractor settings
settings = {}
settings['binWidth'] = 25
settings['resampledPixelSpacing'] = None  # [3,3,3] is an example for defining resampling (voxels with size 3x3x3mm)
settings['interpolator'] = sitk.sitkBSpline
settings['imageType'] = ['original']

# Create extractor
extractor = featureextractor.RadiomicsFeatureExtractor(**settings)

#%% Scenario 1: Using a mask of all ones (this fails)

# Test Image and Mask
volume = np.random.rand(3,3,3)*256
volumeSITK = sitk.GetImageFromArray(volume)

mask = np.ones(volume.shape).astype(int)
# mask[0,0,0] = 0
maskSITK = sitk.GetImageFromArray(mask)
featureVector = extractor.execute(volumeSITK, maskSITK, label=1)


#%% Scenario 2: Setting corner voxel of mask intentionally to zero (this works, but unecessarily hacky)

mask = np.ones(volume.shape).astype(int)
mask[0,0,0] = 0 # This is diffeer
maskSITK = sitk.GetImageFromArray(mask)
featureVector = extractor.execute(volumeSITK, maskSITK, label=1)

Expected behavior PyRadiomics should take a mask image of all ones and recognize that I would like the features to be computed on all voxels of the image.

Version (please complete the following information):

  • OS: Ubuntu
  • Python version: 3.8
  • PyRadiomics version: latest

qiancao avatar May 03 '22 22:05 qiancao

This is because in imageoperations.py (lines 47-49):

  labels = numpy.unique(sitk.GetArrayFromImage(mask))
  if len(labels) == 1:
    raise ValueError('No labels found in this mask (i.e. nothing is segmented)!')

The use of numpy.unique checks for number of unique values in the mask image. I think this is inaccurate. The error message: "No labels found in this mask (i.e. nothing is segmented)!" should be interpreted as: when the mask image is all zeros (everything is background and nothing is segmented).

I suggest changing line 48 to: if np.all((sitk.GetArrayFromImage(mask) == 0)):

qiancao avatar May 03 '22 22:05 qiancao

I met the same problem

mgcyung avatar Jul 26 '22 04:07 mgcyung