chenz53 commited on
Commit
3f039bf
1 Parent(s): 16e2d73

Upload tumor_mask.py

Browse files
Files changed (1) hide show
  1. tumor_mask.py +84 -0
tumor_mask.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy import ndimage
3
+
4
+
5
+ def extract_tumor_and_peritumoral(mask_volume, peritumoral_margin=2, patch_size=(16, 16, 16)):
6
+ """
7
+ Extract tumor and peritumoral regions from a 3D annotation mask.
8
+ Flattens dilated mask into sequence of patches and creates position mask.
9
+
10
+ Parameters:
11
+ mask_volume: 3D numpy array (z, y, x) with tumor annotations (1 for tumor, 0 for background)
12
+ peritumoral_margin: Integer specifying the margin size (in voxels) for peritumoral region
13
+ patch_size: Tuple (z,y,x) specifying size of patches to use
14
+
15
+ Returns:
16
+ tumor_coords: List of coordinates (z, y, x) for tumor region
17
+ peritumoral_coords: List of coordinates (z, y, x) for peritumoral region
18
+ patch_mask: Binary mask indicating if patches contain tumor (1) or not (0)
19
+ """
20
+
21
+ # Get tumor coordinates
22
+ tumor_coords = np.where(mask_volume == 1)
23
+ tumor_coords = list(zip(tumor_coords[0], tumor_coords[1], tumor_coords[2]))
24
+
25
+ # Create dilated mask for peritumoral region
26
+ dilated_mask = ndimage.binary_dilation(
27
+ mask_volume,
28
+ structure=np.ones((peritumoral_margin * 2 + 1, peritumoral_margin * 2 + 1, peritumoral_margin * 2 + 1)),
29
+ )
30
+
31
+ # Create patch position mask
32
+ z_steps = mask_volume.shape[0] // patch_size[0]
33
+ y_steps = mask_volume.shape[1] // patch_size[1]
34
+ x_steps = mask_volume.shape[2] // patch_size[2]
35
+
36
+ patch_mask = np.zeros((z_steps, y_steps, x_steps))
37
+
38
+ for z in range(z_steps):
39
+ for y in range(y_steps):
40
+ for x in range(x_steps):
41
+ patch = dilated_mask[
42
+ z * patch_size[0] : (z + 1) * patch_size[0],
43
+ y * patch_size[1] : (y + 1) * patch_size[1],
44
+ x * patch_size[2] : (x + 1) * patch_size[2],
45
+ ]
46
+ if np.any(patch):
47
+ patch_mask[z, y, x] = 1
48
+
49
+ return tumor_coords, patch_mask.flatten()
50
+
51
+
52
+ # Example usage
53
+ def main():
54
+ # Create sample data for testing
55
+ volume_shape = (96, 96, 96)
56
+ mask_volume = np.zeros(volume_shape)
57
+
58
+ # Create a synthetic tumor mask in the middle
59
+ mask_volume[40:60, 40:60, 40:60] = 1
60
+
61
+ # Test parameters
62
+ patch_size = (16, 16, 16)
63
+ peritumoral_margin = 5
64
+
65
+ # Call function and get results
66
+ tumor_coords, patch_mask = extract_tumor_and_peritumoral(
67
+ mask_volume, peritumoral_margin=peritumoral_margin, patch_size=patch_size
68
+ )
69
+
70
+ # Print test results
71
+ print(f"Volume shape: {volume_shape}")
72
+ print(f"Tumor volume: {len(tumor_coords)}")
73
+ print(f"Number of total patches: {patch_mask.shape}")
74
+ print(f"Number of patches containing tumor/peritumoral region: {np.sum(patch_mask)}")
75
+
76
+ # Validate results
77
+ assert len(tumor_coords) > 0, "No tumor coordinates found"
78
+ assert len(patch_mask) == np.prod(np.array(volume_shape) // np.array(patch_size)), "Incorrect patch mask size"
79
+
80
+ return tumor_coords, patch_mask
81
+
82
+
83
+ if __name__ == "__main__":
84
+ tumor_coords, patch_mask = main()