Skip to content

Commit f44f456

Browse files
committed
BUG labels measurement not updated in examples
1 parent 5aa5204 commit f44f456

File tree

8 files changed

+100
-244
lines changed

8 files changed

+100
-244
lines changed

LABelsToolkit/agents/measurer.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,8 @@ def dist(self, segm_1_filename, segm_2_filename, labels_list=None, labels_names=
9898
labels_list1, labels_names1 = labels_query('all', im_segm1.get_data())
9999
labels_list2, labels_names2 = labels_query('all', im_segm2.get_data())
100100
labels_list = list(set(labels_list1) & set(labels_list2))
101-
labels_names = list(set(labels_names1) & set(labels_names2))
102101
labels_list.sort(key=int)
103-
labels_names.sort(key=int)
102+
labels_names = None
104103

105104
if labels_names is None:
106105
labels_names = labels_list

LABelsToolkit/tools/caliber/volumes_and_values.py

Lines changed: 22 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -85,180 +85,56 @@ def get_values_below_labels_list(im_seg, im_anat, labels_list):
8585
# ---- Second part ----
8686

8787

88-
8988
def get_volumes_per_label(im_segm, labels, labels_names, tot_volume_prior=None, verbose=0):
9089
"""
90+
Get a separate volume for each label in a data-frame
9191
:param im_segm:
9292
:param labels:
9393
:param labels_names: index of labels in the final dataframes.
9494
:param tot_volume_prior:
9595
:param verbose:
9696
:return:
9797
"""
98-
num_voxels = get_total_num_nonzero_voxels(im_segm)
99-
vol_mm3 = num_voxels * one_voxel_volume(im_segm)
98+
num_non_zero_voxels = get_total_num_nonzero_voxels(im_segm)
99+
vol_non_zero_voxels_mm3 = num_non_zero_voxels * one_voxel_volume(im_segm)
100100
if tot_volume_prior is None:
101-
tot_volume_prior = 1
102-
if tot_volume_prior == 'tot':
103-
tot_volume_prior = vol_mm3
104-
101+
tot_volume_prior = vol_non_zero_voxels_mm3
105102
if labels_names == 'tot':
106103

107104
data_frame = pa.DataFrame({'Labels': pa.Series(labels, index=[labels_names]),
108-
'Num voxels': pa.Series(num_voxels, index=[labels_names]),
109-
'Volume': pa.Series(vol_mm3, index=[labels_names]),
110-
'Vol over Tot': pa.Series(vol_mm3 / tot_volume_prior, index=[labels_names])})
111-
112-
else:
113-
all_places = np.zeros_like(im_segm.get_data(), dtype=np.bool)
114-
for label_k in labels:
115-
if isinstance(label_k, int):
116-
all_places += im_segm.get_data() == label_k
117-
else:
118-
for label_k_j in label_k:
119-
all_places += im_segm.get_data() == label_k_j
120-
121-
flat_volume_voxel = np.nan_to_num( (all_places.astype(np.float64)).flatten() )
122-
123-
non_zero_voxels = np.count_nonzero(flat_volume_voxel)
124-
volumes = non_zero_voxels * one_voxel_volume(im_segm)
125-
if tot_volume_prior is None:
126-
num_voxels = get_total_num_nonzero_voxels(im_segm)
127-
tot_volume_prior = num_voxels * one_voxel_volume(im_segm)
128-
129-
vol_over_tot = volumes / float(tot_volume_prior)
130-
131-
data_frame = pa.DataFrame({'Labels': pa.Series(labels, index=labels_names),
132-
'Num voxels': pa.Series(non_zero_voxels, index=labels_names),
133-
'Volume': pa.Series(volumes, index=labels_names),
134-
'Vol over Tot': pa.Series(vol_over_tot, index=labels_names)})
135-
if verbose > 0:
136-
print(data_frame)
137-
138-
return data_frame
105+
'Num voxels': pa.Series(num_non_zero_voxels, index=[labels_names]),
106+
'Volume': pa.Series(vol_non_zero_voxels_mm3, index=[labels_names]),
107+
'Vol over Tot': pa.Series(vol_non_zero_voxels_mm3 / tot_volume_prior, index=[labels_names])})
139108

