mediml 0.9.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- MEDiml/MEDscan.py +1696 -0
- MEDiml/__init__.py +21 -0
- MEDiml/biomarkers/BatchExtractor.py +806 -0
- MEDiml/biomarkers/BatchExtractorTexturalFilters.py +840 -0
- MEDiml/biomarkers/__init__.py +16 -0
- MEDiml/biomarkers/diagnostics.py +125 -0
- MEDiml/biomarkers/get_oriented_bound_box.py +158 -0
- MEDiml/biomarkers/glcm.py +1602 -0
- MEDiml/biomarkers/gldzm.py +523 -0
- MEDiml/biomarkers/glrlm.py +1315 -0
- MEDiml/biomarkers/glszm.py +555 -0
- MEDiml/biomarkers/int_vol_hist.py +527 -0
- MEDiml/biomarkers/intensity_histogram.py +615 -0
- MEDiml/biomarkers/local_intensity.py +89 -0
- MEDiml/biomarkers/morph.py +1756 -0
- MEDiml/biomarkers/ngldm.py +780 -0
- MEDiml/biomarkers/ngtdm.py +414 -0
- MEDiml/biomarkers/stats.py +373 -0
- MEDiml/biomarkers/utils.py +389 -0
- MEDiml/filters/TexturalFilter.py +299 -0
- MEDiml/filters/__init__.py +9 -0
- MEDiml/filters/apply_filter.py +134 -0
- MEDiml/filters/gabor.py +215 -0
- MEDiml/filters/laws.py +283 -0
- MEDiml/filters/log.py +147 -0
- MEDiml/filters/mean.py +121 -0
- MEDiml/filters/textural_filters_kernels.py +1738 -0
- MEDiml/filters/utils.py +107 -0
- MEDiml/filters/wavelet.py +237 -0
- MEDiml/learning/DataCleaner.py +198 -0
- MEDiml/learning/DesignExperiment.py +480 -0
- MEDiml/learning/FSR.py +667 -0
- MEDiml/learning/Normalization.py +112 -0
- MEDiml/learning/RadiomicsLearner.py +714 -0
- MEDiml/learning/Results.py +2237 -0
- MEDiml/learning/Stats.py +694 -0
- MEDiml/learning/__init__.py +10 -0
- MEDiml/learning/cleaning_utils.py +107 -0
- MEDiml/learning/ml_utils.py +1015 -0
- MEDiml/processing/__init__.py +6 -0
- MEDiml/processing/compute_suv_map.py +121 -0
- MEDiml/processing/discretisation.py +149 -0
- MEDiml/processing/interpolation.py +275 -0
- MEDiml/processing/resegmentation.py +66 -0
- MEDiml/processing/segmentation.py +912 -0
- MEDiml/utils/__init__.py +25 -0
- MEDiml/utils/batch_patients.py +45 -0
- MEDiml/utils/create_radiomics_table.py +131 -0
- MEDiml/utils/data_frame_export.py +42 -0
- MEDiml/utils/find_process_names.py +16 -0
- MEDiml/utils/get_file_paths.py +34 -0
- MEDiml/utils/get_full_rad_names.py +21 -0
- MEDiml/utils/get_institutions_from_ids.py +16 -0
- MEDiml/utils/get_patient_id_from_scan_name.py +22 -0
- MEDiml/utils/get_patient_names.py +26 -0
- MEDiml/utils/get_radiomic_names.py +27 -0
- MEDiml/utils/get_scan_name_from_rad_name.py +22 -0
- MEDiml/utils/image_reader_SITK.py +37 -0
- MEDiml/utils/image_volume_obj.py +22 -0
- MEDiml/utils/imref.py +340 -0
- MEDiml/utils/initialize_features_names.py +62 -0
- MEDiml/utils/inpolygon.py +159 -0
- MEDiml/utils/interp3.py +43 -0
- MEDiml/utils/json_utils.py +78 -0
- MEDiml/utils/mode.py +31 -0
- MEDiml/utils/parse_contour_string.py +58 -0
- MEDiml/utils/save_MEDscan.py +30 -0
- MEDiml/utils/strfind.py +32 -0
- MEDiml/utils/textureTools.py +188 -0
- MEDiml/utils/texture_features_names.py +115 -0
- MEDiml/utils/write_radiomics_csv.py +47 -0
- MEDiml/wrangling/DataManager.py +1724 -0
- MEDiml/wrangling/ProcessDICOM.py +512 -0
- MEDiml/wrangling/__init__.py +3 -0
- mediml-0.9.9.dist-info/LICENSE.md +674 -0
- mediml-0.9.9.dist-info/METADATA +232 -0
- mediml-0.9.9.dist-info/RECORD +78 -0
- mediml-0.9.9.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,780 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from copy import deepcopy
|
|
6
|
+
from typing import Dict, List
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
import pandas as pd
|
|
10
|
+
|
|
11
|
+
from ..utils.textureTools import (coord2index, get_neighbour_direction,
|
|
12
|
+
get_value, is_list_all_none)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_matrix(roi_only: np.array,
|
|
16
|
+
levels: np.ndarray) -> float:
|
|
17
|
+
"""Computes Neighbouring grey level dependence matrix.
|
|
18
|
+
This matrix refers to "Neighbouring grey level dependence based features" (ID = REK0)
|
|
19
|
+
in the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`_.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
roi_only_int (ndarray): Smallest box containing the ROI, with the imaging data ready
|
|
23
|
+
for texture analysis computations. Voxels outside the ROI are
|
|
24
|
+
set to NaNs.
|
|
25
|
+
levels (ndarray or List): Vector containing the quantized gray-levels
|
|
26
|
+
in the tumor region (or reconstruction ``levels`` of quantization).
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
ndarray: Array of neighbouring grey level dependence matrix of ``roi_only``.
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
roi_only = roi_only.copy()
|
|
33
|
+
|
|
34
|
+
# PRELIMINARY
|
|
35
|
+
level_temp = np.max(levels)+1
|
|
36
|
+
roi_only[np.isnan(roi_only)] = level_temp
|
|
37
|
+
levels = np.append(levels, level_temp)
|
|
38
|
+
dim = np.shape(roi_only)
|
|
39
|
+
if np.size(dim) == 2:
|
|
40
|
+
np.append(dim, 1)
|
|
41
|
+
|
|
42
|
+
q_2 = np.reshape(roi_only, np.prod(dim), order='F').astype("int")
|
|
43
|
+
|
|
44
|
+
# QUANTIZATION EFFECTS CORRECTION (M. Vallieres)
|
|
45
|
+
# In case (for example) we initially wanted to have 64 levels, but due to
|
|
46
|
+
# quantization, only 60 resulted.
|
|
47
|
+
# q_s = round(levels*adjust)/adjust;
|
|
48
|
+
# q_2 = round(q_2*adjust)/adjust;
|
|
49
|
+
q_s = levels.copy()
|
|
50
|
+
|
|
51
|
+
# EL NAQA CODE
|
|
52
|
+
q_3 = q_2*0
|
|
53
|
+
lqs = np.size(q_s)
|
|
54
|
+
for k in range(1, lqs+1):
|
|
55
|
+
q_3[q_2 == q_s[k-1]] = k
|
|
56
|
+
|
|
57
|
+
q_3 = np.reshape(q_3, dim, order='F')
|
|
58
|
+
|
|
59
|
+
# Min dependence = 0, Max dependence = 26; So 27 columns
|
|
60
|
+
ngldm = np.zeros((lqs, 27))
|
|
61
|
+
for i in range(1, dim[0]+1):
|
|
62
|
+
i_min = max(1, i-1)
|
|
63
|
+
i_max = min(i+1, dim[0])
|
|
64
|
+
for j in range(1, dim[1]+1):
|
|
65
|
+
j_min = max(1, j-1)
|
|
66
|
+
j_max = min(j+1, dim[1])
|
|
67
|
+
for k in range(1, dim[2]+1):
|
|
68
|
+
k_min = max(1, k-1)
|
|
69
|
+
k_max = min(k+1, dim[2])
|
|
70
|
+
val_q3 = q_3[i-1, j-1, k-1]
|
|
71
|
+
count = 0
|
|
72
|
+
for I2 in range(i_min, i_max+1):
|
|
73
|
+
for J2 in range(j_min, j_max+1):
|
|
74
|
+
for K2 in range(k_min, k_max+1):
|
|
75
|
+
if (I2 == i) & (J2 == j) & (K2 == k):
|
|
76
|
+
continue
|
|
77
|
+
else:
|
|
78
|
+
# a = 0
|
|
79
|
+
if (val_q3 - q_3[I2-1, J2-1, K2-1] == 0):
|
|
80
|
+
count += 1
|
|
81
|
+
|
|
82
|
+
ngldm[val_q3-1, count] = ngldm[val_q3-1, count] + 1
|
|
83
|
+
|
|
84
|
+
# Last column was for the NaN voxels, to be removed
|
|
85
|
+
ngldm = np.delete(ngldm, -1, 0)
|
|
86
|
+
stop = np.nonzero(np.sum(ngldm, 0))[0][-1]
|
|
87
|
+
ngldm = np.delete(ngldm, range(stop+1, np.shape(ngldm)[1]+1), 1)
|
|
88
|
+
|
|
89
|
+
return ngldm
|
|
90
|
+
|
|
91
|
+
def extract_all(vol: np.ndarray) -> Dict :
|
|
92
|
+
"""Compute NGLDM features
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
vol (np.ndarray): volume with discretised intensities as 3D numpy array (x, y, z)
|
|
96
|
+
method (str, optional): Either 'old' (deprecated) or 'new' (faster) method.
|
|
97
|
+
|
|
98
|
+
Raises:
|
|
99
|
+
ValueError: Ngldm should either be calculated using the faster \"new\" method, or the slow \"old\" method.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
dict: Dictionary of NGTDM features.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
ngldm = get_ngldm_features(vol=vol)
|
|
106
|
+
|
|
107
|
+
return ngldm
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def get_ngldm_features(vol: np.ndarray,
|
|
111
|
+
ngldm_spatial_method: str="3d",
|
|
112
|
+
ngldm_diff_lvl: float=0.0,
|
|
113
|
+
ngldm_dist: float=1.0) -> Dict:
|
|
114
|
+
"""Extract neighbouring grey level dependence matrix-based features from the intensity roi mask.
|
|
115
|
+
These features refer to "Neighbouring grey level dependence based features" (ID = REK0) in
|
|
116
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
|
|
120
|
+
vol (ndarray): volume with discretised intensities as 3D numpy array (x, y, z).
|
|
121
|
+
intensity_range (ndarray): range of potential discretised intensities,
|
|
122
|
+
provided as a list: [minimal discretised intensity, maximal discretised intensity].
|
|
123
|
+
If one or both values are unknown, replace the respective values with np.nan.
|
|
124
|
+
ngldm_spatial_method(str): spatial method which determines the way neighbouring grey level dependence
|
|
125
|
+
matrices are calculated and how features are determined. One of "2d", "2.5d" or "3d".
|
|
126
|
+
ngldm_diff_lvl (float): also called coarseness. Coarseness determines which intensity
|
|
127
|
+
differences are allowed for intensities to be considered similar. Typically 0, and
|
|
128
|
+
changing discretisation levels may have the same effect as increasing
|
|
129
|
+
the coarseness parameter.
|
|
130
|
+
ngldm_dist (float): the chebyshev distance that forms a local neighbourhood around a center voxel.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
dict: dictionary with feature values.
|
|
134
|
+
"""
|
|
135
|
+
if type(ngldm_spatial_method) is not list:
|
|
136
|
+
ngldm_spatial_method = [ngldm_spatial_method]
|
|
137
|
+
|
|
138
|
+
if type(ngldm_diff_lvl) is not list:
|
|
139
|
+
ngldm_diff_lvl = [ngldm_diff_lvl]
|
|
140
|
+
|
|
141
|
+
if type(ngldm_dist) is not list:
|
|
142
|
+
ngldm_dist = [ngldm_dist]
|
|
143
|
+
|
|
144
|
+
# Get the roi in tabular format
|
|
145
|
+
img_dims = vol.shape
|
|
146
|
+
index_id = np.arange(start=0, stop=vol.size)
|
|
147
|
+
coords = np.unravel_index(indices=index_id, shape=img_dims)
|
|
148
|
+
df_img = pd.DataFrame({"index_id": index_id,
|
|
149
|
+
"g": np.ravel(vol),
|
|
150
|
+
"x": coords[0],
|
|
151
|
+
"y": coords[1],
|
|
152
|
+
"z": coords[2],
|
|
153
|
+
"roi_int_mask": np.ravel(np.isfinite(vol))})
|
|
154
|
+
|
|
155
|
+
# Generate an empty feature list
|
|
156
|
+
feat_list = []
|
|
157
|
+
|
|
158
|
+
# Iterate over spatial arrangements
|
|
159
|
+
for ii_spatial in ngldm_spatial_method:
|
|
160
|
+
|
|
161
|
+
# Iterate over difference levels
|
|
162
|
+
for ii_diff_lvl in ngldm_diff_lvl:
|
|
163
|
+
|
|
164
|
+
# Iterate over distances
|
|
165
|
+
for ii_dist in ngldm_dist:
|
|
166
|
+
|
|
167
|
+
# Initiate list of ngldm objects
|
|
168
|
+
ngldm_list = []
|
|
169
|
+
|
|
170
|
+
# Perform 2D analysis
|
|
171
|
+
if ii_spatial.lower() in ["2d", "2.5d"]:
|
|
172
|
+
|
|
173
|
+
# Iterate over slices
|
|
174
|
+
for ii_slice in np.arange(0, img_dims[2]):
|
|
175
|
+
|
|
176
|
+
# Add ngldm matrices to list
|
|
177
|
+
ngldm_list += [GreyLevelDependenceMatrix(distance=int(ii_dist), diff_lvl=ii_diff_lvl,
|
|
178
|
+
spatial_method=ii_spatial.lower(), img_slice=ii_slice)]
|
|
179
|
+
|
|
180
|
+
# Perform 3D analysis
|
|
181
|
+
elif ii_spatial.lower() == "3d":
|
|
182
|
+
|
|
183
|
+
# Add ngldm matrices to list
|
|
184
|
+
ngldm_list += [GreyLevelDependenceMatrix(distance=int(ii_dist), diff_lvl=ii_diff_lvl,
|
|
185
|
+
spatial_method=ii_spatial.lower(), img_slice=None)]
|
|
186
|
+
else:
|
|
187
|
+
raise ValueError("Spatial methods for ngldm should be \"2d\", \"2.5d\" or \"3d\".")
|
|
188
|
+
|
|
189
|
+
# Calculate ngldm matrices
|
|
190
|
+
for ngldm in ngldm_list:
|
|
191
|
+
ngldm.calculate_ngldm_matrix(df_img=df_img, img_dims=img_dims)
|
|
192
|
+
|
|
193
|
+
# Merge matrices according to the given method
|
|
194
|
+
upd_list = combine_ngldm_matrices(ngldm_list=ngldm_list, spatial_method=ii_spatial.lower())
|
|
195
|
+
|
|
196
|
+
# Calculate features
|
|
197
|
+
feat_run_list = []
|
|
198
|
+
for ngldm in upd_list:
|
|
199
|
+
feat_run_list += [ngldm.compute_ngldm_features()]
|
|
200
|
+
|
|
201
|
+
# Average feature values
|
|
202
|
+
feat_list += [pd.concat(feat_run_list, axis=0).mean(axis=0, skipna=True).to_frame().transpose()]
|
|
203
|
+
|
|
204
|
+
# Merge feature tables into a single dictionary
|
|
205
|
+
df_feat = pd.concat(feat_list, axis=1).to_dict(orient="records")[0]
|
|
206
|
+
|
|
207
|
+
return df_feat
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def combine_ngldm_matrices(ngldm_list: List,
|
|
211
|
+
spatial_method: str) -> List:
|
|
212
|
+
"""Function to merge neighbouring grey level dependence matrices prior to feature calculation.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
ngldm_list (List): list of GreyLevelDependenceMatrix objects.
|
|
216
|
+
spatial_method (str): spatial method which determines the way neighbouring grey level
|
|
217
|
+
dependence matrices are calculated and how features are determined.
|
|
218
|
+
One of "2d", "2.5d" or "3d".
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
List: list of one or more merged GreyLevelDependenceMatrix objects.
|
|
222
|
+
"""
|
|
223
|
+
# Initiate empty list
|
|
224
|
+
use_list = []
|
|
225
|
+
|
|
226
|
+
if spatial_method == "2d":
|
|
227
|
+
# Average features over slice: maintain original ngldms
|
|
228
|
+
|
|
229
|
+
# Make copy of ngldm_list
|
|
230
|
+
use_list = []
|
|
231
|
+
for ngldm in ngldm_list:
|
|
232
|
+
use_list += [ngldm.copy()]
|
|
233
|
+
|
|
234
|
+
elif spatial_method in ["2.5d", "3d"]:
|
|
235
|
+
# Merge all ngldms into a single representation
|
|
236
|
+
|
|
237
|
+
# Select all matrices within the slice
|
|
238
|
+
sel_matrix_list = []
|
|
239
|
+
for ngldm_id in np.arange(len(ngldm_list)):
|
|
240
|
+
sel_matrix_list += [ngldm_list[ngldm_id].matrix]
|
|
241
|
+
|
|
242
|
+
# Check if any matrix has been created
|
|
243
|
+
if is_list_all_none(sel_matrix_list):
|
|
244
|
+
# No matrix was created
|
|
245
|
+
use_list += [GreyLevelDependenceMatrix(distance=ngldm_list[0].distance, diff_lvl=ngldm_list[0].diff_lvl,
|
|
246
|
+
spatial_method=spatial_method, img_slice=None, matrix=None, n_v=0.0)]
|
|
247
|
+
else:
|
|
248
|
+
# Merge neighbouring grey level difference matrices
|
|
249
|
+
merge_ngldm = pd.concat(sel_matrix_list, axis=0)
|
|
250
|
+
merge_ngldm = merge_ngldm.groupby(by=["i", "j"]).sum().reset_index()
|
|
251
|
+
|
|
252
|
+
# Update the number of voxels
|
|
253
|
+
merge_n_v = 0.0
|
|
254
|
+
for ngldm_id in np.arange(len(ngldm_list)):
|
|
255
|
+
merge_n_v += ngldm_list[ngldm_id].n_v
|
|
256
|
+
|
|
257
|
+
# Create new neighbouring grey level difference matrix
|
|
258
|
+
use_list += [GreyLevelDependenceMatrix(distance=ngldm_list[0].distance, diff_lvl=ngldm_list[0].diff_lvl,
|
|
259
|
+
spatial_method=spatial_method, img_slice=None, matrix=merge_ngldm, n_v=merge_n_v)]
|
|
260
|
+
else:
|
|
261
|
+
use_list = None
|
|
262
|
+
|
|
263
|
+
# Return to new ngldm list to calling function
|
|
264
|
+
return use_list
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class GreyLevelDependenceMatrix:
|
|
268
|
+
|
|
269
|
+
def __init__(self,
|
|
270
|
+
distance: float,
|
|
271
|
+
diff_lvl: float,
|
|
272
|
+
spatial_method: str,
|
|
273
|
+
img_slice: np.ndarray=None,
|
|
274
|
+
matrix: np.ndarray=None,
|
|
275
|
+
n_v: float=None) -> None:
|
|
276
|
+
"""Initialising function for a new neighbouring grey level dependence ``matrix``.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
distance (float): chebyshev ``distance`` used to determine the local neighbourhood.
|
|
280
|
+
diff_lvl (float): coarseness parameter which determines which intensities are considered similar.
|
|
281
|
+
spatial_method (str): spatial method used to calculate the ngldm: 2d, 2.5d or 3d
|
|
282
|
+
img_slice (ndarray): corresponding slice index (only if the ngldm corresponds to a 2d image slice)
|
|
283
|
+
matrix (ndarray): the actual ngldm in sparse format (row, column, count)
|
|
284
|
+
n_v (float): the number of voxels in the volume
|
|
285
|
+
"""
|
|
286
|
+
|
|
287
|
+
# Distance used
|
|
288
|
+
self.distance = distance
|
|
289
|
+
self.diff_lvl = diff_lvl
|
|
290
|
+
|
|
291
|
+
# Slice for which the current matrix is extracted
|
|
292
|
+
self.img_slice = img_slice
|
|
293
|
+
|
|
294
|
+
# Spatial analysis method (2d, 2.5d, 3d)
|
|
295
|
+
self.spatial_method = spatial_method
|
|
296
|
+
|
|
297
|
+
# Place holders
|
|
298
|
+
self.matrix = matrix
|
|
299
|
+
self.n_v = n_v
|
|
300
|
+
|
|
301
|
+
def copy(self):
|
|
302
|
+
"""Returns a copy of the GreyLevelDependenceMatrix object."""
|
|
303
|
+
return deepcopy(self)
|
|
304
|
+
|
|
305
|
+
def set_empty(self):
|
|
306
|
+
"""Creates an empty GreyLevelDependenceMatrix"""
|
|
307
|
+
self.n_v = 0
|
|
308
|
+
self.matrix = None
|
|
309
|
+
|
|
310
|
+
def calculate_ngldm_matrix(self,
|
|
311
|
+
df_img: pd.DataFrame,
|
|
312
|
+
img_dims: int):
|
|
313
|
+
"""
|
|
314
|
+
Function that calculates an ngldm for the settings provided during initialisation and the input image.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
df_img (pd.DataFrame): data table containing image intensities, x, y and z coordinates,
|
|
318
|
+
and mask labels corresponding to voxels in the volume.
|
|
319
|
+
img_dims (int): dimensions of the image volume
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
# Check if the input image and roi exist
|
|
323
|
+
if df_img is None:
|
|
324
|
+
self.set_empty()
|
|
325
|
+
return
|
|
326
|
+
|
|
327
|
+
# Check if the roi contains any masked voxels. If this is not the case, don't construct the ngldm.
|
|
328
|
+
if not np.any(df_img.roi_int_mask):
|
|
329
|
+
self.set_empty()
|
|
330
|
+
return
|
|
331
|
+
|
|
332
|
+
if self.spatial_method == "3d":
|
|
333
|
+
# Set up neighbour vectors
|
|
334
|
+
nbrs = get_neighbour_direction(d=self.distance, distance="chebyshev", centre=False, complete=True, dim3=True)
|
|
335
|
+
|
|
336
|
+
# Set up work copy
|
|
337
|
+
df_ngldm = deepcopy(df_img)
|
|
338
|
+
elif self.spatial_method in ["2d", "2.5d"]:
|
|
339
|
+
# Set up neighbour vectors
|
|
340
|
+
nbrs = get_neighbour_direction(d=self.distance, distance="chebyshev", centre=False, complete=True, dim3=False)
|
|
341
|
+
|
|
342
|
+
# Set up work copy
|
|
343
|
+
df_ngldm = deepcopy(df_img[df_img.z == self.img_slice])
|
|
344
|
+
df_ngldm["index_id"] = np.arange(0, len(df_ngldm))
|
|
345
|
+
df_ngldm["z"] = 0
|
|
346
|
+
df_ngldm = df_ngldm.reset_index(drop=True)
|
|
347
|
+
else:
|
|
348
|
+
raise ValueError("The spatial method for neighbouring grey level dependence matrices should be one of \"2d\", \"2.5d\" or \"3d\".")
|
|
349
|
+
|
|
350
|
+
# Set grey level of voxels outside ROI to NaN
|
|
351
|
+
df_ngldm.loc[df_ngldm.roi_int_mask == False, "g"] = np.nan
|
|
352
|
+
|
|
353
|
+
# Update number of voxels for current iteration
|
|
354
|
+
self.n_v = np.sum(df_ngldm.roi_int_mask.values)
|
|
355
|
+
|
|
356
|
+
# Initialise sum of grey levels and number of neighbours
|
|
357
|
+
df_ngldm["occur"] = 0.0
|
|
358
|
+
df_ngldm["n_nbrs"] = 0.0
|
|
359
|
+
|
|
360
|
+
for k in range(0, np.shape(nbrs)[1]):
|
|
361
|
+
# Determine potential transitions from valid voxels
|
|
362
|
+
df_ngldm["to_index"] = coord2index(x=df_ngldm.x.values + nbrs[2, k],
|
|
363
|
+
y=df_ngldm.y.values + nbrs[1, k],
|
|
364
|
+
z=df_ngldm.z.values + nbrs[0, k],
|
|
365
|
+
dims=img_dims)
|
|
366
|
+
|
|
367
|
+
# Get grey level value from transitions
|
|
368
|
+
df_ngldm["to_g"] = get_value(x=df_ngldm.g.values, index=df_ngldm.to_index.values)
|
|
369
|
+
|
|
370
|
+
# Determine which voxels have valid neighbours
|
|
371
|
+
sel_index = np.isfinite(df_ngldm.to_g)
|
|
372
|
+
|
|
373
|
+
# Determine co-occurrence within diff_lvl
|
|
374
|
+
df_ngldm.loc[sel_index, "occur"] += ((np.abs(df_ngldm.to_g - df_ngldm.g)[sel_index]) <= self.diff_lvl) * 1
|
|
375
|
+
|
|
376
|
+
# Work with voxels within the intensity roi
|
|
377
|
+
df_ngldm = df_ngldm[df_ngldm.roi_int_mask]
|
|
378
|
+
|
|
379
|
+
# Drop superfluous columns
|
|
380
|
+
df_ngldm = df_ngldm.drop(labels=["index_id", "x", "y", "z", "to_index", "to_g", "roi_int_mask"], axis=1)
|
|
381
|
+
|
|
382
|
+
# Sum s over voxels
|
|
383
|
+
df_ngldm = df_ngldm.groupby(by=["g", "occur"]).size().reset_index(name="n")
|
|
384
|
+
|
|
385
|
+
# Rename columns
|
|
386
|
+
df_ngldm.columns = ["i", "j", "s"]
|
|
387
|
+
|
|
388
|
+
# Add one to dependency count as features are not defined for k=0
|
|
389
|
+
df_ngldm.j += 1.0
|
|
390
|
+
|
|
391
|
+
# Add matrix to object
|
|
392
|
+
self.matrix = df_ngldm
|
|
393
|
+
|
|
394
|
+
def compute_ngldm_features(self) -> pd.DataFrame:
|
|
395
|
+
"""Computes neighbouring grey level dependence matrix features for the current neighbouring grey level dependence matrix.
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
pandas data frame: with values for each feature.
|
|
399
|
+
"""
|
|
400
|
+
# Create feature table
|
|
401
|
+
feat_names = ["Fngl_lde",
|
|
402
|
+
"Fngl_hde",
|
|
403
|
+
"Fngl_lgce",
|
|
404
|
+
"Fngl_hgce",
|
|
405
|
+
"Fngl_ldlge",
|
|
406
|
+
"Fngl_ldhge",
|
|
407
|
+
"Fngl_hdlge",
|
|
408
|
+
"Fngl_hdhge",
|
|
409
|
+
"Fngl_glnu",
|
|
410
|
+
"Fngl_glnu_norm",
|
|
411
|
+
"Fngl_dcnu",
|
|
412
|
+
"Fngl_dcnu_norm",
|
|
413
|
+
"Fngl_gl_var",
|
|
414
|
+
"Fngl_dc_var",
|
|
415
|
+
"Fngl_dc_entr",
|
|
416
|
+
"Fngl_dc_energy"]
|
|
417
|
+
df_feat = pd.DataFrame(np.full(shape=(1, len(feat_names)), fill_value=np.nan))
|
|
418
|
+
df_feat.columns = feat_names
|
|
419
|
+
|
|
420
|
+
# Don't return data for empty slices or slices without a good matrix
|
|
421
|
+
if self.matrix is None:
|
|
422
|
+
# Update names
|
|
423
|
+
# df_feat.columns += self.parse_feature_names()
|
|
424
|
+
return df_feat
|
|
425
|
+
elif len(self.matrix) == 0:
|
|
426
|
+
# Update names
|
|
427
|
+
# df_feat.columns += self.parse_feature_names()
|
|
428
|
+
return df_feat
|
|
429
|
+
|
|
430
|
+
# Dependence count dataframe
|
|
431
|
+
df_sij = deepcopy(self.matrix)
|
|
432
|
+
df_sij.columns = ("i", "j", "sij")
|
|
433
|
+
|
|
434
|
+
# Sum over grey levels
|
|
435
|
+
df_si = df_sij.groupby(by="i")["sij"].agg(np.sum).reset_index().rename(columns={"sij": "si"})
|
|
436
|
+
|
|
437
|
+
# Sum over dependence counts
|
|
438
|
+
df_sj = df_sij.groupby(by="j")["sij"].agg(np.sum).reset_index().rename(columns={"sij": "sj"})
|
|
439
|
+
|
|
440
|
+
# Constant definitions
|
|
441
|
+
n_s = np.sum(df_sij.sij) * 1.0 # Number of neighbourhoods considered
|
|
442
|
+
n_v = self.n_v # Number of voxels
|
|
443
|
+
|
|
444
|
+
###############################################
|
|
445
|
+
# ngldm features
|
|
446
|
+
###############################################
|
|
447
|
+
|
|
448
|
+
# Low dependence emphasis
|
|
449
|
+
df_feat.loc[0, "Fngl_lde"] = np.sum(df_sj.sj / df_sj.j ** 2.0) / n_s
|
|
450
|
+
|
|
451
|
+
# High dependence emphasis
|
|
452
|
+
df_feat.loc[0, "Fngl_hde"] = np.sum(df_sj.sj * df_sj.j ** 2.0) / n_s
|
|
453
|
+
|
|
454
|
+
# Grey level non-uniformity
|
|
455
|
+
df_feat.loc[0, "Fngl_glnu"] = np.sum(df_si.si ** 2.0) / n_s
|
|
456
|
+
|
|
457
|
+
# Grey level non-uniformity, normalised
|
|
458
|
+
df_feat.loc[0, "Fngl_glnu_norm"] = np.sum(df_si.si ** 2.0) / n_s ** 2.0
|
|
459
|
+
|
|
460
|
+
# Dependence count non-uniformity
|
|
461
|
+
df_feat.loc[0, "Fngl_dcnu"] = np.sum(df_sj.sj ** 2.0) / n_s
|
|
462
|
+
|
|
463
|
+
# Dependence count non-uniformity, normalised
|
|
464
|
+
df_feat.loc[0, "Fngl_dcnu_norm"] = np.sum(df_sj.sj ** 2.0) / n_s ** 2.0
|
|
465
|
+
|
|
466
|
+
# Dependence count percentage
|
|
467
|
+
# df_feat.loc[0, "ngl_dc_perc"] = n_s / n_v
|
|
468
|
+
|
|
469
|
+
# Low grey level count emphasis
|
|
470
|
+
df_feat.loc[0, "Fngl_lgce"] = np.sum(df_si.si / df_si.i ** 2.0) / n_s
|
|
471
|
+
|
|
472
|
+
# High grey level count emphasis
|
|
473
|
+
df_feat.loc[0, "Fngl_hgce"] = np.sum(df_si.si * df_si.i ** 2.0) / n_s
|
|
474
|
+
|
|
475
|
+
# Low dependence low grey level emphasis
|
|
476
|
+
df_feat.loc[0, "Fngl_ldlge"] = np.sum(df_sij.sij / (df_sij.i * df_sij.j) ** 2.0) / n_s
|
|
477
|
+
|
|
478
|
+
# Low dependence high grey level emphasis
|
|
479
|
+
df_feat.loc[0, "Fngl_ldhge"] = np.sum(df_sij.sij * df_sij.i ** 2.0 / df_sij.j ** 2.0) / n_s
|
|
480
|
+
|
|
481
|
+
# High dependence low grey level emphasis
|
|
482
|
+
df_feat.loc[0, "Fngl_hdlge"] = np.sum(df_sij.sij * df_sij.j ** 2.0 / df_sij.i ** 2.0) / n_s
|
|
483
|
+
|
|
484
|
+
# High dependence high grey level emphasis
|
|
485
|
+
df_feat.loc[0, "Fngl_hdhge"] = np.sum(df_sij.sij * df_sij.i ** 2.0 * df_sij.j ** 2.0) / n_s
|
|
486
|
+
|
|
487
|
+
# Grey level variance
|
|
488
|
+
mu = np.sum(df_sij.sij * df_sij.i) / n_s
|
|
489
|
+
df_feat.loc[0, "Fngl_gl_var"] = np.sum((df_sij.i - mu) ** 2.0 * df_sij.sij) / n_s
|
|
490
|
+
del mu
|
|
491
|
+
|
|
492
|
+
# Dependence count variance
|
|
493
|
+
mu = np.sum(df_sij.sij * df_sij.j) / n_s
|
|
494
|
+
df_feat.loc[0, "Fngl_dc_var"] = np.sum((df_sij.j - mu) ** 2.0 * df_sij.sij) / n_s
|
|
495
|
+
del mu
|
|
496
|
+
|
|
497
|
+
# Dependence count entropy
|
|
498
|
+
df_feat.loc[0, "Fngl_dc_entr"] = - np.sum(df_sij.sij * np.log2(df_sij.sij / n_s)) / n_s
|
|
499
|
+
|
|
500
|
+
# Dependence count energy
|
|
501
|
+
df_feat.loc[0, "Fngl_dc_energy"] = np.sum(df_sij.sij ** 2.0) / (n_s ** 2.0)
|
|
502
|
+
|
|
503
|
+
# Update names
|
|
504
|
+
# df_feat.columns += self.parse_feature_names()
|
|
505
|
+
|
|
506
|
+
return df_feat
|
|
507
|
+
|
|
508
|
+
def parse_feature_names(self):
|
|
509
|
+
"""
|
|
510
|
+
Adds additional settings-related identifiers to each feature.
|
|
511
|
+
Not used currently, as the use of different settings for the
|
|
512
|
+
neighbouring grey level dependence matrix is not supported.
|
|
513
|
+
"""
|
|
514
|
+
parse_str = ""
|
|
515
|
+
|
|
516
|
+
# Add distance
|
|
517
|
+
parse_str += "_d" + str(np.round(self.distance, 1))
|
|
518
|
+
|
|
519
|
+
# Add difference level
|
|
520
|
+
parse_str += "_a" + str(np.round(self.diff_lvl, 0))
|
|
521
|
+
|
|
522
|
+
# Add spatial method
|
|
523
|
+
if self.spatial_method is not None:
|
|
524
|
+
parse_str += "_" + self.spatial_method
|
|
525
|
+
|
|
526
|
+
return parse_str
|
|
527
|
+
|
|
528
|
+
def get_dict(vol: np.ndarray) -> dict:
|
|
529
|
+
"""
|
|
530
|
+
Extract neighbouring grey level dependence matrix-based features from the intensity roi mask.
|
|
531
|
+
|
|
532
|
+
Args:
|
|
533
|
+
vol (ndarray): volume with discretised intensities as 3D numpy array (x, y, z)
|
|
534
|
+
|
|
535
|
+
Returns:
|
|
536
|
+
dict: dictionary with feature values
|
|
537
|
+
|
|
538
|
+
"""
|
|
539
|
+
ngldm_dict = get_ngldm_features(vol, intensity_range=[np.nan, np.nan])
|
|
540
|
+
return ngldm_dict
|
|
541
|
+
|
|
542
|
+
def lde(ngldm_dict: np.ndarray)-> float:
|
|
543
|
+
"""
|
|
544
|
+
Computes low dependence emphasis feature.
|
|
545
|
+
This feature refers to "Fngl_lde" (ID = SODN) in
|
|
546
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
547
|
+
|
|
548
|
+
Args:
|
|
549
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
550
|
+
|
|
551
|
+
Returns:
|
|
552
|
+
float: low depence emphasis value
|
|
553
|
+
|
|
554
|
+
"""
|
|
555
|
+
return ngldm_dict["Fngl_lde"]
|
|
556
|
+
|
|
557
|
+
def hde(ngldm_dict: np.ndarray)-> float:
|
|
558
|
+
"""
|
|
559
|
+
Computes high dependence emphasis feature.
|
|
560
|
+
This feature refers to "Fngl_hde" (ID = IMOQ) in
|
|
561
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
562
|
+
|
|
563
|
+
Args:
|
|
564
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
565
|
+
|
|
566
|
+
Returns:
|
|
567
|
+
float: high depence emphasis value
|
|
568
|
+
|
|
569
|
+
"""
|
|
570
|
+
return ngldm_dict["Fngl_hde"]
|
|
571
|
+
|
|
572
|
+
def lgce(ngldm_dict: np.ndarray)-> float:
|
|
573
|
+
"""
|
|
574
|
+
Computes low grey level count emphasis feature.
|
|
575
|
+
This feature refers to "Fngl_lgce" (ID = TL9H) in
|
|
576
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
577
|
+
|
|
578
|
+
Args:
|
|
579
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
580
|
+
|
|
581
|
+
Returns:
|
|
582
|
+
float: low grey level count emphasis value
|
|
583
|
+
|
|
584
|
+
"""
|
|
585
|
+
return ngldm_dict["Fngl_lgce"]
|
|
586
|
+
|
|
587
|
+
def hgce(ngldm_dict: np.ndarray)-> float:
|
|
588
|
+
"""
|
|
589
|
+
Computes high grey level count emphasis feature.
|
|
590
|
+
This feature refers to "Fngl_hgce" (ID = OAE7) in
|
|
591
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
592
|
+
|
|
593
|
+
Args:
|
|
594
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
595
|
+
|
|
596
|
+
Returns:
|
|
597
|
+
float: high grey level count emphasis value
|
|
598
|
+
|
|
599
|
+
"""
|
|
600
|
+
return ngldm_dict["Fngl_hgce"]
|
|
601
|
+
|
|
602
|
+
def ldlge(ngldm_dict: np.ndarray)-> float:
|
|
603
|
+
"""
|
|
604
|
+
Computes low dependence low grey level emphasis feature.
|
|
605
|
+
This feature refers to "Fngl_ldlge" (ID = EQ3F) in
|
|
606
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
607
|
+
|
|
608
|
+
Args:
|
|
609
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
610
|
+
|
|
611
|
+
Returns:
|
|
612
|
+
float: low dependence low grey level emphasis value
|
|
613
|
+
|
|
614
|
+
"""
|
|
615
|
+
return ngldm_dict["Fngl_ldlge"]
|
|
616
|
+
|
|
617
|
+
def ldhge(ngldm_dict: np.ndarray)-> float:
|
|
618
|
+
"""
|
|
619
|
+
Computes low dependence high grey level emphasis feature.
|
|
620
|
+
This feature refers to "Fngl_ldhge" (ID = JA6D) in
|
|
621
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
622
|
+
|
|
623
|
+
Args:
|
|
624
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
625
|
+
|
|
626
|
+
Returns:
|
|
627
|
+
float: low dependence high grey level emphasis value
|
|
628
|
+
|
|
629
|
+
"""
|
|
630
|
+
return ngldm_dict["Fngl_ldhge"]
|
|
631
|
+
|
|
632
|
+
def hdlge(ngldm_dict: np.ndarray)-> float:
|
|
633
|
+
"""
|
|
634
|
+
Computes high dependence low grey level emphasis feature.
|
|
635
|
+
This feature refers to "Fngl_hdlge" (ID = NBZI) in
|
|
636
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
637
|
+
|
|
638
|
+
Args:
|
|
639
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
640
|
+
|
|
641
|
+
Returns:
|
|
642
|
+
float: high dependence low grey level emphasis value
|
|
643
|
+
|
|
644
|
+
"""
|
|
645
|
+
return ngldm_dict["Fngl_hdlge"]
|
|
646
|
+
|
|
647
|
+
def hdhge(ngldm_dict: np.ndarray)-> float:
|
|
648
|
+
"""
|
|
649
|
+
Computes high dependence high grey level emphasis feature.
|
|
650
|
+
This feature refers to "Fngl_hdhge" (ID = 9QMG) in
|
|
651
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
652
|
+
|
|
653
|
+
Args:
|
|
654
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
655
|
+
|
|
656
|
+
Returns:
|
|
657
|
+
float: high dependence high grey level emphasis value
|
|
658
|
+
|
|
659
|
+
"""
|
|
660
|
+
return ngldm_dict["Fngl_hdhge"]
|
|
661
|
+
|
|
662
|
+
def glnu(ngldm_dict: np.ndarray)-> float:
|
|
663
|
+
"""
|
|
664
|
+
Computes grey level non-uniformity feature.
|
|
665
|
+
This feature refers to "Fngl_glnu" (ID = FP8K) in
|
|
666
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
667
|
+
|
|
668
|
+
Args:
|
|
669
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
670
|
+
|
|
671
|
+
Returns:
|
|
672
|
+
float: grey level non-uniformity value
|
|
673
|
+
|
|
674
|
+
"""
|
|
675
|
+
return ngldm_dict["Fngl_glnu"]
|
|
676
|
+
|
|
677
|
+
def glnu_norm(ngldm_dict: np.ndarray)-> float:
|
|
678
|
+
"""
|
|
679
|
+
Computes grey level non-uniformity normalised feature.
|
|
680
|
+
This feature refers to "Fngl_glnu_norm" (ID = 5SPA) in
|
|
681
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
682
|
+
|
|
683
|
+
Args:
|
|
684
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
685
|
+
|
|
686
|
+
Returns:
|
|
687
|
+
float: grey level non-uniformity normalised value
|
|
688
|
+
|
|
689
|
+
"""
|
|
690
|
+
return ngldm_dict["Fngl_glnu_norm"]
|
|
691
|
+
|
|
692
|
+
def dcnu(ngldm_dict: np.ndarray)-> float:
|
|
693
|
+
"""
|
|
694
|
+
Computes dependence count non-uniformity feature.
|
|
695
|
+
This feature refers to "Fngl_dcnu" (ID = Z87G) in
|
|
696
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
697
|
+
|
|
698
|
+
Args:
|
|
699
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
700
|
+
|
|
701
|
+
Returns:
|
|
702
|
+
float: dependence count non-uniformity value
|
|
703
|
+
|
|
704
|
+
"""
|
|
705
|
+
return ngldm_dict["Fngl_dcnu"]
|
|
706
|
+
|
|
707
|
+
def dcnu_norm(ngldm_dict: np.ndarray)-> float:
|
|
708
|
+
"""
|
|
709
|
+
Computes dependence count non-uniformity normalised feature.
|
|
710
|
+
This feature refers to "Fngl_dcnu_norm" (ID = OKJI) in
|
|
711
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
712
|
+
|
|
713
|
+
Args:
|
|
714
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
715
|
+
|
|
716
|
+
Returns:
|
|
717
|
+
float: dependence count non-uniformity normalised value
|
|
718
|
+
|
|
719
|
+
"""
|
|
720
|
+
return ngldm_dict["Fngl_dcnu_norm"]
|
|
721
|
+
|
|
722
|
+
def gl_var(ngldm_dict: np.ndarray)-> float:
|
|
723
|
+
"""
|
|
724
|
+
Computes grey level variance feature.
|
|
725
|
+
This feature refers to "Fngl_gl_var" (ID = 1PFV) in
|
|
726
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
727
|
+
|
|
728
|
+
Args:
|
|
729
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
730
|
+
|
|
731
|
+
Returns:
|
|
732
|
+
float: grey level variance value
|
|
733
|
+
|
|
734
|
+
"""
|
|
735
|
+
return ngldm_dict["Fngl_gl_var"]
|
|
736
|
+
|
|
737
|
+
def dc_var(ngldm_dict: np.ndarray)-> float:
|
|
738
|
+
"""
|
|
739
|
+
Computes dependence count variance feature.
|
|
740
|
+
This feature refers to "Fngl_dc_var" (ID = DNX2) in
|
|
741
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
742
|
+
|
|
743
|
+
Args:
|
|
744
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
745
|
+
|
|
746
|
+
Returns:
|
|
747
|
+
float: dependence count variance value
|
|
748
|
+
|
|
749
|
+
"""
|
|
750
|
+
return ngldm_dict["Fngl_dc_var"]
|
|
751
|
+
|
|
752
|
+
def dc_entr(ngldm_dict: np.ndarray)-> float:
|
|
753
|
+
"""
|
|
754
|
+
Computes dependence count entropy feature.
|
|
755
|
+
This feature refers to "Fngl_dc_entr" (ID = FCBV) in
|
|
756
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
757
|
+
|
|
758
|
+
Args:
|
|
759
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
760
|
+
|
|
761
|
+
Returns:
|
|
762
|
+
float: dependence count entropy value
|
|
763
|
+
|
|
764
|
+
"""
|
|
765
|
+
return ngldm_dict["Fngl_dc_entr"]
|
|
766
|
+
|
|
767
|
+
def dc_energy(ngldm_dict: np.ndarray)-> float:
|
|
768
|
+
"""
|
|
769
|
+
Computes dependence count energy feature.
|
|
770
|
+
This feature refers to "Fngl_dc_energy" (ID = CAS9) in
|
|
771
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
772
|
+
|
|
773
|
+
Args:
|
|
774
|
+
ngldm (ndarray): array of neighbouring grey level dependence matrix
|
|
775
|
+
|
|
776
|
+
Returns:
|
|
777
|
+
float: dependence count energy value
|
|
778
|
+
|
|
779
|
+
"""
|
|
780
|
+
return ngldm_dict["Fngl_dc_energy"]
|