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.
Files changed (78) hide show
  1. MEDiml/MEDscan.py +1696 -0
  2. MEDiml/__init__.py +21 -0
  3. MEDiml/biomarkers/BatchExtractor.py +806 -0
  4. MEDiml/biomarkers/BatchExtractorTexturalFilters.py +840 -0
  5. MEDiml/biomarkers/__init__.py +16 -0
  6. MEDiml/biomarkers/diagnostics.py +125 -0
  7. MEDiml/biomarkers/get_oriented_bound_box.py +158 -0
  8. MEDiml/biomarkers/glcm.py +1602 -0
  9. MEDiml/biomarkers/gldzm.py +523 -0
  10. MEDiml/biomarkers/glrlm.py +1315 -0
  11. MEDiml/biomarkers/glszm.py +555 -0
  12. MEDiml/biomarkers/int_vol_hist.py +527 -0
  13. MEDiml/biomarkers/intensity_histogram.py +615 -0
  14. MEDiml/biomarkers/local_intensity.py +89 -0
  15. MEDiml/biomarkers/morph.py +1756 -0
  16. MEDiml/biomarkers/ngldm.py +780 -0
  17. MEDiml/biomarkers/ngtdm.py +414 -0
  18. MEDiml/biomarkers/stats.py +373 -0
  19. MEDiml/biomarkers/utils.py +389 -0
  20. MEDiml/filters/TexturalFilter.py +299 -0
  21. MEDiml/filters/__init__.py +9 -0
  22. MEDiml/filters/apply_filter.py +134 -0
  23. MEDiml/filters/gabor.py +215 -0
  24. MEDiml/filters/laws.py +283 -0
  25. MEDiml/filters/log.py +147 -0
  26. MEDiml/filters/mean.py +121 -0
  27. MEDiml/filters/textural_filters_kernels.py +1738 -0
  28. MEDiml/filters/utils.py +107 -0
  29. MEDiml/filters/wavelet.py +237 -0
  30. MEDiml/learning/DataCleaner.py +198 -0
  31. MEDiml/learning/DesignExperiment.py +480 -0
  32. MEDiml/learning/FSR.py +667 -0
  33. MEDiml/learning/Normalization.py +112 -0
  34. MEDiml/learning/RadiomicsLearner.py +714 -0
  35. MEDiml/learning/Results.py +2237 -0
  36. MEDiml/learning/Stats.py +694 -0
  37. MEDiml/learning/__init__.py +10 -0
  38. MEDiml/learning/cleaning_utils.py +107 -0
  39. MEDiml/learning/ml_utils.py +1015 -0
  40. MEDiml/processing/__init__.py +6 -0
  41. MEDiml/processing/compute_suv_map.py +121 -0
  42. MEDiml/processing/discretisation.py +149 -0
  43. MEDiml/processing/interpolation.py +275 -0
  44. MEDiml/processing/resegmentation.py +66 -0
  45. MEDiml/processing/segmentation.py +912 -0
  46. MEDiml/utils/__init__.py +25 -0
  47. MEDiml/utils/batch_patients.py +45 -0
  48. MEDiml/utils/create_radiomics_table.py +131 -0
  49. MEDiml/utils/data_frame_export.py +42 -0
  50. MEDiml/utils/find_process_names.py +16 -0
  51. MEDiml/utils/get_file_paths.py +34 -0
  52. MEDiml/utils/get_full_rad_names.py +21 -0
  53. MEDiml/utils/get_institutions_from_ids.py +16 -0
  54. MEDiml/utils/get_patient_id_from_scan_name.py +22 -0
  55. MEDiml/utils/get_patient_names.py +26 -0
  56. MEDiml/utils/get_radiomic_names.py +27 -0
  57. MEDiml/utils/get_scan_name_from_rad_name.py +22 -0
  58. MEDiml/utils/image_reader_SITK.py +37 -0
  59. MEDiml/utils/image_volume_obj.py +22 -0
  60. MEDiml/utils/imref.py +340 -0
  61. MEDiml/utils/initialize_features_names.py +62 -0
  62. MEDiml/utils/inpolygon.py +159 -0
  63. MEDiml/utils/interp3.py +43 -0
  64. MEDiml/utils/json_utils.py +78 -0
  65. MEDiml/utils/mode.py +31 -0
  66. MEDiml/utils/parse_contour_string.py +58 -0
  67. MEDiml/utils/save_MEDscan.py +30 -0
  68. MEDiml/utils/strfind.py +32 -0
  69. MEDiml/utils/textureTools.py +188 -0
  70. MEDiml/utils/texture_features_names.py +115 -0
  71. MEDiml/utils/write_radiomics_csv.py +47 -0
  72. MEDiml/wrangling/DataManager.py +1724 -0
  73. MEDiml/wrangling/ProcessDICOM.py +512 -0
  74. MEDiml/wrangling/__init__.py +3 -0
  75. mediml-0.9.9.dist-info/LICENSE.md +674 -0
  76. mediml-0.9.9.dist-info/METADATA +232 -0
  77. mediml-0.9.9.dist-info/RECORD +78 -0
  78. mediml-0.9.9.dist-info/WHEEL +4 -0