140-
141-
# ---- DUMP ----
142-
'''
143-
144-
def se_values_below_labels(im_seg, im_anat, labels_list, labels_names=None):
145-
"""
146-
147-
:param im_seg: image segmentation
148-
:param im_anat: image anatomy
149-
:param labels_list: integer, list of labels [l1, l2, ..., ln], or list of list of labels if labels needs to be
150-
considered together.
151-
e.g. labels_list = [1,2,[3,4]] -> values below label 1, values below label 2, values below label 3 and 4.
152-
:return: list of numpy arrays, each element is the flat array of the values below the labels
153-
"""
154-
values = []
155-
for label_k in labels_list:
156-
# TODO: optimise with np.where after testing
157-
if isinstance(label_k, int):
158-
all_places += im_seg.get_data() == label_k
159-
else:
160-
all_places = np.zeros_like(im_seg.get_data(), dtype=np.bool)
161-
for label_k_j in label_k:
162-
all_places += im_seg.get_data() == label_k_j
163-
164-
masked_scalar_data = np.nan_to_num(
165-
(all_places.astype(np.float64) * im_anat.get_data().astype(np.float64)).flatten())
166-
# remove zero elements from the array:
167-
non_zero_masked_scalar_data = masked_scalar_data[np.where(masked_scalar_data > 1e-6)] # 1e-6
168-
169-
if non_zero_masked_scalar_data.size == 0: # if not non_zero_masked_scalar_data is an empty array.
170-
non_zero_masked_scalar_data = 0.
171-
172-
values.append(non_zero_masked_scalar_data)
173-
if labels_names is None:
174-
return values
175109
else:
176-
return pa.Series(values, index=labels_names)
177-
178-
179-
def from_values_below_labels_to_mu_std(values_below_labels, labels, labels_names, verbose=0):
180-
"""
110+
non_zero_voxels_list = []
111+
volumes_list = []
112+
vol_over_tot_list = []
181113

182-
:param values_below_labels: output of values_below_labels
183-
:param labels:
184-
:param labels_names:
185-
:param verbose:
186-
:return:
187-
"""
188-
data_frame = pa.DataFrame({'Labels' : pa.Series(labels, index=labels_names),
189-
'Average below label' : pa.Series([np.mean(v) for v in values_below_labels], index=labels_names),
190-
'Std below label' : pa.Series([np.std(v) for v in values_below_labels], index=labels_names)})
191-
192-
if verbose > 0:
193-
print(data_frame)
194-
195-
return data_frame
196-
197-
198-
def get_volumes_per_label(im_segm, labels, labels_names, tot_volume_prior=None, verbose=0):
199-
"""
200-
:param im_segm:
201-
:param labels:
202-
:param labels_names: index of labels in the final dataframes.
203-
:param tot_volume_prior:
204-
:param verbose:
205-
:return:
206-
"""
207-
num_voxels, vol_mm3 = get_total_volume(im_segm)
208-
if tot_volume_prior is None:
209-
tot_volume_prior = 1
210-
if tot_volume_prior == 'tot':
211-
tot_volume_prior = vol_mm3
212-
213-
if labels_names == 'tot':
214-
215-
data_frame = pa.DataFrame({'Labels': pa.Series(labels, index=[labels_names]),
216-
'Num voxels': pa.Series(num_voxels, index=[labels_names]),
217-
'Volume': pa.Series(vol_mm3, index=[labels_names]),
218-
'Vol over Tot': pa.Series(vol_mm3 / tot_volume_prior, index=[labels_names])})
219-
220-
else:
221-
all_places = np.zeros_like(im_segm.get_data(), dtype=np.bool)
222114
for label_k in labels:
115+
all_places = np.zeros_like(im_segm.get_data(), dtype=np.bool)
223116
if isinstance(label_k, int):
224117
all_places += im_segm.get_data() == label_k
225118
else:
226119
for label_k_j in label_k:
227120
all_places += im_segm.get_data() == label_k_j
228121

229-
flat_volume_voxel = np.nan_to_num( (all_places.astype(np.float64)).flatten() )
122+
flat_volume_voxel = np.nan_to_num((all_places.astype(np.float64)).flatten() )
230123

231-
non_zero_voxels = np.count_nonzero(flat_volume_voxel)
232-
volumes = non_zero_voxels * one_voxel_volume(im_segm)
233-
if tot_volume_prior is None:
234-
tot_volume_prior = get_total_volume(im_segm, labels_to_exclude=[0])[1]
124+
non_zero_voxels = np.count_nonzero(flat_volume_voxel)
125+
volumes = non_zero_voxels * one_voxel_volume(im_segm)
235126

236-
vol_over_tot = volumes / float(tot_volume_prior)
127+
vol_over_tot = volumes / float(tot_volume_prior)
128+
129+
non_zero_voxels_list.append(non_zero_voxels)
130+
volumes_list.append(volumes)
131+
vol_over_tot_list.append(vol_over_tot)
237132

238133
data_frame = pa.DataFrame({'Labels': pa.Series(labels, index=labels_names),
239-
'Num voxels': pa.Series(non_zero_voxels, index=labels_names),
240-
'Volume': pa.Series(volumes, index=labels_names),
241-
'Vol over Tot': pa.Series(vol_over_tot, index=labels_names)})
134+
'Num voxels': pa.Series(non_zero_voxels_list, index=labels_names),
135+
'Volume': pa.Series(volumes_list, index=labels_names),
136+
'Vol over Tot': pa.Series(vol_over_tot_list, index=labels_names)})
242137
if verbose > 0:
243138
print(data_frame)
244139

245140
return data_frame
246-
247-
248-
def get_mu_std_below_labels(im_segm, im_anatomical, labels, labels_names, verbose=0):
249-
"""
250-
251-
:param im_anatomical:
252-
:param im_segm:
253-
:param labels: can be an integer, or a list.
254-
If it is a list, it can contain sublists.
255-
If labels are in the sublist, volumes will be computed for all the labels in the list.
256-
e.g. [1,2,[3,4]] -> volume of label 1, volume of label 2, volume of label 3 and 4.
257-
:param labels_names:
258-
:param verbose:
259-
:return:
260-
"""
261-
values_below_labels = get_values_below_labels(im_segm, im_anatomical, labels)
262-
df = from_values_below_labels_to_mu_std(values_below_labels, labels, labels_names, verbose=verbose)
263-
return df
264-
'''

