Exemplo n.º 1
0
    def __init__(self, inputImage, inputMask, **kwargs):
        super(RadiomicsGLRLM, self).__init__(inputImage, inputMask, **kwargs)

        self.weightingNorm = kwargs.get('weightingNorm',
                                        None)  # manhattan, euclidean, infinity

        self.coefficients = {}
        self.P_glrlm = {}

        # binning
        self.matrix, self.binEdges = imageoperations.binImage(
            self.binWidth, self.matrix, self.matrixCoordinates)
        self.coefficients['Ng'] = int(
            numpy.max(self.matrix[
                self.matrixCoordinates]))  # max gray level in the ROI
        self.coefficients['Nr'] = numpy.max(self.matrix.shape)
        self.coefficients['Np'] = self.targetVoxelArray.size

        if cMatsEnabled():
            self.P_glrlm = self._calculateCMatrix()
        else:
            self.P_glrlm = self._calculateMatrix()

        self._calculateCoefficients()

        self.logger.debug(
            'Feature class initialized, calculated GLRLM with shape %s',
            self.P_glrlm.shape)
Exemplo n.º 2
0
  def __init__(self, inputImage, inputMask, **kwargs):
    super(RadiomicsShape, self).__init__(inputImage, inputMask, **kwargs)

    self.pixelSpacing = numpy.array(inputImage.GetSpacing()[::-1])

    # Use SimpleITK for some shape features
    self.lssif = sitk.LabelShapeStatisticsImageFilter()
    self.lssif.SetComputeFeretDiameter(True)
    self.lssif.Execute(inputMask)

    # Pad inputMask to prevent index-out-of-range errors
    cpif = sitk.ConstantPadImageFilter()

    padding = numpy.tile(1, 3)
    try:
      cpif.SetPadLowerBound(padding)
      cpif.SetPadUpperBound(padding)
    except TypeError:
      # newer versions of SITK/python want a tuple or list
      cpif.SetPadLowerBound(padding.tolist())
      cpif.SetPadUpperBound(padding.tolist())

    self.inputMask = cpif.Execute(self.inputMask)

    # Reassign self.maskArray using the now-padded self.inputMask and make it binary
    self.maskArray = (sitk.GetArrayFromImage(self.inputMask) == self.label).astype('int')
    self.matrixCoordinates = numpy.where(self.maskArray != 0)

    # Volume and Surface Area are pre-calculated
    self.Volume = self.lssif.GetPhysicalSize(self.label)
    if cMatsEnabled():
      self.SurfaceArea = self._calculateCSurfaceArea()
    else:
      self.SurfaceArea = self._calculateSurfaceArea()
Exemplo n.º 3
0
    def _initSegmentBasedCalculation(self):

        self.pixelSpacing = numpy.array(self.inputImage.GetSpacing()[::-1])

        # Pad inputMask to prevent index-out-of-range errors
        self.logger.debug('Padding the mask with 0s')

        cpif = sitk.ConstantPadImageFilter()

        padding = numpy.tile(1, 3)
        try:
            cpif.SetPadLowerBound(padding)
            cpif.SetPadUpperBound(padding)
        except TypeError:
            # newer versions of SITK/python want a tuple or list
            cpif.SetPadLowerBound(padding.tolist())
            cpif.SetPadUpperBound(padding.tolist())

        self.inputMask = cpif.Execute(self.inputMask)

        # Reassign self.maskArray using the now-padded self.inputMask and make it binary
        self.maskArray = (sitk.GetArrayFromImage(
            self.inputMask) == self.label).astype('int')
        self.labelledVoxelCoordinates = numpy.where(self.maskArray != 0)

        self.logger.debug('Pre-calculate Volume, Surface Area and Eigenvalues')

        # Volume, Surface Area and eigenvalues are pre-calculated
        # Compute volume
        z, x, y = self.pixelSpacing
        Np = len(self.labelledVoxelCoordinates[0])
        self.Volume = Np * (z * x * y)

        # Compute Surface Area
        if cMatsEnabled():
            self.SurfaceArea = self._calculateCSurfaceArea()
        else:
            self.SurfaceArea = self._calculateSurfaceArea()

        # Compute eigenvalues and -vectors
        coordinates = numpy.array(self.labelledVoxelCoordinates,
                                  dtype='int').transpose(
                                      (1, 0))  # Transpose equals zip(*a)
        physicalCoordinates = [
            self.inputMask.TransformIndexToPhysicalPoint((idx.tolist())[::-1])
            for idx in coordinates
        ]
        physicalCoordinates -= numpy.mean(physicalCoordinates,
                                          axis=0)  # Centered at 0
        physicalCoordinates /= numpy.sqrt(Np)
        covariance = numpy.dot(physicalCoordinates.T.copy(),
                               physicalCoordinates)
        self.eigenValues, eigenVectors = numpy.linalg.eig(
            covariance)  # eigenVectors are not used

        self.eigenValues.sort()  # Sort the eigenValues from small to large

        self.diameters = None  # Do not precompute diameters

        self.logger.debug('Shape feature class initialized')
