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,555 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from typing import Dict, List, Union
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import skimage.measure as skim
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_matrix(roi_only: np.ndarray,
|
|
11
|
+
levels: Union[np.ndarray, List]) -> Dict:
|
|
12
|
+
r"""
|
|
13
|
+
This function computes the Gray-Level Size Zone Matrix (GLSZM) of the
|
|
14
|
+
region of interest (ROI) of an input volume. The input volume is assumed
|
|
15
|
+
to be isotropically resampled. The zones of different sizes are computed
|
|
16
|
+
using 26-voxel connectivity.
|
|
17
|
+
This matrix refers to "Grey level size zone based features" (ID = 9SAK)
|
|
18
|
+
in the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`_.
|
|
19
|
+
|
|
20
|
+
Note:
|
|
21
|
+
This function is compatible with 2D analysis (language not adapted in the text).
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
roi_only_int (ndarray): Smallest box containing the ROI, with the imaging data ready
|
|
25
|
+
for texture analysis computations. Voxels outside the ROI are
|
|
26
|
+
set to NaNs.
|
|
27
|
+
levels (ndarray or List): Vector containing the quantized gray-levels
|
|
28
|
+
in the tumor region (or reconstruction ``levels`` of quantization).
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
ndarray: Array of Gray-Level Size Zone Matrix of ``roi_only``.
|
|
32
|
+
|
|
33
|
+
REFERENCES:
|
|
34
|
+
[1] Thibault, G., Fertil, B., Navarro, C., Pereira, S., Cau, P., Levy,
|
|
35
|
+
N., Mari, J.-L. (2009). Texture Indexes and Gray Level Size Zone
|
|
36
|
+
Matrix. Application to Cell Nuclei Classification. In Pattern
|
|
37
|
+
Recognition and Information Processing (PRIP) (pp. 140–145).
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
# PRELIMINARY
|
|
41
|
+
roi_only = roi_only.copy()
|
|
42
|
+
n_max = np.sum(~np.isnan(roi_only))
|
|
43
|
+
level_temp = np.max(levels) + 1
|
|
44
|
+
roi_only[np.isnan(roi_only)] = level_temp
|
|
45
|
+
levels = np.append(levels, level_temp)
|
|
46
|
+
|
|
47
|
+
# QUANTIZATION EFFECTS CORRECTION
|
|
48
|
+
# In case (for example) we initially wanted to have 64 levels, but due to
|
|
49
|
+
# quantization, only 60 resulted.
|
|
50
|
+
unique_vect = levels
|
|
51
|
+
n_l = np.size(levels) - 1
|
|
52
|
+
|
|
53
|
+
# INITIALIZATION
|
|
54
|
+
# THIS NEEDS TO BE CHANGED. THE ARRAY INITIALIZED COULD BE TOO BIG!
|
|
55
|
+
glszm = np.zeros((n_l, n_max))
|
|
56
|
+
|
|
57
|
+
# COMPUTATION OF glszm
|
|
58
|
+
temp = roi_only.copy().astype('int')
|
|
59
|
+
for i in range(1, n_l+1):
|
|
60
|
+
temp[roi_only != unique_vect[i-1]] = 0
|
|
61
|
+
temp[roi_only == unique_vect[i-1]] = 1
|
|
62
|
+
conn_objects, n_zone = skim.label(temp, return_num=True)
|
|
63
|
+
for j in range(1, n_zone+1):
|
|
64
|
+
col = np.sum(conn_objects == j)
|
|
65
|
+
glszm[i-1, col-1] = glszm[i-1, col-1] + 1
|
|
66
|
+
|
|
67
|
+
# REMOVE UNECESSARY COLUMNS
|
|
68
|
+
stop = np.nonzero(np.sum(glszm, 0))[0][-1]
|
|
69
|
+
glszm = np.delete(glszm, range(stop+1, np.shape(glszm)[1]), 1)
|
|
70
|
+
|
|
71
|
+
return glszm
|
|
72
|
+
|
|
73
|
+
def extract_all(vol: np.ndarray,
|
|
74
|
+
glszm: np.ndarray = None) -> Dict:
|
|
75
|
+
"""Computes glszm features.
|
|
76
|
+
These features refer to "Grey level size zone based features" (ID = 9SAK)
|
|
77
|
+
in the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
vol (ndarray): 3D volume, isotropically resampled, quantized
|
|
81
|
+
(e.g. n_g = 32, levels = [1, ..., n_g]),
|
|
82
|
+
with NaNs outside the region of interest.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Dict: Dict of glszm features.
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
glszm_features = {'Fszm_sze': [],
|
|
89
|
+
'Fszm_lze': [],
|
|
90
|
+
'Fszm_lgze': [],
|
|
91
|
+
'Fszm_hgze': [],
|
|
92
|
+
'Fszm_szlge': [],
|
|
93
|
+
'Fszm_szhge': [],
|
|
94
|
+
'Fszm_lzlge': [],
|
|
95
|
+
'Fszm_lzhge': [],
|
|
96
|
+
'Fszm_glnu': [],
|
|
97
|
+
'Fszm_glnu_norm': [],
|
|
98
|
+
'Fszm_zsnu': [],
|
|
99
|
+
'Fszm_zsnu_norm': [],
|
|
100
|
+
'Fszm_z_perc': [],
|
|
101
|
+
'Fszm_gl_var': [],
|
|
102
|
+
'Fszm_zs_var': [],
|
|
103
|
+
'Fszm_zs_entr': []}
|
|
104
|
+
|
|
105
|
+
# GET THE GLSZM MATRIX
|
|
106
|
+
# Correct definition, without any assumption
|
|
107
|
+
vol = vol.copy()
|
|
108
|
+
levels = np.arange(1, np.max(vol[~np.isnan(vol[:])])+1)
|
|
109
|
+
if glszm is None:
|
|
110
|
+
glszm = get_matrix(vol, levels)
|
|
111
|
+
n_s = np.sum(glszm)
|
|
112
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
113
|
+
sz = np.shape(glszm) # Size of glszm
|
|
114
|
+
|
|
115
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
116
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
117
|
+
# Column and row indicators for each entry of the glszm
|
|
118
|
+
c_mat, r_mat = np.meshgrid(c_vect, r_vect)
|
|
119
|
+
pg = np.transpose(np.sum(glszm, 1)) # Gray-Level Vector
|
|
120
|
+
pz = np.sum(glszm, 0) # Zone Size Vector
|
|
121
|
+
|
|
122
|
+
# COMPUTING TEXTURES
|
|
123
|
+
|
|
124
|
+
# Small zone emphasis
|
|
125
|
+
glszm_features['Fszm_sze'] = (np.matmul(pz, np.transpose(np.power(1.0/np.array(c_vect), 2))))
|
|
126
|
+
|
|
127
|
+
# Large zone emphasis
|
|
128
|
+
glszm_features['Fszm_lze'] = (np.matmul(pz, np.transpose(np.power(np.array(c_vect), 2))))
|
|
129
|
+
|
|
130
|
+
# Low grey level zone emphasis
|
|
131
|
+
glszm_features['Fszm_lgze'] = np.matmul(pg, np.transpose(np.power(
|
|
132
|
+
1.0/np.array(r_vect), 2)))
|
|
133
|
+
|
|
134
|
+
# High grey level zone emphasis
|
|
135
|
+
glszm_features['Fszm_hgze'] = np.matmul(pg, np.transpose(np.power(np.array(r_vect), 2)))
|
|
136
|
+
|
|
137
|
+
# Small zone low grey level emphasis
|
|
138
|
+
glszm_features['Fszm_szlge'] = np.sum(np.sum(glszm*(np.power(1.0/r_mat, 2))*(np.power(1.0/c_mat, 2))))
|
|
139
|
+
|
|
140
|
+
# Small zone high grey level emphasis
|
|
141
|
+
glszm_features['Fszm_szhge'] = np.sum(np.sum(glszm*(np.power(r_mat, 2))*(np.power(1.0/c_mat, 2))))
|
|
142
|
+
|
|
143
|
+
# Large zone low grey levels emphasis
|
|
144
|
+
glszm_features['Fszm_lzlge'] = np.sum(np.sum(glszm*(np.power(1.0/r_mat, 2))*(np.power(c_mat, 2))))
|
|
145
|
+
|
|
146
|
+
# Large zone high grey level emphasis
|
|
147
|
+
glszm_features['Fszm_lzhge'] = np.sum(np.sum(glszm*(np.power(r_mat, 2))*(np.power(c_mat, 2))))
|
|
148
|
+
|
|
149
|
+
# Gray level non-uniformity
|
|
150
|
+
glszm_features['Fszm_glnu'] = np.sum(np.power(pg, 2)) * n_s
|
|
151
|
+
|
|
152
|
+
# Gray level non-uniformity normalised
|
|
153
|
+
glszm_features['Fszm_glnu_norm'] = np.sum(np.power(pg, 2))
|
|
154
|
+
|
|
155
|
+
# Zone size non-uniformity
|
|
156
|
+
glszm_features['Fszm_zsnu'] = np.sum(np.power(pz, 2)) * n_s
|
|
157
|
+
|
|
158
|
+
# Zone size non-uniformity normalised
|
|
159
|
+
glszm_features['Fszm_zsnu_norm'] = np.sum(np.power(pz, 2))
|
|
160
|
+
|
|
161
|
+
# Zone percentage
|
|
162
|
+
glszm_features['Fszm_z_perc'] = np.sum(pg)/(np.matmul(pz, np.transpose(c_vect)))
|
|
163
|
+
|
|
164
|
+
# Grey level variance
|
|
165
|
+
temp = r_mat * glszm
|
|
166
|
+
u = np.sum(temp)
|
|
167
|
+
temp = (np.power(r_mat - u, 2)) * glszm
|
|
168
|
+
glszm_features['Fszm_gl_var'] = np.sum(temp)
|
|
169
|
+
|
|
170
|
+
# Zone size variance
|
|
171
|
+
temp = c_mat * glszm
|
|
172
|
+
u = np.sum(temp)
|
|
173
|
+
temp = (np.power(c_mat - u, 2)) * glszm
|
|
174
|
+
glszm_features['Fszm_zs_var'] = np.sum(temp)
|
|
175
|
+
|
|
176
|
+
# Zone size entropy
|
|
177
|
+
val_pos = glszm[np.nonzero(glszm)]
|
|
178
|
+
temp = val_pos * np.log2(val_pos)
|
|
179
|
+
glszm_features['Fszm_zs_entr'] = -np.sum(temp)
|
|
180
|
+
|
|
181
|
+
return glszm_features
|
|
182
|
+
|
|
183
|
+
def get_single_matrix(vol: np.ndarray) -> np.ndarray:
|
|
184
|
+
"""Computes gray level size zone matrix in order to compute the single features.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
vol_int: 3D volume, isotropically resampled,
|
|
188
|
+
quantized (e.g. n_g = 32, levels = [1, ..., n_g]),
|
|
189
|
+
with NaNs outside the region of interest.
|
|
190
|
+
levels: Vector containing the quantized gray-levels
|
|
191
|
+
in the tumor region (or reconstruction ``levels`` of quantization).
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
ndarray: Array of Gray-Level Size Zone Matrix of 'vol'.
|
|
195
|
+
|
|
196
|
+
"""
|
|
197
|
+
# Correct definition, without any assumption
|
|
198
|
+
vol = vol.copy()
|
|
199
|
+
levels = np.arange(1, np.max(vol[~np.isnan(vol[:])])+1)
|
|
200
|
+
|
|
201
|
+
# GET THE gldzm MATRIX
|
|
202
|
+
glszm = get_matrix(vol, levels)
|
|
203
|
+
|
|
204
|
+
return glszm
|
|
205
|
+
|
|
206
|
+
def sze(glszm: np.ndarray) -> float:
|
|
207
|
+
"""Computes small zone emphasis feature.
|
|
208
|
+
This feature refers to "Fszm_sze" (ID = 5QRC) in
|
|
209
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
float: the small zone emphasis
|
|
216
|
+
|
|
217
|
+
"""
|
|
218
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
219
|
+
sz = np.shape(glszm) # Size of glszm
|
|
220
|
+
|
|
221
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
222
|
+
pz = np.sum(glszm, 0) # Zone Size Vector
|
|
223
|
+
|
|
224
|
+
# Small zone emphasis
|
|
225
|
+
return (np.matmul(pz, np.transpose(np.power(1.0/np.array(c_vect), 2))))
|
|
226
|
+
|
|
227
|
+
def lze(glszm: np.ndarray) -> float:
|
|
228
|
+
"""Computes large zone emphasis feature.
|
|
229
|
+
This feature refers to "Fszm_lze" (ID = 48P8) in
|
|
230
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
float: the large zone emphasis
|
|
237
|
+
|
|
238
|
+
"""
|
|
239
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
240
|
+
sz = np.shape(glszm) # Size of glszm
|
|
241
|
+
|
|
242
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
243
|
+
pz = np.sum(glszm, 0) # Zone Size Vector
|
|
244
|
+
|
|
245
|
+
# Large zone emphasis
|
|
246
|
+
return (np.matmul(pz, np.transpose(np.power(np.array(c_vect), 2))))
|
|
247
|
+
|
|
248
|
+
def lgze(glszm: np.ndarray) -> float:
|
|
249
|
+
"""Computes low grey zone emphasis feature.
|
|
250
|
+
This feature refers to "Fszm_lgze" (ID = XMSY) in
|
|
251
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
float: the low grey zone emphasis
|
|
258
|
+
|
|
259
|
+
"""
|
|
260
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
261
|
+
sz = np.shape(glszm) # Size of glszm
|
|
262
|
+
|
|
263
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
264
|
+
pg = np.transpose(np.sum(glszm, 1)) # Gray-Level Vector
|
|
265
|
+
|
|
266
|
+
# Low grey zone emphasis
|
|
267
|
+
return np.matmul(pg, np.transpose(np.power(
|
|
268
|
+
1.0/np.array(r_vect), 2)))
|
|
269
|
+
|
|
270
|
+
def hgze(glszm: np.ndarray) -> float:
|
|
271
|
+
"""Computes high grey zone emphasis feature.
|
|
272
|
+
This feature refers to "Fszm_hgze" (ID = 5GN9) in
|
|
273
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
float: the high grey zone emphasis
|
|
280
|
+
|
|
281
|
+
"""
|
|
282
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
283
|
+
sz = np.shape(glszm) # Size of glszm
|
|
284
|
+
|
|
285
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
286
|
+
pg = np.transpose(np.sum(glszm, 1)) # Gray-Level Vector
|
|
287
|
+
|
|
288
|
+
# High grey zone emphasis
|
|
289
|
+
return np.matmul(pg, np.transpose(np.power(np.array(r_vect), 2)))
|
|
290
|
+
|
|
291
|
+
def szlge(glszm: np.ndarray) -> float:
|
|
292
|
+
"""Computes small zone low grey level emphasis feature.
|
|
293
|
+
This feature refers to "Fszm_szlge" (ID = 5RAI) in
|
|
294
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
float: the small zone low grey level emphasis
|
|
301
|
+
|
|
302
|
+
"""
|
|
303
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
304
|
+
sz = np.shape(glszm) # Size of glszm
|
|
305
|
+
|
|
306
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
307
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
308
|
+
# Column and row indicators for each entry of the glszm
|
|
309
|
+
c_mat, r_mat = np.meshgrid(c_vect, r_vect)
|
|
310
|
+
|
|
311
|
+
# Small zone low grey level emphasis
|
|
312
|
+
return np.sum(np.sum(glszm*(np.power(1.0/r_mat, 2))*(np.power(1.0/c_mat, 2))))
|
|
313
|
+
|
|
314
|
+
def szhge(glszm: np.ndarray) -> float:
|
|
315
|
+
"""Computes small zone high grey level emphasis feature.
|
|
316
|
+
This feature refers to "Fszm_szhge" (ID = HW1V) in
|
|
317
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
float: the small zone high grey level emphasis
|
|
324
|
+
|
|
325
|
+
"""
|
|
326
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
327
|
+
sz = np.shape(glszm) # Size of glszm
|
|
328
|
+
|
|
329
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
330
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
331
|
+
# Column and row indicators for each entry of the glszm
|
|
332
|
+
c_mat, r_mat = np.meshgrid(c_vect, r_vect)
|
|
333
|
+
|
|
334
|
+
# Small zone high grey level emphasis
|
|
335
|
+
return np.sum(np.sum(glszm*(np.power(r_mat, 2))*(np.power(1.0/c_mat, 2))))
|
|
336
|
+
|
|
337
|
+
def lzlge(glszm: np.ndarray) -> float:
|
|
338
|
+
"""Computes large zone low grey level emphasis feature.
|
|
339
|
+
This feature refers to "Fszm_lzlge" (ID = YH51) in
|
|
340
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
344
|
+
|
|
345
|
+
Returns:
|
|
346
|
+
float: the large zone low grey level emphasis
|
|
347
|
+
|
|
348
|
+
"""
|
|
349
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
350
|
+
sz = np.shape(glszm) # Size of glszm
|
|
351
|
+
|
|
352
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
353
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
354
|
+
# Column and row indicators for each entry of the glszm
|
|
355
|
+
c_mat, r_mat = np.meshgrid(c_vect, r_vect)
|
|
356
|
+
|
|
357
|
+
# Lage zone low grey level emphasis
|
|
358
|
+
return np.sum(np.sum(glszm*(np.power(1.0/r_mat, 2))*(np.power(c_mat, 2))))
|
|
359
|
+
|
|
360
|
+
def lzhge(glszm: np.ndarray) -> float:
|
|
361
|
+
"""Computes large zone high grey level emphasis feature.
|
|
362
|
+
This feature refers to "Fszm_lzhge" (ID = J17V) in
|
|
363
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
float: the large zone high grey level emphasis
|
|
370
|
+
|
|
371
|
+
"""
|
|
372
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
373
|
+
sz = np.shape(glszm) # Size of glszm
|
|
374
|
+
|
|
375
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
376
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
377
|
+
# Column and row indicators for each entry of the glszm
|
|
378
|
+
c_mat, r_mat = np.meshgrid(c_vect, r_vect)
|
|
379
|
+
|
|
380
|
+
# Large zone high grey level emphasis
|
|
381
|
+
return np.sum(np.sum(glszm*(np.power(r_mat, 2))*(np.power(c_mat, 2))))
|
|
382
|
+
|
|
383
|
+
def glnu(glszm: np.ndarray) -> float:
|
|
384
|
+
"""Computes grey level non-uniformity feature.
|
|
385
|
+
This feature refers to "Fszm_glnu" (ID = JNSA) in
|
|
386
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
387
|
+
|
|
388
|
+
Args:
|
|
389
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
float: the grey level non-uniformity feature
|
|
393
|
+
|
|
394
|
+
"""
|
|
395
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
396
|
+
n_s = np.sum(glszm)
|
|
397
|
+
|
|
398
|
+
pg = np.transpose(np.sum(glszm, 1)) # Gray-Level Vector
|
|
399
|
+
|
|
400
|
+
# Grey level non-uniformity feature
|
|
401
|
+
return np.sum(np.power(pg, 2)) * n_s
|
|
402
|
+
|
|
403
|
+
def glnu_norm(glszm: np.ndarray) -> float:
|
|
404
|
+
"""Computes grey level non-uniformity normalised
|
|
405
|
+
This feature refers to "Fszm_glnu_norm" (ID = Y1RO) in
|
|
406
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
float: the grey level non-uniformity normalised feature
|
|
413
|
+
|
|
414
|
+
"""
|
|
415
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
416
|
+
|
|
417
|
+
pg = np.transpose(np.sum(glszm, 1)) # Gray-Level Vector
|
|
418
|
+
|
|
419
|
+
# Grey level non-uniformity normalised feature
|
|
420
|
+
return np.sum(np.power(pg, 2))
|
|
421
|
+
|
|
422
|
+
def zsnu(glszm: np.ndarray) -> float:
|
|
423
|
+
"""Computes zone size non-uniformity
|
|
424
|
+
This feature refers to "Fszm_zsnu" (ID = 4JP3) in
|
|
425
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
426
|
+
|
|
427
|
+
Args:
|
|
428
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
float: the zone size non-uniformity feature
|
|
432
|
+
|
|
433
|
+
"""
|
|
434
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
435
|
+
n_s = np.sum(glszm)
|
|
436
|
+
|
|
437
|
+
pz = np.sum(glszm, 0) # Zone Size Vector
|
|
438
|
+
|
|
439
|
+
# Zone size non-uniformity feature
|
|
440
|
+
return np.sum(np.power(pz, 2)) * n_s
|
|
441
|
+
|
|
442
|
+
def zsnu_norm(glszm: np.ndarray) -> float:
|
|
443
|
+
"""Computes zone size non-uniformity normalised
|
|
444
|
+
This feature refers to "Fszm_zsnu_norm" (ID = VB3A) in
|
|
445
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
446
|
+
|
|
447
|
+
Args:
|
|
448
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
449
|
+
|
|
450
|
+
Returns:
|
|
451
|
+
float: the zone size non-uniformity normalised feature
|
|
452
|
+
|
|
453
|
+
"""
|
|
454
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
455
|
+
|
|
456
|
+
pz = np.sum(glszm, 0) # Zone Size Vector
|
|
457
|
+
|
|
458
|
+
# Zone size non-uniformity normalised feature
|
|
459
|
+
return np.sum(np.power(pz, 2))
|
|
460
|
+
|
|
461
|
+
def z_perc(glszm: np.ndarray) -> float:
|
|
462
|
+
"""Computes zone percentage
|
|
463
|
+
This feature refers to "Fszm_z_perc" (ID = P30P) in
|
|
464
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
465
|
+
|
|
466
|
+
Args:
|
|
467
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
468
|
+
|
|
469
|
+
Returns:
|
|
470
|
+
float: the zone percentage feature
|
|
471
|
+
|
|
472
|
+
"""
|
|
473
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
474
|
+
sz = np.shape(glszm) # Size of glszm
|
|
475
|
+
|
|
476
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
477
|
+
pg = np.transpose(np.sum(glszm, 1)) # Gray-Level Vector
|
|
478
|
+
pz = np.sum(glszm, 0) # Zone Size Vector
|
|
479
|
+
|
|
480
|
+
# Zone percentage feature
|
|
481
|
+
return np.sum(pg)/(np.matmul(pz, np.transpose(c_vect)))
|
|
482
|
+
|
|
483
|
+
def gl_var(glszm: np.ndarray) -> float:
|
|
484
|
+
"""Computes grey level variance
|
|
485
|
+
This feature refers to "Fszm_gl_var" (ID = BYLV) in
|
|
486
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
487
|
+
|
|
488
|
+
Args:
|
|
489
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
490
|
+
|
|
491
|
+
Returns:
|
|
492
|
+
float: the grey level variance feature
|
|
493
|
+
|
|
494
|
+
"""
|
|
495
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
496
|
+
sz = np.shape(glszm) # Size of glszm
|
|
497
|
+
|
|
498
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
499
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
500
|
+
# Column and row indicators for each entry of the glszm
|
|
501
|
+
_, r_mat = np.meshgrid(c_vect, r_vect)
|
|
502
|
+
|
|
503
|
+
temp = r_mat * glszm
|
|
504
|
+
u = np.sum(temp)
|
|
505
|
+
temp = (np.power(r_mat - u, 2)) * glszm
|
|
506
|
+
|
|
507
|
+
# Grey level variance feature
|
|
508
|
+
return np.sum(temp)
|
|
509
|
+
|
|
510
|
+
def zs_var(glszm: np.ndarray) -> float:
|
|
511
|
+
"""Computes zone size variance
|
|
512
|
+
This feature refers to "Fszm_zs_var" (ID = 3NSA) in
|
|
513
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
514
|
+
|
|
515
|
+
Args:
|
|
516
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
517
|
+
|
|
518
|
+
Returns:
|
|
519
|
+
float: the zone size variance feature
|
|
520
|
+
|
|
521
|
+
"""
|
|
522
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
523
|
+
sz = np.shape(glszm) # Size of glszm
|
|
524
|
+
|
|
525
|
+
c_vect = range(1, sz[1]+1) # Row vectors
|
|
526
|
+
r_vect = range(1, sz[0]+1) # Column vectors
|
|
527
|
+
# Column and row indicators for each entry of the glszm
|
|
528
|
+
c_mat, _ = np.meshgrid(c_vect, r_vect)
|
|
529
|
+
|
|
530
|
+
temp = c_mat * glszm
|
|
531
|
+
u = np.sum(temp)
|
|
532
|
+
temp = (np.power(c_mat - u, 2)) * glszm
|
|
533
|
+
|
|
534
|
+
# Zone size variance feature
|
|
535
|
+
return np.sum(temp)
|
|
536
|
+
|
|
537
|
+
def zs_entr(glszm: np.ndarray) -> float:
|
|
538
|
+
"""Computes zone size entropy
|
|
539
|
+
This feature refers to "Fszm_zs_entr" (ID = GU8N) in
|
|
540
|
+
the `IBSI1 reference manual <https://arxiv.org/pdf/1612.07003.pdf>`__.
|
|
541
|
+
|
|
542
|
+
Args:
|
|
543
|
+
glszm (ndarray): array of the gray level size zone matrix
|
|
544
|
+
|
|
545
|
+
Returns:
|
|
546
|
+
float: the zone size entropy feature
|
|
547
|
+
|
|
548
|
+
"""
|
|
549
|
+
glszm = glszm/np.sum(glszm) # Normalization of glszm
|
|
550
|
+
|
|
551
|
+
val_pos = glszm[np.nonzero(glszm)]
|
|
552
|
+
temp = val_pos * np.log2(val_pos)
|
|
553
|
+
|
|
554
|
+
# Zone size entropy feature
|
|
555
|
+
return -np.sum(temp)
|