def _calculateCMatrix(self): self.logger.debug('Calculating GLCM matrix in C') size = numpy.max(self.matrixCoordinates, 1) - numpy.min( self.matrixCoordinates, 1) + 1 angles = imageoperations.generateAngles(size, **self.kwargs) Ng = self.coefficients['Ng'] P_glcm = cMatrices.calculate_glcm(self.matrix, self.maskArray, angles, Ng) P_glcm = self._applyMatrixOptions(P_glcm, angles) # Delete rows and columns that specify gray levels not present in the ROI Ng = self.coefficients['Ng'] NgVector = range(1, Ng + 1) # All possible gray values GrayLevels = self.coefficients[ 'grayLevels'] # Gray values present in ROI emptyGrayLevels = numpy.array( list(set(NgVector) - set(GrayLevels))) # Gray values NOT present in ROI P_glcm = numpy.delete(P_glcm, emptyGrayLevels - 1, 0) P_glcm = numpy.delete(P_glcm, emptyGrayLevels - 1, 1) return P_glcm
def _calculateCMatrix(self): size = numpy.max(self.matrixCoordinates, 1) - numpy.min( self.matrixCoordinates, 1) + 1 angles = imageoperations.generateAngles(size) Ng = self.coefficients['Ng'] P_glcm = cMatrices.calculate_glcm(self.matrix, self.maskArray, angles, Ng) P_glcm = self._applyMatrixOptions(P_glcm, angles) return P_glcm
def _calculateCMatrix(self): self.logger.debug('Calculating GLCM matrix in C') size = numpy.max(self.matrixCoordinates, 1) - numpy.min(self.matrixCoordinates, 1) + 1 angles = imageoperations.generateAngles(size, **self.kwargs) Ng = self.coefficients['Ng'] P_glcm = cMatrices.calculate_glcm(self.matrix, self.maskArray, angles, Ng) P_glcm = self._applyMatrixOptions(P_glcm, angles) return P_glcm
def _calculateCMatrix(self): self.logger.debug('Calculating GLCM matrix in C') Ng = self.coefficients['Ng'] P_glcm, angles = cMatrices.calculate_glcm(self.matrix, self.maskArray, numpy.array(self.kwargs.get('distances', [1])), Ng, self.kwargs.get('force2D', False), self.kwargs.get('force2Ddimension', 0)) P_glcm = self._applyMatrixOptions(P_glcm, angles) # Delete rows and columns that specify gray levels not present in the ROI NgVector = range(1, Ng + 1) # All possible gray values GrayLevels = self.coefficients['grayLevels'] # Gray values present in ROI emptyGrayLevels = numpy.array(list(set(NgVector) - set(GrayLevels))) # Gray values NOT present in ROI P_glcm = numpy.delete(P_glcm, emptyGrayLevels - 1, 0) P_glcm = numpy.delete(P_glcm, emptyGrayLevels - 1, 1) return P_glcm
def _calculateMatrix(self, voxelCoordinates=None): r""" Compute GLCMs for the input image for every direction in 3D. Calculated GLCMs are placed in array P_glcm with shape (i/j, a) i/j = total gray-level bins for image array, a = directions in 3D (generated by imageoperations.generateAngles) """ self.logger.debug('Calculating GLCM matrix in C') Ng = self.coefficients['Ng'] matrix_args = [ self.imageArray, self.maskArray, numpy.array(self.settings.get('distances', [1])), Ng, self.settings.get('force2D', False), self.settings.get('force2Ddimension', 0) ] if self.voxelBased: matrix_args += [ self.settings.get('kernelRadius', 1), voxelCoordinates ] P_glcm, angles = cMatrices.calculate_glcm(*matrix_args) self.logger.debug('Process calculated matrix') # Delete rows and columns that specify gray levels not present in the ROI NgVector = range(1, Ng + 1) # All possible gray values GrayLevels = self.coefficients[ 'grayLevels'] # Gray values present in ROI emptyGrayLevels = numpy.array( list(set(NgVector) - set(GrayLevels)), dtype=int) # Gray values NOT present in ROI P_glcm = numpy.delete(P_glcm, emptyGrayLevels - 1, 1) P_glcm = numpy.delete(P_glcm, emptyGrayLevels - 1, 2) # Optionally make GLCMs symmetrical for each angle if self.symmetricalGLCM: self.logger.debug('Create symmetrical matrix') # Transpose and copy GLCM and add it to P_glcm. Numpy.transpose returns a view if possible, use .copy() to ensure # a copy of the array is used and not just a view (otherwise erroneous additions can occur) P_glcm += numpy.transpose(P_glcm, (0, 2, 1, 3)).copy() # Optionally apply a weighting factor if self.weightingNorm is not None: self.logger.debug('Applying weighting (%s)', self.weightingNorm) pixelSpacing = self.inputImage.GetSpacing()[::-1] weights = numpy.empty(len(angles)) for a_idx, a in enumerate(angles): if self.weightingNorm == 'infinity': weights[a_idx] = numpy.exp( -max(numpy.abs(a) * pixelSpacing)**2) elif self.weightingNorm == 'euclidean': weights[a_idx] = numpy.exp(-numpy.sum( (numpy.abs(a) * pixelSpacing)**2)) # sqrt ^ 2 = 1 elif self.weightingNorm == 'manhattan': weights[a_idx] = numpy.exp( -numpy.sum(numpy.abs(a) * pixelSpacing)**2) elif self.weightingNorm == 'no_weighting': weights[a_idx] = 1 else: self.logger.warning( 'weigthing norm "%s" is unknown, W is set to 1', self.weightingNorm) weights[a_idx] = 1 P_glcm = numpy.sum(P_glcm * weights[None, None, None, :], 3, keepdims=True) sumP_glcm = numpy.sum(P_glcm, (1, 2)) # Delete empty angles if no weighting is applied if P_glcm.shape[3] > 1: emptyAngles = numpy.where(numpy.sum(sumP_glcm, 0) == 0) if len(emptyAngles[0]) > 0: # One or more angles are 'empty' self.logger.debug('Deleting %d empty angles:\n%s', len(emptyAngles[0]), angles[emptyAngles]) P_glcm = numpy.delete(P_glcm, emptyAngles, 3) sumP_glcm = numpy.delete(sumP_glcm, emptyAngles, 1) else: self.logger.debug('No empty angles') # Mark empty angles with NaN, allowing them to be ignored in feature calculation sumP_glcm[sumP_glcm == 0] = numpy.nan # Normalize each glcm P_glcm /= sumP_glcm[:, None, None, :] return P_glcm