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)
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()
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')
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)
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)
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)
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
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
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()
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
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()
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