11import numpy as np
22from scipy import ndimage
3-
3+ import matplotlib .pyplot as plt
4+ import nibabel as nib
45
56def compute_bounding_box (mask_gt , mask_pred , exclusion_zone ):
67 mask_all = mask_gt | mask_pred
@@ -27,25 +28,26 @@ def compute_bounding_box(mask_gt, mask_pred, exclusion_zone):
2728 bbox_min [2 ] = np .min (idx_nonzero_2 )
2829 bbox_max [2 ] = np .max (idx_nonzero_2 )
2930
30- # crop the processing subvolume.
31- # we need to zeropad the cropped region with 1 voxel at the lower,
32- # the right and the back side. This is required to obtain the "full"
33- # convolution result with the 2x2x2 kernel
34- # cropmask = np.zeros((bbox_max - bbox_min)+2, np.uint8)
3531
3632 return bbox_min , bbox_max
3733
3834
3935def crop_mask (mask , bbox_min , bbox_max ):
36+
4037 cropmask = np .zeros ((bbox_max - bbox_min ) + 2 )
4138
4239 cropmask [0 :- 1 , 0 :- 1 , 0 :- 1 ] = mask [bbox_min [0 ]:bbox_max [0 ] + 1 ,
4340 bbox_min [1 ]:bbox_max [1 ] + 1 ,
4441 bbox_min [2 ]:bbox_max [2 ] + 1 ]
42+ # TODO: This is correct only if the object is interior to the bounding box. Must perform testing.
43+ # crop the processing subvolume.
44+ # we need to zeropad the cropped region with 1 voxel at the lower,
45+ # the right and the back side. This is required to obtain the "full"
46+ # convolution result with the 2x2x2 kernel
4547 return cropmask
4648
4749
48- def compute_distances (mask_gt , mask_pred , exclusion_zone , spacing_mm , connectivity = 1 , crop = True , exclusion_distance = 5 ):
50+ def compute_distances (mask_gt , mask_pred , affine_transform , exclusion_zone , spacing_mm , connectivity = 1 , crop = True , exclusion_distance = 5 ):
4951 if crop :
5052 if exclusion_zone is not None :
5153 bbox_min , bbox_max = compute_bounding_box (mask_gt , mask_pred , exclusion_zone )
@@ -58,16 +60,24 @@ def compute_distances(mask_gt, mask_pred, exclusion_zone, spacing_mm, connectivi
5860 mask_pred = crop_mask (mask_pred , bbox_min , bbox_max ).astype (np .bool )
5961
6062 border_inside = ndimage .binary_erosion (mask_gt , structure = ndimage .generate_binary_structure (3 , connectivity ))
61- borders_gt = mask_gt ^ border_inside
63+ ni_img = nib .Nifti1Image (border_inside .astype (np .uint8 ), affine_transform )
64+ nib .save (ni_img , 'border_inside_tumor.nii.gz' )
65+ borders_gt = mask_gt ^ border_inside # contours
66+ ni_img = nib .Nifti1Image (borders_gt .astype (np .uint8 ), affine_transform )
67+ nib .save (ni_img , 'contour_tumor.nii.gz' )
6268 border_inside = ndimage .binary_erosion (mask_pred , structure = ndimage .generate_binary_structure (3 , connectivity ))
63- borders_pred = mask_pred ^ border_inside
64-
65- # compute the distance transform (closest distance of each voxel to the
66- # surface voxels)
69+ borders_pred = mask_pred ^ border_inside # contours
70+ ni_img = nib . Nifti1Image ( borders_pred . astype ( np . uint8 ), affine_transform )
71+ nib . save ( ni_img , 'contour_ablation.nii.gz' )
72+ # compute the distance transform (closest distance of each voxel to the surface voxels)
6773 if borders_gt .any ():
6874 distmap_gt = ndimage .morphology .distance_transform_edt (
6975 ~ borders_gt , sampling = spacing_mm )
76+ ni_img = nib .Nifti1Image (distmap_gt .astype (np .uint8 ), affine_transform )
77+ nib .save (ni_img , 'distmap_tumor.nii.gz' )
7078 distmask_gt = mask_gt .astype (np .int8 )
79+ # todo: visualize with matplotlib
80+ # mark outside zones with -1
7181 distmask_gt [distmask_gt == 0 ] = - 1
7282 distmap_gt *= distmask_gt
7383 else :
@@ -76,7 +86,10 @@ def compute_distances(mask_gt, mask_pred, exclusion_zone, spacing_mm, connectivi
7686 if borders_pred .any ():
7787 distmap_pred = ndimage .morphology .distance_transform_edt (
7888 ~ borders_pred , sampling = spacing_mm )
89+ ni_img = nib .Nifti1Image (distmap_pred , affine_transform )
90+ nib .save (ni_img , 'distmap_ablation.nii.gz' )
7991 distmask_pred = mask_pred .astype (np .int8 )
92+ # mark outside zones with -1
8093 distmask_pred [distmask_pred == 0 ] = - 1
8194 distmap_pred *= distmask_pred
8295 else :
@@ -90,6 +103,7 @@ def compute_distances(mask_gt, mask_pred, exclusion_zone, spacing_mm, connectivi
90103 ~ borders_exclusion , sampling = spacing_mm )
91104
92105 distmask_exclusion = exclusion_zone .astype (np .int8 )
106+ # mark outside zones with -1
93107 distmask_exclusion [distmask_exclusion == 0 ] = - 1
94108 distmap_exclusion *= distmask_exclusion
95109
0 commit comments