@@ -0,0 +1,523 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ from typing import Dict, List, Union
6
+
7
+ import numpy as np
8
+ import scipy.ndimage as sc
9
+ import skimage.measure as skim
10
+
11
+
12
+ def get_matrix(roi_only_int: np.ndarray,
13
+ mask: np.ndarray,
14
+ levels: Union[np.ndarray, List]) -> np.ndarray:
15
+ r"""
16
+ Computes Grey level distance zone matrix.
17
+ This matrix refers to "Grey level distance zone based features" (ID = VMDZ)
18
+ in the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`_.
19
+
20
+ Args:
21
+ roi_only_int (ndarray): 3D volume, isotropically resampled,
22
+ quantized (e.g. n_g = 32, levels = [1, ..., n_g]),
23
+ with NaNs outside the region of interest.
24
+ mask (ndarray): Morphological ROI ``mask``.
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: Grey level distance zone Matrix.
30
+
31
+ Todo:
32
+ ``levels`` should be removed at some point, no longer needed if we always
33
+ quantize our volume such that ``levels = 1,2,3,4,...,max(quantized Volume)``.
34
+ So simply calculate ``levels = 1:max(roi_only(~isnan(roi_only(:))))``
35
+ directly in this function.
36
+
37
+ """
38
+
39
+ roi_only_int = roi_only_int.copy()
40
+ levels = levels.copy().astype("int")
41
+ morph_voxel_grid = mask.copy().astype(np.uint8)
42
+
43
+ # COMPUTATION OF DISTANCE MAP
44
+ morph_voxel_grid = np.pad(morph_voxel_grid,
45
+ [1,1],
46
+ 'constant',
47
+ constant_values=0)
48
+
49
+ # Computing the smallest ROI edge possible.
50
+ # Distances are determined in 3D
51
+ binary_struct = sc.generate_binary_structure(rank=3, connectivity=1)
52
+ perimeter = morph_voxel_grid - sc.binary_erosion(morph_voxel_grid, structure=binary_struct)
53
+ perimeter = perimeter[1:-1,1:-1,1:-1] # Removing the padding.
54
+ morph_voxel_grid = morph_voxel_grid[1:-1,1:-1,1:-1] # Removing the padding
55
+
56
+ # +1 according to the definition of the IBSI
57
+ dist_map = sc.distance_transform_cdt(np.logical_not(perimeter), metric='cityblock') + 1
58
+
59
+ # INITIALIZATION
60
+ # Since levels is always defined as 1,2,3,4,...,max(quantized Volume)
61
+ n_g = np.size(levels)
62
+ level_temp = np.max(levels) + 1
63
+ roi_only_int[np.isnan(roi_only_int)] = level_temp
64
+ # Since the ROI morph always encompasses ROI int,
65
+ # using the mask as defined from ROI morph does not matter since
66
+ # we want to find the maximal possible distance.
67
+ dist_init = np.max(dist_map[morph_voxel_grid == 1])
68
+ gldzm = np.zeros((n_g,dist_init))
69
+
70
+ # COMPUTATION OF gldzm
71
+ temp = roi_only_int.copy().astype('int')
72
+ for i in range(1,n_g+1):
73
+ temp[roi_only_int!=levels[i-1]] = 0
74
+ temp[roi_only_int==levels[i-1]] = 1
75
+ conn_objects, n_zone = skim.label(temp,return_num = True)
76
+ for j in range(1,n_zone+1):
77
+ col = np.min(dist_map[conn_objects==j]).astype("int")
78
+ gldzm[i-1,col-1] = gldzm[i-1,col-1] + 1
79
+
80
+ # REMOVE UNECESSARY COLUMNS
81
+ stop = np.nonzero(np.sum(gldzm,0))[0][-1]
82
+ gldzm = np.delete(gldzm, range(stop+1, np.shape(gldzm)[1]), 1)
83
+
84
+ return gldzm
85
+
86
+ def extract_all(vol_int: np.ndarray,
87
+ mask_morph: np.ndarray,
88
+ gldzm: np.ndarray = None) -> Dict:
89
+ """Computes gldzm features.
90
+ This feature refers to "Grey level distance zone based features" (ID = VMDZ)
91
+ in the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
92
+
93
+ Args:
94
+ vol_int (np.ndarray): 3D volume, isotropically resampled, quantized (e.g. n_g = 32, levels = [1, ..., n_g]),
95
+ with NaNs outside the region of interest.
96
+ mask_morph (np.ndarray): Morphological ROI mask.
97
+ gldzm (np.ndarray, optional): array of the gray level distance zone matrix. Defaults to None.
98
+
99
+ Returns:
100
+ Dict: dict of ``gldzm`` features
101
+ """
102
+ gldzm_features = {'Fdzm_sde': [],
103
+ 'Fdzm_lde': [],
104
+ 'Fdzm_lgze': [],
105
+ 'Fdzm_hgze': [],
106
+ 'Fdzm_sdlge': [],
107
+ 'Fdzm_sdhge': [],
108
+ 'Fdzm_ldlge': [],
109
+ 'Fdzm_ldhge': [],
110
+ 'Fdzm_glnu': [],
111
+ 'Fdzm_glnu_norm': [],
112
+ 'Fdzm_zdnu': [],
113
+ 'Fdzm_zdnu_norm': [],
114
+ 'Fdzm_z_perc': [],
115
+ 'Fdzm_gl_var': [],
116
+ 'Fdzm_zd_var': [],
117
+ 'Fdzm_zd_entr': []}
118
+
119
+ # Correct definition, without any assumption
120
+ levels = np.arange(1, np.max(vol_int[~np.isnan(vol_int[:])])+1)
121
+
122
+ # GET THE gldzm MATRIX
123
+ if gldzm is None:
124
+ gldzm = get_matrix(vol_int, mask_morph, levels)
125
+ n_s = np.sum(gldzm)
126
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
127
+ s_z = np.shape(gldzm) # Size of gldzm
128
+ c_vect = range(1, s_z[1]+1) # Row vectors
129
+ r_vect = range(1, s_z[0]+1) # Column vectors
130
+ # Column and row indicators for each entry of the gldzm
131
+ c_mat, r_mat = np.meshgrid(c_vect, r_vect)
132
+ p_g = np.transpose(np.sum(gldzm, 1)) # Gray-Level Vector
133
+ p_d = np.sum(gldzm, 0) # Distance Zone Vector
134
+
135
+ # COMPUTING TEXTURES
136
+
137
+ # Small distance emphasis
138
+ gldzm_features['Fdzm_sde'] = (np.matmul(p_d, np.transpose(np.power(1.0/np.array(c_vect), 2))))
139
+
140
+ # Large distance emphasis
141
+ gldzm_features['Fdzm_lde'] = (np.matmul(p_d, np.transpose(np.power(np.array(c_vect), 2))))
142
+
143
+ # Low grey level zone emphasis
144
+ gldzm_features['Fdzm_lgze'] = np.matmul(p_g, np.transpose(np.power(1.0/np.array(r_vect), 2)))
145
+
146
+ # High grey level zone emphasis
147
+ gldzm_features['Fdzm_hgze'] = np.matmul(p_g, np.transpose(np.power(np.array(r_vect), 2)))
148
+
149
+ # Small distance low grey level emphasis
150
+ gldzm_features['Fdzm_sdlge'] = np.sum(np.sum(gldzm*(np.power(1.0/r_mat, 2))*(np.power(1.0/c_mat, 2))))
151
+
152
+ # Small distance high grey level emphasis
153
+ gldzm_features['Fdzm_sdhge'] = np.sum(np.sum(gldzm*(np.power(r_mat, 2))*(np.power(1.0/c_mat, 2))))
154
+
155
+ # Large distance low grey level emphasis
156
+ gldzm_features['Fdzm_ldlge'] = np.sum(np.sum(gldzm*(np.power(1.0/r_mat, 2))*(np.power(c_mat, 2))))
157
+
158
+ # Large distance high grey level emphasis
159
+ gldzm_features['Fdzm_ldhge'] = np.sum(np.sum(gldzm*(np.power(r_mat, 2))*(np.power(c_mat, 2))))
160
+
161
+ # Gray level non-uniformity
162
+ gldzm_features['Fdzm_glnu'] = np.sum(np.power(p_g, 2)) * n_s
163
+
164
+ # Gray level non-uniformity normalised
165
+ gldzm_features['Fdzm_glnu_norm'] = np.sum(np.power(p_g, 2))
166
+
167
+ # Zone distance non-uniformity
168
+ gldzm_features['Fdzm_zdnu'] = np.sum(np.power(p_d, 2)) * n_s
169
+
170
+ # Zone distance non-uniformity normalised
171
+ gldzm_features['Fdzm_zdnu_norm'] = np.sum(np.power(p_d, 2))
172
+
173
+ # Zone percentage
174
+ # Must change the original definition here.
175
+ gldzm_features['Fdzm_z_perc'] = n_s / np.sum(~np.isnan(vol_int[:]))
176
+
177
+ # Grey level variance
178
+ temp = r_mat * gldzm
179
+ u = np.sum(temp)
180
+ temp = (np.power(r_mat-u, 2)) * gldzm
181
+ gldzm_features['Fdzm_gl_var'] = np.sum(temp)
182
+
183
+ # Zone distance variance
184
+ temp = c_mat * gldzm
185
+ u = np.sum(temp)
186
+ temp = (np.power(c_mat-u, 2)) * gldzm
187
+ temp = (np.power(c_mat - u, 2)) * gldzm
188
+ gldzm_features['Fdzm_zd_var'] = np.sum(temp)
189
+
190
+ # Zone distance entropy
191
+ val_pos = gldzm[np.nonzero(gldzm)]
192
+ temp = val_pos * np.log2(val_pos)
193
+ gldzm_features['Fdzm_zd_entr'] = -np.sum(temp)
194
+
195
+ return gldzm_features
196
+
197
+ def get_single_matrix(vol_int: np.ndarray, mask_morph: np.ndarray) -> np.ndarray:
198
+ """Computes gray level distance zone matrix in order to compute the single features.
199
+
200
+ Args:
201
+ vol_int (ndarray): 3D volume, isotropically resampled,
202
+ quantized (e.g. n_g = 32, levels = [1, ..., n_g]),
203
+ with NaNs outside the region of interest.
204
+ mask_morph (ndarray): Morphological ROI mask.
205
+
206
+ Returns:
207
+ ndarray: gldzm features.
208
+ """
209
+ # Correct definition, without any assumption
210
+ levels = np.arange(1, np.max(vol_int[~np.isnan(vol_int[:])])+1)
211
+
212
+ # GET THE gldzm MATRIX
213
+ gldzm = get_matrix(vol_int, mask_morph, levels)
214
+
215
+ return gldzm
216
+
217
+ def sde(gldzm: np.ndarray) -> float:
218
+ """Computes small distance emphasis feature.
219
+ This feature refers to "Fdzm_sde" (ID = 0GBI) in
220
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
221
+
222
+ Args:
223
+ gldzm (ndarray): array of the gray level distance zone matrix
224
+
225
+ Returns:
226
+ float: the small distance emphasis feature
227
+ """
228
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
229
+ s_z = np.shape(gldzm) # Size of gldzm
230
+ c_vect = range(1, s_z[1]+1) # Row vectors
231
+ p_d = np.sum(gldzm, 0) # Distance Zone Vector
232
+
233
+ # Small distance emphasis
234
+ return (np.matmul(p_d, np.transpose(np.power(1.0 / np.array(c_vect), 2))))
235
+
236
+ def lde(gldzm: np.ndarray) -> float:
237
+ """Computes large distance emphasis feature.
238
+ This feature refers to "Fdzm_lde" (ID = MB4I) in
239
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
240
+
241
+ Args:
242
+ gldzm (ndarray): array of the gray level distance zone matrix
243
+
244
+ Returns:
245
+ float: the large distance emphasis feature
246
+ """
247
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
248
+ s_z = np.shape(gldzm) # Size of gldzm
249
+ c_vect = range(1, s_z[1]+1) # Row vectors
250
+ p_d = np.sum(gldzm, 0) # Distance Zone Vector
251
+
252
+ #Large distance emphasis
253
+ return (np.matmul(p_d, np.transpose(np.power(np.array(c_vect), 2))))
254
+
255
+ def lgze(gldzm: np.ndarray) -> float:
256
+ """Computes distance matrix low grey level zone emphasis feature.
257
+ This feature refers to "Fdzm_lgze" (ID = S1RA) in
258
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
259
+
260
+ Args:
261
+ gldzm (ndarray): array of the gray level distance zone matrix
262
+
263
+ Returns:
264
+ float: the low grey level zone emphasis feature
265
+ """
266
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
267
+ s_z = np.shape(gldzm) # Size of gldzm
268
+ r_vect = range(1, s_z[0]+1) # Column vectors
269
+ p_g = np.transpose(np.sum(gldzm, 1)) # Gray-Level Vector
270
+
271
+ #Low grey level zone emphasisphasis
272
+ return np.matmul(p_g, np.transpose(np.power(1.0/np.array(r_vect), 2)))
273
+
274
+ def hgze(gldzm: np.ndarray) -> float:
275
+ """Computes distance matrix high grey level zone emphasis feature.
276
+ This feature refers to "Fdzm_hgze" (ID = K26C) in
277
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
278
+
279
+ Args:
280
+ gldzm (ndarray): array of the gray level distance zone matrix
281
+
282
+ Returns:
283
+ float: the high grey level zone emphasis feature
284
+ """
285
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
286
+ s_z = np.shape(gldzm) # Size of gldzm
287
+ r_vect = range(1, s_z[0]+1) # Column vectors
288
+ p_g = np.transpose(np.sum(gldzm, 1)) # Gray-Level Vector
289
+
290
+ #Low grey level zone emphasisphasis
291
+ return np.matmul(p_g, np.transpose(np.power(np.array(r_vect), 2)))
292
+
293
+ def sdlge(gldzm: np.ndarray) -> float:
294
+ """Computes small distance low grey level emphasis feature.
295
+ This feature refers to "Fdzm_sdlge" (ID = RUVG) in
296
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
297
+
298
+ Args:
299
+ gldzm (ndarray): array of the gray level distance zone matrix
300
+
301
+ Returns:
302
+ float: the low grey level emphasis feature
303
+ """
304
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
305
+ s_z = np.shape(gldzm) # Size of gldzm
306
+ c_vect = range(1, s_z[1]+1) # Row vectors
307
+ r_vect = range(1, s_z[0]+1) # Column vectors
308
+ c_mat, r_mat = np.meshgrid(c_vect, r_vect) # Column and row indicators for each entry of the gldzm
309
+
310
+ #Low grey level zone emphasisphasis
311
+ return np.sum(np.sum(gldzm*(np.power(1.0/r_mat, 2))*(np.power(1.0/c_mat, 2))))
312
+
313
+ def sdhge(gldzm: np.ndarray) -> float:
314
+ """Computes small distance high grey level emphasis feature.
315
+ This feature refers to "Fdzm_sdhge" (ID = DKNJ) in
316
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
317
+
318
+ Args:
319
+ gldzm (ndarray): array of the gray level distance zone matrix
320
+
321
+ Returns:
322
+ float: the distance high grey level emphasis feature
323
+ """
324
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
325
+ s_z = np.shape(gldzm) # Size of gldzm
326
+ c_vect = range(1, s_z[1]+1) # Row vectors
327
+ r_vect = range(1, s_z[0]+1) # Column vectors
328
+ c_mat, r_mat = np.meshgrid(c_vect, r_vect) # Column and row indicators for each entry of the gldzm
329
+
330
+ #High grey level zone emphasisphasis
331
+ return np.sum(np.sum(gldzm*(np.power(r_mat, 2))*(np.power(1.0/c_mat, 2))))
332
+
333
+ def ldlge(gldzm: np.ndarray) -> float:
334
+ """Computes large distance low grey level emphasis feature.
335
+ This feature refers to "Fdzm_ldlge" (ID = A7WM) in
336
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
337
+
338
+ Args:
339
+ gldzm (ndarray): array of the gray level distance zone matrix
340
+
341
+ Returns:
342
+ float: the low grey level emphasis feature
343
+ """
344
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
345
+ s_z = np.shape(gldzm) # Size of gldzm
346
+ c_vect = range(1, s_z[1]+1) # Row vectors
347
+ r_vect = range(1, s_z[0]+1) # Column vectors
348
+ c_mat, r_mat = np.meshgrid(c_vect, r_vect) # Column and row indicators for each entry of the gldzm
349
+
350
+ #Large distance low grey levels emphasis
351
+ return np.sum(np.sum(gldzm*(np.power(1.0/r_mat, 2))*(np.power(c_mat, 2))))
352
+
353
+ def ldhge(gldzm: np.ndarray) -> float:
354
+ """Computes large distance high grey level emphasis feature.
355
+ This feature refers to "Fdzm_ldhge" (ID = KLTH) in
356
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
357
+
358
+ Args:
359
+ gldzm (ndarray): array of the gray level distance zone matrix
360
+
361
+ Returns:
362
+ float: the high grey level emphasis feature
363
+ """
364
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
365
+ s_z = np.shape(gldzm) # Size of gldzm
366
+ c_vect = range(1, s_z[1]+1) # Row vectors
367
+ r_vect = range(1, s_z[0]+1) # Column vectors
368
+ c_mat, r_mat = np.meshgrid(c_vect, r_vect) # Column and row indicators for each entry of the gldzm
369
+
370
+ #Large distance high grey levels emphasis
371
+ return np.sum(np.sum(gldzm*(np.power(
372
+ r_mat, 2))*(np.power(c_mat, 2))))
373
+
374
+ def glnu(gldzm: np.ndarray) -> float:
375
+ """Computes distance zone matrix gray level non-uniformity
376
+ This feature refers to "Fdzm_glnu" (ID = VFT7) in
377
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
378
+
379
+ Args:
380
+ gldzm (ndarray): array of the gray level distance zone matrix
381
+
382
+ Returns:
383
+ float: the gray level non-uniformity feature
384
+ """
385
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
386
+ p_g = np.transpose(np.sum(gldzm, 1)) # Gray-Level Vector
387
+ n_s = np.sum(gldzm)
388
+
389
+ #Gray level non-uniformity
390
+ return np.sum(np.power(p_g, 2)) * n_s
391
+
392
+ def glnu_norm(gldzm: np.ndarray) -> float:
393
+ """Computes distance zone matrix gray level non-uniformity normalised
394
+ This feature refers to "Fdzm_glnu_norm" (ID = 7HP3) in
395
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
396
+
397
+ Args:
398
+ gldzm (ndarray): array of the gray level distance zone matrix
399
+
400
+ Returns:
401
+ float: the gray level non-uniformity normalised feature
402
+ """
403
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
404
+ p_g = np.transpose(np.sum(gldzm, 1)) # Gray-Level Vector
405
+
406
+ #Gray level non-uniformity normalised
407
+ return np.sum(np.power(p_g, 2))
408
+
409
+ def zdnu(gldzm: np.ndarray) -> float:
410
+ """Computes zone distance non-uniformity
411
+ This feature refers to "Fdzm_zdnu" (ID = V294) in
412
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
413
+
414
+ Args:
415
+ gldzm (ndarray): array of the gray level distance zone matrix
416
+
417
+ Returns:
418
+ float: the zone distance non-uniformity feature
419
+ """
420
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
421
+ p_d = np.sum(gldzm, 0) # Distance Zone Vector
422
+ n_s = np.sum(gldzm)
423
+
424
+ #Zone distance non-uniformity
425
+ return np.sum(np.power(p_d, 2)) * n_s
426
+
427
+ def zdnu_norm(gldzm: np.ndarray) -> float:
428
+ """Computes zone distance non-uniformity normalised
429
+ This feature refers to "Fdzm_zdnu_norm" (ID = IATH) in
430
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
431
+
432
+ Args:
433
+ gldzm (ndarray): array of the gray level distance zone matrix
434
+
435
+ Returns:
436
+ float: the zone distance non-uniformity normalised feature
437
+ """
438
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
439
+ p_d = np.sum(gldzm, 0) # Distance Zone Vector
440
+
441
+ #Zone distance non-uniformity normalised
442
+ return np.sum(np.power(p_d, 2))
443
+
444
+ def z_perc(gldzm, vol_int):
445
+ """Computes zone percentage
446
+ This feature refers to "Fdzm_z_perc" (ID = VIWW) in
447
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
448
+
449
+ Args:
450
+ gldzm (ndarray): array of the gray level distance zone matrix
451
+
452
+ Returns:
453
+ float: the zone percentage feature
454
+ """
455
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
456
+ n_s = np.sum(gldzm)
457
+
458
+ #Zone percentage
459
+ return n_s/np.sum(~np.isnan(vol_int[:]))
460
+
461
+ def gl_var(gldzm: np.ndarray) -> float:
462
+ """Computes grey level variance
463
+ This feature refers to "Fdzm_gl_var" (ID = QK93) in
464
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
465
+
466
+ Args:
467
+ gldzm (ndarray): array of the gray level distance zone matrix
468
+
469
+ Returns:
470
+ float: the grey level variance feature
471
+ """
472
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
473
+ s_z = np.shape(gldzm) # Size of gldzm
474
+ c_vect = range(1, s_z[1]+1) # Row vectors
475
+ r_vect = range(1, s_z[0]+1) # Column vectors
476
+ _, r_mat = np.meshgrid(c_vect, r_vect) # Column and row indicators for each entry of the gldzm
477
+ temp = r_mat * gldzm
478
+ u = np.sum(temp)
479
+ temp = (np.power(r_mat-u, 2)) * gldzm
480
+
481
+ #Grey level variance
482
+ return np.sum(temp)
483
+
484
+ def zd_var(gldzm: np.ndarray) -> float:
485
+ """Computes zone distance variance
486
+ This feature refers to "Fdzm_zd_var" (ID = 7WT1) in
487
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
488
+
489
+ Args:
490
+ gldzm (ndarray): array of the gray level distance zone matrix
491
+
492
+ Returns:
493
+ float: the zone distance variance feature
494
+ """
495
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
496
+ s_z = np.shape(gldzm) # Size of gldzm
497
+ c_vect = range(1, s_z[1]+1) # Row vectors
498
+ r_vect = range(1, s_z[0]+1) # Column vectors
499
+ c_mat, _ = np.meshgrid(c_vect, r_vect) # Column and row indicators for each entry of the gldzm
500
+ temp = c_mat * gldzm
501
+ u = np.sum(temp)
502
+ temp = (np.power(c_mat-u, 2)) * gldzm
503
+
504
+ #Zone distance variance
505
+ return np.sum(temp)
506
+
507
+ def zd_entr(gldzm: np.ndarray) -> float:
508
+ """Computes zone distance entropy
509
+ This feature refers to "Fdzm_zd_entr" (ID = GBDU) in
510
+ the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
511
+
512
+ Args:
513
+ gldzm (ndarray): array of the gray level distance zone matrix
514
+
515
+ Returns:
516
+ float: the zone distance entropy feature
517
+ """
518
+ gldzm = gldzm / np.sum(gldzm) # Normalization of gldzm
519
+ val_pos = gldzm[np.nonzero(gldzm)]
520
+ temp = val_pos * np.log2(val_pos)
521
+
522
+ #Zone distance entropy
523
+ return -np.sum(temp)