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,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)
|