Exemplo n.º 4
0
    def __init__(self, inputImage, inputMask, **kwargs):
        super(RadiomicsGLSZM, self).__init__(inputImage, inputMask, **kwargs)

        self.coefficients = {}
        self.P_glszm = {}

        # binning
        self.matrix, self.binEdges = imageoperations.binImage(
            self.binWidth, self.matrix, self.matrixCoordinates)
        self.coefficients['Ng'] = int(
            numpy.max(self.matrix[
                self.matrixCoordinates]))  # max gray level in the ROI
        self.coefficients['Np'] = self.targetVoxelArray.size
        self.coefficients['grayLevels'] = numpy.unique(
            self.matrix[self.matrixCoordinates])

        if cMatsEnabled():
            self.P_glszm = self._calculateCMatrix()
        else:
            self.P_glszm = self._calculateMatrix()

        self._calculateCoefficients()

        self.logger.debug(
            'Feature class initialized, calculated GLSZM with shape %s',
            self.P_glszm.shape)
Exemplo n.º 5
0
  def _initSegmentBasedCalculation(self):
    super(RadiomicsGLCM, self)._initSegmentBasedCalculation()

    self._applyBinning()

    if cMatsEnabled():
      self.P_glcm = self._calculateCMatrix()
    else:
      self.P_glcm = self._calculateMatrix()

    self._calculateCoefficients()

    self.logger.debug('GLCM feature class initialized, calculated GLCM with shape %s', self.P_glcm.shape)
Exemplo n.º 6
0
  def _initSegmentBasedCalculation(self):
    super(RadiomicsGLSZM, self)._initSegmentBasedCalculation()

    self._applyBinning()

    self.coefficients['Np'] = len(self.labelledVoxelCoordinates[0])

    if cMatsEnabled():
      self.P_glszm = self._calculateCMatrix()
    else:
      self.P_glszm = self._calculateMatrix()

    self._calculateCoefficients()

    self.logger.debug('GLSZM feature class initialized, calculated GLSZM with shape %s', self.P_glszm.shape)
Exemplo n.º 7
0
    def test_scenario(self, test, featureClassName):
        print("")
        global testUtils, featureClasses

        logging.debug('test_scenario: testCase = %s, featureClassName = %s',
                      test, featureClassName)

        assert cMatsEnabled()

        testUtils.setFeatureClassAndTestCase(featureClassName, test)

        testImage = testUtils.getImage('original')
        testMask = testUtils.getMask('original')

        featureClass = featureClasses[featureClassName](
            testImage, testMask, **testUtils.getSettings())

        if featureClassName == 'shape':
            cSA = getattr(featureClass,
                          'SurfaceArea')  # pre-calculated value by C extension
            assert (cSA is not None)

            pySA = getattr(featureClass, '_calculateSurfaceArea')(
            )  # Function, call to calculate SA in full-python mode
            assert (pySA is not None)

            # Check if the calculated values match
            assert (numpy.abs(pySA - cSA)) < 1e-3

        else:
            assert "_calculateMatrix" in dir(featureClass)

            cMat = featureClass._calculateCMatrix()
            assert cMat is not None

            pyMat = featureClass._calculateMatrix()
            assert pyMat is not None

            if len(pyMat.shape) == 3:
                # specific matrices per angle, so ensure angles are in the same order for python and C calculated matrices
                pyMat = numpy.array([
                    pyMat[:, :, x]
                    for x in (12, 11, 10, 8, 7, 6, 4, 3, 2, 9, 5, 1, 0)
                ])
                pyMat = pyMat.transpose((1, 2, 0))

            # Check if the calculated arrays match
            assert numpy.max(numpy.abs(pyMat - cMat)) < 1e-3