LABelsToolkit/tools/phantoms_generator/generate_phantom_multi_atlas.py

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
from LABelsToolkit.tools.aux_methods.utils import print_and_run
99
from LABelsToolkit.tools.phantoms_generator.shapes_for_phantoms import sphere_shape
10-
from LABelsToolkit.tools.visualiser.see_volume import see_array
1110
from LABelsToolkit.tools.phantoms_generator.shapes_for_headlike_phantoms import headlike_phantom
1211

12+
from LABelsToolkit.tools.visualiser.see_volume import see_array
13+
1314

1415
def generate_atlas_at_folder(pfo_where_to_save_atlas, atlas_name='test', randomness_shape=0.3, randomness_noise=0.4):
1516

@@ -49,14 +50,14 @@ def generate_atlas_at_folder(pfo_where_to_save_atlas, atlas_name='test', randomn
4950
mod_inv_noise = mod_inv + noise_array
5051

5152
# -- add hypo-intensities artefacts:
52-
num_artefacts_per_type = int(10 * randomness_noise / 2)
53+
num_spots = int(10 * randomness_noise / 2)
5354
noise_hypo = np.zeros_like(noise_array).astype(np.int32)
54-
for j in range(num_artefacts_per_type):
55-
random_radius = 0.05 * randomness_noise * np.min(omega) *np.random.randn() # 5% of the min direction
55+
for j in range(num_spots):
56+
radius_centre = 0.05 * randomness_noise * np.min(omega)
57+
random_radius = np.random.uniform(radius_centre - radius_centre/2, radius_centre + radius_centre/2) # 5% of the min direction
5658
random_centre = [np.random.uniform(0 + random_radius, j - random_radius) for j in omega]
5759

5860
noise_hypo = noise_hypo + sphere_shape(omega, random_centre, random_radius, foreground_intensity=1, dtype=np.int32)
59-
see_array(noise_hypo, block=True)
6061

6162
noise_hypo = 1 - 1 * (noise_hypo.astype(np.bool))
6263
# filter the results:
@@ -66,8 +67,6 @@ def generate_atlas_at_folder(pfo_where_to_save_atlas, atlas_name='test', randomn
6667
# D) Get the Registration Mask (based on):
6768
reg_mask = noise_hypo * roi_mask
6869

69-
see_array([mod_gt, segm_gt, roi_mask.astype(np.int32), reg_mask.astype(np.int32), mod_gt_noise, mod_inv_noise])
70-
7170
# E) save all in the data structure
7271
im_segm_gt = nib.Nifti1Image(segm_gt, affine=np.eye(4))
7372
im_mod_gt = nib.Nifti1Image(mod_gt, affine=np.eye(4))
@@ -97,30 +96,15 @@ def generate_multi_atlas_at_folder(pfo_where_to_create_the_multi_atlas, number_o
9796
:param randomness_noise: randomness in the simulated noise signal and artefacts. Must be between 0 and 1.
9897
:return:
9998
"""
100-
print_and_run('mkdir -p {}'.format(pfo_where_to_create_the_multi_atlas))
101-
99+
print_and_run('mkdir {}'.format(pfo_where_to_create_the_multi_atlas))
102100
for sj in range(number_of_subjects):
103-
104-
# A) Generate folder structure
105-
sj_name = multi_atlas_root_name + str(sj).zfill(len(str(number_of_subjects)) + 1)
106-
101+
sj_name = multi_atlas_root_name + str(sj + 1).zfill(len(str(number_of_subjects)) + 1)
107102
print('Creating atlas {0} ({1}/{2})'.format(sj_name, sj+1, number_of_subjects))
103+
print_and_run('mkdir {}'.format(jph(pfo_where_to_create_the_multi_atlas, sj_name)))
108104
generate_atlas_at_folder(jph(pfo_where_to_create_the_multi_atlas, sj_name), atlas_name=sj_name,
109105
randomness_shape=randomness_shape, randomness_noise=randomness_noise)
110106

111-
112-
113107
if __name__ == '__main__':
114-
omega = (80, 90, 80)
115-
# noise1 = np.random.choice(range(10), size=omega).astype(np.float64)
116-
# noise2 = fil.gaussian_filter(noise1, 5)
117-
# print np.mean(noise2)
118-
# print np.std(noise2)
119-
# noise3 = noise2 / (np.mean(noise2) + 2 * np.std(noise2))
120-
# see_array([noise1, noise2, noise3])
121-
122-
# noise_array = np.random.uniform(-10, 10, size=omega).astype(np.float64)
123-
# noise_array = 0.2 * 0.4 * fil.gaussian_filter(noise_array, 3)
124-
# see_array(noise_array)
125-
#
126-
generate_atlas_at_folder('/Users/sebastiano/Desktop/z_test_phantom_atlas', randomness_noise=1)
108+
# test
109+
generate_multi_atlas_at_folder('/Users/sebastiano/Desktop/z_test_phantom_atlas', number_of_subjects=3,
110+
randomness_noise=1, randomness_shape=1)

examples/caliber_usage_distances_example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
from os.path import join as jph
33

4-
from LABelsToolkit.main import LABelsToolkit as LM
4+
from LABelsToolkit.main import LABelsToolkit as LT
55
from LABelsToolkit.tools.caliber.distances import dice_score, covariance_distance, hausdorff_distance
66
from LABelsToolkit.tools.defs import root_dir
77

@@ -14,7 +14,7 @@
1414
where_to_save = None
1515

1616
# Instantiate a Labels Manager class
17-
m = LM()
17+
m = LT()
1818
m.measure.return_mm3 = False
1919

2020
# get the measure

examples/caliber_usage_example.py

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
from os.path import join as jph
3+
import numpy as np
34

45
from LABelsToolkit.main import LABelsToolkit as LT
56
from LABelsToolkit.tools.defs import root_dir
@@ -25,43 +26,35 @@
2526

2627
# Get volumes per label:
2728
print('The 4 cubes of sides 11, 17, 19 and 9 are labelled 1, 2, 3 and 4 resp.:')
28-
print('Volume measured label 1 = {}'.format( m.measure.volume(pfi_im, labels=1)['Volume'].values) )
29+
print('Volume measured label 1 = {}'.format(m.measure.volume(pfi_im, labels=1)['Volume'].values))
2930
print('11**3 = {}'.format(11 ** 3))
30-
print('Volume measured label 2 = {}'.format( m.measure.volume(pfi_im, labels=2)['Volume'].values) )
31+
print('Volume measured label 2 = {}'.format(m.measure.volume(pfi_im, labels=2)['Volume'].values))
3132
print('17**3 = {}'.format(17 ** 3))
32-
print('Volume measured label 3 = {}'.format( m.measure.volume(pfi_im, labels=3)['Volume'].values) )
33+
print('Volume measured label 3 = {}'.format(m.measure.volume(pfi_im, labels=3)['Volume'].values))
3334
print('19**3 = {}'.format(19 ** 3))
34-
print('Volume measured label 4 = {}'.format( m.measure.volume(pfi_im, labels=4)['Volume'].values) )
35+
print('Volume measured label 4 = {}'.format(m.measure.volume(pfi_im, labels=4)['Volume'].values))
3536
print('9**3 = {}'.format(9 ** 3))
36-
print('Volume measured labels ([1, 3]) = {}'.format( m.measure.volume(pfi_im,
37-
labels=[[1, 3]])['Volume'].values) )
38-
print('11* 3 + 19**3 = {}'.format(11**3 + 19**3))
37+
print('Volume measured labels ([1, 3]) = {}'.format(m.measure.volume(pfi_im, labels=[[1, 3]])['Volume'].values))
38+
print('11**3 + 19**3 = {}'.format(11**3 + 19**3))
3939
print('\nTo sum up: \n')
4040
print('Volume measured labels ([1, 2, 3, 4, [1, 3]]) = \n{}\n'.format(
41-
m.measure.volume(pfi_im, labels=[1,2, 3, 4, [1, 3]])
42-
))
41+
m.measure.volume(pfi_im, labels=[1, 2, 3, 4, [1, 3], [1, 2, 3, 4]])))
42+
print('Total volume = {} \n'.format(m.measure.get_total_volume(pfi_im)))
43+
4344

4445
print('------------')
4546

4647
# Get volumes under each label, given the image weight, corresponding to the label itself:
47-
print('average below label 1 = {}'.format( m.measure.volume(pfi_im, anatomy_filename=pfi_im, labels=1)['Average below label'].values) )
48-
print('11**3 * 1 / 11**3 = {}'.format(11 ** 3 * 1/ float(11**3) ))
49-
print('average below label 2 = {}'.format( m.measure.volume(pfi_im, anatomy_filename=pfi_im, labels=2)['Average below label'].values) )
50-
print('17**3 * 2 / 17 ** 3 = {}'.format(17 ** 3 * 2 / float(17 ** 3)))
51-
print('average below label 3 = {}'.format( m.measure.volume(pfi_im, anatomy_filename=pfi_im, labels=3)['Average below label'].values) )
52-
print('19**3 * 3/ 19 ** 3 = {}'.format(19 ** 3 * 3 / float(19 ** 3)))
53-
print('average below label 4 = {}'.format( m.measure.volume(pfi_im, anatomy_filename=pfi_im, labels=4)['Average below label'].values) )
54-
print('9**3 * 4 / 9 ** 3 = {}'.format(9 ** 3 * 4 / float(9 ** 3)))
55-
print('average below labels [1,3] = {}'.format(
56-
m.measure.volume(pfi_im, anatomy_filename=pfi_im, labels=[1,3])['Average below label'].values)
57-
)
58-
print('11**3 * 1 / 11**3, 19**3 * 3/ 19 ** 3 = {}'.format([11 ** 3 * 1 / float(11 ** 3),
59-
19 ** 3 * 3 / float(19 ** 3)]))
60-
print('average below labels [[1, 3]] = {}'.format(
61-
m.measure.volume(pfi_im, anatomy_filename=pfi_im, labels=[[1,3]])['Average below label'].values)
62-
)
63-
print('( 11**3 * 1 +19**3 * 3 ) / (11**3 + 19 ** 3) = {0}'.format( (11**3 * 1 +19**3 * 3) / float(11**3 + 19 ** 3)))
64-
print('\n\nTo sum up: \n')
65-
print('average below labels [1, 2, 3, 4, [1, 3]] = \n{}'.format(
66-
m.measure.volume(pfi_im, anatomy_filename=pfi_im, labels=[1, 2, 3, 4, [1, 3]] ))
67-
)
48+
vals_below_labels = m.measure.values_below_labels(pfi_im, pfi_im, labels=[1, 2, 3, 4, 5, [1, 3]])
49+
50+
print('average below labels [1, 2, 3, 4, [1, 3]] = \n{}'.format(vals_below_labels))
51+
52+
print('mu, std below label 1 = {} {}'.format(np.mean(vals_below_labels['1']), np.std(vals_below_labels['1'])))
53+
print('mu, std below label 2 = {} {}'.format(np.mean(vals_below_labels['2']), np.std(vals_below_labels['2'])))
54+
print('mu, std below label 3 = {} {}'.format(np.mean(vals_below_labels['3']), np.std(vals_below_labels['3'])))
55+
print('mu, std below label 4 = {} {}'.format(np.mean(vals_below_labels['4']), np.std(vals_below_labels['4'])))
56+
# print('mu, std below label 5 = {} {}'.format(np.mean(vals_below_labels['5']), np.std(vals_below_labels['5'])))
57+
print('mu, std below label [1, 3] = {} {}'.format(np.mean(vals_below_labels['[1, 3]']), np.std(vals_below_labels['[1, 3]'])))
58+
59+
print('\nValues as they are reported: {}'.format(vals_below_labels))
60+

examples/icv_estimation_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# Wip
1+
# TODO

0 commit comments

Comments
 (0)