Exemplo n.º 8
0
    def getMaximum2DDiameterRowFeatureValue(self):
        r"""
    **11. Maximum 2D diameter (Row)**

    Maximum 2D diameter (Row) is defined as the largest pairwise Euclidean distance between tumor surface voxels in the
    column-slice (usually the sagittal) plane.

    .. warning::
      This feature is only available when C Extensions are enabled
    """
        if cMatsEnabled():
            if self.diameters is None:
                self.diameters = self._calculateCDiameters()
            return self.diameters[2]
        else:
            self.logger.warning(
                'For computational reasons, this feature is only implemented in C. Enable C extensions to '
                'calculate this feature.')
            return numpy.nan
Exemplo n.º 9
0
    def __init__(self, inputImage, inputMask, **kwargs):
        super(RadiomicsGLCM, self).__init__(inputImage, inputMask, **kwargs)

        self.symmetricalGLCM = kwargs.get('symmetricalGLCM', True)
        self.weightingNorm = kwargs.get('weightingNorm',
                                        None)  # manhattan, euclidean, infinity

        self.coefficients = {}
        self.P_glcm = {}

        # binning
        self.matrix, self.histogram = imageoperations.binImage(
            self.binWidth, self.matrix, self.matrixCoordinates)
        self.coefficients['Ng'] = self.histogram[1].shape[0] - 1

        if cMatsEnabled():
            self.P_glcm = self._calculateCMatrix()
        else:
            self.P_glcm = self._calculateMatrix()

        self._calculateCoefficients()
Exemplo n.º 10
0
    def getMaximum3DDiameterFeatureValue(self):
        r"""
    **8. Maximum 3D diameter**

    Maximum 3D diameter is defined as the largest pairwise Euclidean distance between surface voxels in the ROI.

    Also known as Feret Diameter.

    .. warning::
      This feature is only available when C Extensions are enabled
    """

        if cMatsEnabled():
            if self.diameters is None:
                self.diameters = self._calculateCDiameters()
            return self.diameters[3]
        else:
            self.logger.warning(
                'For computational reasons, this feature is only implemented in C. Enable C extensions to '
                'calculate this feature.')
            return numpy.nan
Exemplo n.º 11
0
    def __init__(self, inputImage, inputMask, **kwargs):
        super(RadiomicsGLRLM, self).__init__(inputImage, inputMask, **kwargs)

        self.weightingNorm = kwargs.get('weightingNorm',
                                        None)  # manhattan, euclidean, infinity

        self.coefficients = {}
        self.P_glrlm = {}

        # binning
        self.matrix, self.histogram = imageoperations.binImage(
            self.binWidth, self.matrix, self.matrixCoordinates)
        self.coefficients['Ng'] = self.histogram[1].shape[0] - 1
        self.coefficients['Nr'] = numpy.max(self.matrix.shape)
        self.coefficients['Np'] = self.targetVoxelArray.size

        if cMatsEnabled():
            self.P_glrlm = self._calculateCMatrix()
        else:
            self.P_glrlm = self._calculateMatrix()

        self._calculateCoefficients()
Exemplo n.º 12
0
  def test_scenario(self, testCase, featureClassName):
    print("")
    global testUtils, featureClasses

    logging.debug('test_scenario: testCase = %s, featureClassName = %s', testCase, featureClassName)

    assert cMatsEnabled()

    testUtils.setFeatureClassAndTestCase(featureClassName, testCase)

    testImage = testUtils.getImage()
    testMask = testUtils.getMask()

    featureClass = featureClasses[featureClassName](testImage, testMask, **testUtils.getSettings())

    if featureClassName == 'shape':
      cSA = getattr(featureClass, 'SurfaceArea')  # pre-calculated value by C extension
      assert (cSA is not None)

      pySA = getattr(featureClass, '_calculateSurfaceArea')()  # Function, call to calculate SA in full-python mode
      assert (pySA is not None)

      # Check if the calculated values match
      assert (numpy.abs(pySA - cSA)) < 1e-3

    else:
      assert "_calculateMatrix" in dir(featureClass)

      cMat = getattr(featureClass, 'P_%s' % featureClassName)  # matrix calculated at initialization by C extension
      assert cMat is not None

      pyMat = featureClass._calculateMatrix()
      assert pyMat is not None

      # Check if the calculated arrays match
      assert numpy.max(numpy.abs(pyMat - cMat)) < 1e-3