biomedisa 24.8.10__py3-none-any.whl → 24.8.11__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.
- biomedisa/deeplearning.py +8 -1
- biomedisa/features/DataGenerator.py +122 -2
- biomedisa/features/biomedisa_helper.py +28 -9
- biomedisa/features/keras_helper.py +8 -9
- biomedisa/features/remove_outlier.py +3 -3
- biomedisa/features/split_volume.py +12 -11
- biomedisa/interpolation.py +3 -8
- biomedisa/mesh.py +2 -2
- {biomedisa-24.8.10.dist-info → biomedisa-24.8.11.dist-info}/METADATA +1 -1
- {biomedisa-24.8.10.dist-info → biomedisa-24.8.11.dist-info}/RECORD +13 -13
- {biomedisa-24.8.10.dist-info → biomedisa-24.8.11.dist-info}/LICENSE +0 -0
- {biomedisa-24.8.10.dist-info → biomedisa-24.8.11.dist-info}/WHEEL +0 -0
- {biomedisa-24.8.10.dist-info → biomedisa-24.8.11.dist-info}/top_level.txt +0 -0
biomedisa/deeplearning.py
CHANGED
@@ -67,7 +67,7 @@ def deep_learning(img_data, label_data=None, val_img_data=None, val_label_data=N
|
|
67
67
|
balance=False, crop_data=False, flip_x=False, flip_y=False, flip_z=False,
|
68
68
|
swapaxes=False, train_dice=False, val_dice=True, compression=True, ignore='none', only='all',
|
69
69
|
network_filters='32-64-128-256-512', resnet=False, debug_cropping=False,
|
70
|
-
save_cropped=False, epochs=100, normalization=True, rotate=0.0, validation_split=0.0,
|
70
|
+
save_cropped=False, epochs=100, normalization=True, rotate=0.0, rotate3d=0.0, validation_split=0.0,
|
71
71
|
learning_rate=0.01, stride_size=32, validation_stride_size=32, validation_freq=1,
|
72
72
|
batch_size=None, x_scale=256, y_scale=256, z_scale=256, scaling=True, early_stopping=0,
|
73
73
|
pretrained_model=None, fine_tune=False, workers=1, cropping_epochs=50,
|
@@ -436,6 +436,8 @@ if __name__ == '__main__':
|
|
436
436
|
help='Disable normalization of 3D image volumes')
|
437
437
|
parser.add_argument('-r','--rotate', type=float, default=0.0,
|
438
438
|
help='Randomly rotate during training')
|
439
|
+
parser.add_argument('--rotate3d', action='store_true', default=False,
|
440
|
+
help='Randomly rotate through three dimensions during training. Uniformly distributed over the sphere.')
|
439
441
|
parser.add_argument('-vs','--validation_split', type=float, default=0.0,
|
440
442
|
help='Percentage of data used for training')
|
441
443
|
parser.add_argument('-lr','--learning_rate', type=float, default=0.01,
|
@@ -507,6 +509,11 @@ if __name__ == '__main__':
|
|
507
509
|
bm = parser.parse_args()
|
508
510
|
bm.success = True
|
509
511
|
|
512
|
+
if bm.rotate3d and not bm.scaling:
|
513
|
+
raise RuntimeError("You cannot do true 3d rotation without rescaling the data yet.")
|
514
|
+
# To fix this, have the loading function pass in a list of where the images end,
|
515
|
+
# and use that to figure out the z-centres in biomedisa.features.DataGenerator.rotate_*_3d
|
516
|
+
|
510
517
|
# prediction or training
|
511
518
|
if not any([bm.train, bm.predict]):
|
512
519
|
bm.predict = False
|
@@ -32,6 +32,25 @@ import numba
|
|
32
32
|
import random
|
33
33
|
import scipy
|
34
34
|
|
35
|
+
def get_random_rotation_matrix(batch_size):
|
36
|
+
angle_xy = np.random.uniform(0, 2. * np.pi, batch_size)
|
37
|
+
Householder_1 = np.random.uniform(0, 2. * np.pi, batch_size)
|
38
|
+
Householder_2 = np.random.uniform(0, 1., batch_size)
|
39
|
+
# Matrix for xy rotation
|
40
|
+
RR = np.zeros([batch_size, 3, 3])
|
41
|
+
RR[:, 0, 0] = np.cos(angle_xy[:])
|
42
|
+
RR[:, 0, 1] = np.sin(angle_xy[:])
|
43
|
+
RR[:, 1, 0] = np.cos(angle_xy[:])
|
44
|
+
RR[:, 1, 1] = -np.sin(angle_xy[:])
|
45
|
+
RR[:, 2, 2] = 1.
|
46
|
+
# Householder matrix
|
47
|
+
vv = np.zeros([batch_size, 3, 1])
|
48
|
+
vv[:, 0, 0] = np.cos(Householder_1[:]) * np.sqrt(Householder_2[:])
|
49
|
+
vv[:, 1, 0] = np.sin(Householder_1[:]) * np.sqrt(Householder_2[:])
|
50
|
+
vv[:, 2, 0] = np.sqrt(1. - Householder_2[:])
|
51
|
+
HH = np.eye(3)[np.newaxis, :, :] - 2. * np.matmul(vv, vv.transpose(0, 2, 1))
|
52
|
+
return -np.matmul(HH, RR)
|
53
|
+
|
35
54
|
@numba.jit(nopython=True)#parallel=True
|
36
55
|
def rotate_img_patch(src,trg,k,l,m,cos_a,sin_a,z_patch,y_patch,x_patch,imageHeight,imageWidth):
|
37
56
|
for y in range(l,l+y_patch):
|
@@ -61,6 +80,57 @@ def rotate_img_patch(src,trg,k,l,m,cos_a,sin_a,z_patch,y_patch,x_patch,imageHeig
|
|
61
80
|
trg[z-k,y-l,x-m] = val
|
62
81
|
return trg
|
63
82
|
|
83
|
+
|
84
|
+
@numba.jit(nopython=True)#parallel=True
|
85
|
+
def rotate_img_patch_3d(src,trg,k,l,m,rm_xx,rm_xy,rm_xz,rm_yx,rm_yy,rm_yz,rm_zx,rm_zy,rm_zz,z_patch,y_patch,x_patch,imageVertStride,imageDepth,imageHeight,imageWidth):
|
86
|
+
#return rotate_label_patch_3d(src,trg,k,l,m,rm_xx,rm_xy,rm_xz,rm_yx,rm_yy,rm_yz,rm_zx,rm_zy,rm_zz,z_patch,y_patch,x_patch,imageVertStride,imageDepth,imageHeight,imageWidth)
|
87
|
+
for z in range(k,k+z_patch):
|
88
|
+
zCentreRotation = imageVertStride * (z // imageVertStride) + imageVertStride/2
|
89
|
+
zA = z - zCentreRotation
|
90
|
+
for y in range(l,l+y_patch):
|
91
|
+
yA = y - imageHeight/2
|
92
|
+
for x in range(m,m+x_patch):
|
93
|
+
xA = x - imageWidth/2
|
94
|
+
xR = xA * rm_xx + yA * rm_xy + zA * rm_xz
|
95
|
+
yR = xA * rm_yx + yA * rm_yy + zA * rm_yz
|
96
|
+
zR = xA * rm_zx + yA * rm_zy + zA * rm_zz
|
97
|
+
src_x = xR + imageWidth/2
|
98
|
+
src_y = yR + imageHeight/2
|
99
|
+
src_z = zR + zCentreRotation
|
100
|
+
# bilinear interpolation
|
101
|
+
src_x0 = float(int(src_x))
|
102
|
+
src_x1 = src_x0 + 1
|
103
|
+
src_y0 = float(int(src_y))
|
104
|
+
src_y1 = src_y0 + 1
|
105
|
+
src_z0 = float(int(src_z))
|
106
|
+
src_z1 = src_z0 + 1
|
107
|
+
sx = src_x - src_x0
|
108
|
+
sy = src_y - src_y0
|
109
|
+
sz = src_z - src_z0
|
110
|
+
idx_src_x0 = int(min(max(0,src_x0),imageWidth-1))
|
111
|
+
idx_src_x1 = int(min(max(0,src_x1),imageWidth-1))
|
112
|
+
idx_src_y0 = int(min(max(0,src_y0),imageHeight-1))
|
113
|
+
idx_src_y1 = int(min(max(0,src_y1),imageHeight-1))
|
114
|
+
idx_src_z0 = int(min(max(0,src_z0),imageDepth-1))
|
115
|
+
idx_src_z1 = int(min(max(0,src_z1),imageDepth-1))
|
116
|
+
|
117
|
+
val = (1-sy) * (1-sx) * (1-sz) * float(src[idx_src_z0,idx_src_y0,idx_src_x0])
|
118
|
+
val += (sy) * (1-sx) * (1-sz) * float(src[idx_src_z0,idx_src_y1,idx_src_x0])
|
119
|
+
val += (1-sy) * (sx) * (1-sz) * float(src[idx_src_z0,idx_src_y0,idx_src_x1])
|
120
|
+
val += (sy) * (sx) * (1-sz) * float(src[idx_src_z0,idx_src_y1,idx_src_x1])
|
121
|
+
val += (1-sy) * (1-sx) * (sz) * float(src[idx_src_z1,idx_src_y0,idx_src_x0])
|
122
|
+
val += (sy) * (1-sx) * (sz) * float(src[idx_src_z1,idx_src_y1,idx_src_x0])
|
123
|
+
val += (1-sy) * (sx) * (sz) * float(src[idx_src_z1,idx_src_y0,idx_src_x1])
|
124
|
+
val += (sy) * (sx) * (sz) * float(src[idx_src_z1,idx_src_y1,idx_src_x1])
|
125
|
+
trg[z-k,y-l,x-m] = val
|
126
|
+
return trg
|
127
|
+
|
128
|
+
# This exists so I could test it. It's not called because sometimes numba is funny about nested
|
129
|
+
# nopython functions.
|
130
|
+
@numba.jit(nopython=True)#parallel=True
|
131
|
+
def centre_of_z_rotation(z, imageVertStride):
|
132
|
+
return imageVertStride * (z // imageVertStride) + imageVertStride/2
|
133
|
+
|
64
134
|
@numba.jit(nopython=True)#parallel=True
|
65
135
|
def rotate_label_patch(src,trg,k,l,m,cos_a,sin_a,z_patch,y_patch,x_patch,imageHeight,imageWidth):
|
66
136
|
for y in range(l,l+y_patch):
|
@@ -80,6 +150,31 @@ def rotate_label_patch(src,trg,k,l,m,cos_a,sin_a,z_patch,y_patch,x_patch,imageHe
|
|
80
150
|
trg[z-k,y-l,x-m] = src[z,idx_src_y,idx_src_x]
|
81
151
|
return trg
|
82
152
|
|
153
|
+
@numba.jit(nopython=True)#parallel=True
|
154
|
+
def rotate_label_patch_3d(src,trg,k,l,m,rm_xx,rm_xy,rm_xz,rm_yx,rm_yy,rm_yz,rm_zx,rm_zy,rm_zz,z_patch,y_patch,x_patch,imageVertStride,imageDepth,imageHeight,imageWidth):
|
155
|
+
for z in range(k,k+z_patch):
|
156
|
+
zCentreRotation = imageVertStride * (z // imageVertStride) + imageVertStride/2
|
157
|
+
zA = z - zCentreRotation
|
158
|
+
for y in range(l,l+y_patch):
|
159
|
+
yA = y - imageHeight/2
|
160
|
+
for x in range(m,m+x_patch):
|
161
|
+
xA = x - imageWidth/2
|
162
|
+
xR = xA * rm_xx + yA * rm_xy + zA * rm_xz
|
163
|
+
yR = xA * rm_yx + yA * rm_yy + zA * rm_yz
|
164
|
+
zR = xA * rm_zx + yA * rm_zy + zA * rm_zz
|
165
|
+
src_x = xR + imageWidth/2
|
166
|
+
src_y = yR + imageHeight/2
|
167
|
+
src_z = zR + zCentreRotation
|
168
|
+
# nearest neighbour
|
169
|
+
src_x = round(src_x)
|
170
|
+
src_y = round(src_y)
|
171
|
+
src_z = round(src_z)
|
172
|
+
idx_src_x = int(min(max(0,src_x),imageWidth-1))
|
173
|
+
idx_src_y = int(min(max(0,src_y),imageHeight-1))
|
174
|
+
idx_src_z = int(min(max(0,src_z),imageDepth-1))
|
175
|
+
trg[z-k,y-l,x-m] = src[idx_src_z,idx_src_y,idx_src_x]
|
176
|
+
return trg
|
177
|
+
|
83
178
|
def random_rotation_3d(image, max_angle=180):
|
84
179
|
""" Randomly rotate an image by a random angle (-max_angle, max_angle).
|
85
180
|
|
@@ -107,7 +202,7 @@ def random_rotation_3d(image, max_angle=180):
|
|
107
202
|
class DataGenerator(tf.keras.utils.Sequence):
|
108
203
|
'Generates data for Keras'
|
109
204
|
def __init__(self, img, label, list_IDs_fg, list_IDs_bg, shuffle, train, classification, batch_size=32, dim=(32,32,32),
|
110
|
-
dim_img=(32,32,32), n_classes=10, n_channels=1, augment=(False,False,False,False,0), patch_normalization=False, separation=False):
|
205
|
+
dim_img=(32,32,32), n_classes=10, n_channels=1, augment=(False,False,False,False,0,False), patch_normalization=False, separation=False):
|
111
206
|
'Initialization'
|
112
207
|
self.dim = dim
|
113
208
|
self.dim_img = dim_img
|
@@ -189,7 +284,7 @@ class DataGenerator(tf.keras.utils.Sequence):
|
|
189
284
|
y = np.empty((self.batch_size, *self.dim, 1), dtype=np.int32)
|
190
285
|
|
191
286
|
# get augmentation parameter
|
192
|
-
flip_x, flip_y, flip_z, swapaxes, rotate = self.augment
|
287
|
+
flip_x, flip_y, flip_z, swapaxes, rotate, rotate3d = self.augment
|
193
288
|
n_aug = np.sum([flip_z, flip_y, flip_x])
|
194
289
|
flips = np.where([flip_z, flip_y, flip_x])[0]
|
195
290
|
|
@@ -198,6 +293,8 @@ class DataGenerator(tf.keras.utils.Sequence):
|
|
198
293
|
angle = np.random.uniform(-1,1,self.batch_size) * 3.1416/180*rotate
|
199
294
|
cos_angle = np.cos(angle)
|
200
295
|
sin_angle = np.sin(angle)
|
296
|
+
if rotate3d:
|
297
|
+
rot_mtx = get_random_rotation_matrix(self.batch_size)
|
201
298
|
|
202
299
|
# Generate data
|
203
300
|
for i, ID in enumerate(list_IDs_temp):
|
@@ -268,6 +365,29 @@ class DataGenerator(tf.keras.utils.Sequence):
|
|
268
365
|
tmp_y = rotate_label_patch(self.label,tmp_y,k,l,m,cos_a,sin_a,
|
269
366
|
self.dim[0],self.dim[1],self.dim[2],
|
270
367
|
self.dim_img[1],self.dim_img[2])
|
368
|
+
|
369
|
+
# rotate through a random 3d angle, uniformly distributed on a sphere.
|
370
|
+
if rotate3d:
|
371
|
+
tmp_X = np.empty((*self.dim, self.n_channels), dtype=np.float32)
|
372
|
+
tmp_y = np.empty(self.dim, dtype=np.int32)
|
373
|
+
rm_xx = rot_mtx[i, 0, 0]
|
374
|
+
rm_xy = rot_mtx[i, 0, 1]
|
375
|
+
rm_xz = rot_mtx[i, 0, 2]
|
376
|
+
rm_yx = rot_mtx[i, 1, 0]
|
377
|
+
rm_yy = rot_mtx[i, 1, 1]
|
378
|
+
rm_yz = rot_mtx[i, 1, 2]
|
379
|
+
rm_zx = rot_mtx[i, 2, 0]
|
380
|
+
rm_zy = rot_mtx[i, 2, 1]
|
381
|
+
rm_zz = rot_mtx[i, 2, 2]
|
382
|
+
for c in range(self.n_channels):
|
383
|
+
tmp_X[:,:,:,c] = rotate_img_patch_3d(self.img[:,:,:,c],tmp_X[:,:,:,c],k,l,m,
|
384
|
+
rm_xx,rm_xy,rm_xz,rm_yx,rm_yy,rm_yz,rm_zx,rm_zy,rm_zz,
|
385
|
+
self.dim[0],self.dim[1],self.dim[2],
|
386
|
+
256, self.dim_img[0],self.dim_img[1],self.dim_img[2])
|
387
|
+
tmp_y = rotate_label_patch_3d(self.label,tmp_y,k,l,m,
|
388
|
+
rm_xx,rm_xy,rm_xz,rm_yx,rm_yy,rm_yz,rm_zx,rm_zy,rm_zz,
|
389
|
+
self.dim[0],self.dim[1],self.dim[2],
|
390
|
+
256, self.dim_img[0],self.dim_img[1],self.dim_img[2])
|
271
391
|
|
272
392
|
# flip patch along axes
|
273
393
|
v = np.random.randint(n_aug+1)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
##########################################################################
|
2
2
|
## ##
|
3
|
-
## Copyright (c) 2019-
|
3
|
+
## Copyright (c) 2019-2025 Philipp Lösel. All rights reserved. ##
|
4
4
|
## ##
|
5
5
|
## This file is part of the open source project biomedisa. ##
|
6
6
|
## ##
|
@@ -52,6 +52,26 @@ def silent_remove(filename):
|
|
52
52
|
except OSError:
|
53
53
|
pass
|
54
54
|
|
55
|
+
# determine all values and their count from an array
|
56
|
+
def unique(arr, return_counts=False):
|
57
|
+
try:
|
58
|
+
arr = arr.ravel()
|
59
|
+
counts = np.zeros(np.amax(arr)+1, dtype=int)
|
60
|
+
@numba.jit(nopython=True)
|
61
|
+
def __unique__(arr, size, counts):
|
62
|
+
for k in range(size):
|
63
|
+
counts[arr[k]] += 1
|
64
|
+
return counts
|
65
|
+
counts = __unique__(arr, arr.size, counts)
|
66
|
+
labels = np.where(counts)[0]
|
67
|
+
if return_counts:
|
68
|
+
return labels, counts[labels]
|
69
|
+
else:
|
70
|
+
return labels
|
71
|
+
except Exception as e:
|
72
|
+
print(f"Error: {e}")
|
73
|
+
return None
|
74
|
+
|
55
75
|
# create a unique filename
|
56
76
|
def unique_file_path(path, dir_path=biomedisa.BASE_DIR+'/private_storage/'):
|
57
77
|
|
@@ -105,7 +125,7 @@ def unique_file_path(path, dir_path=biomedisa.BASE_DIR+'/private_storage/'):
|
|
105
125
|
def Dice_score(ground_truth, result, average_dice=False):
|
106
126
|
if average_dice:
|
107
127
|
dice = 0
|
108
|
-
allLabels =
|
128
|
+
allLabels = unique(ground_truth)
|
109
129
|
for l in allLabels[1:]:
|
110
130
|
dice += 2 * np.logical_and(ground_truth==l, result==l).sum() / float((ground_truth==l).sum() + (result==l).sum())
|
111
131
|
dice /= float(len(allLabels)-1)
|
@@ -120,7 +140,7 @@ def ASSD(ground_truth, result):
|
|
120
140
|
number_of_elements = 0
|
121
141
|
distances = 0
|
122
142
|
hausdorff = 0
|
123
|
-
for label in
|
143
|
+
for label in unique(ground_truth)[1:]:
|
124
144
|
d, n, h = ASSD_one_label(ground_truth, result, label)
|
125
145
|
number_of_elements += n
|
126
146
|
distances += d
|
@@ -157,7 +177,7 @@ def img_resize(a, z_shape, y_shape, x_shape, interpolation=None, labels=False):
|
|
157
177
|
|
158
178
|
if labels:
|
159
179
|
data = np.zeros((z_shape, y_shape, x_shape), dtype=a.dtype)
|
160
|
-
for k in
|
180
|
+
for k in unique(a):
|
161
181
|
if k!=0:
|
162
182
|
tmp = np.zeros(a.shape, dtype=np.uint8)
|
163
183
|
tmp[a==k] = 1
|
@@ -193,7 +213,7 @@ def set_labels_to_zero(label, labels_to_compute, labels_to_remove):
|
|
193
213
|
# compute only specific labels (set rest to zero)
|
194
214
|
labels_to_compute = labels_to_compute.split(',')
|
195
215
|
if not any([x in ['all', 'All', 'ALL'] for x in labels_to_compute]):
|
196
|
-
allLabels =
|
216
|
+
allLabels = unique(label)
|
197
217
|
labels_to_del = [k for k in allLabels if str(k) not in labels_to_compute and k > 0]
|
198
218
|
for k in labels_to_del:
|
199
219
|
label[label == k] = 0
|
@@ -430,7 +450,7 @@ def pre_processing(bm):
|
|
430
450
|
bm.labelData = bm.labelData.astype(np.int32)
|
431
451
|
|
432
452
|
# get labels
|
433
|
-
bm.allLabels =
|
453
|
+
bm.allLabels = unique(bm.labelData)
|
434
454
|
index = np.argwhere(bm.allLabels<0)
|
435
455
|
bm.allLabels = np.delete(bm.allLabels, index)
|
436
456
|
|
@@ -553,7 +573,7 @@ def color_to_gray(labelData):
|
|
553
573
|
return labelData
|
554
574
|
|
555
575
|
def delbackground(labels):
|
556
|
-
allLabels, labelcounts =
|
576
|
+
allLabels, labelcounts = unique(labels, return_counts=True)
|
557
577
|
index = np.argmax(labelcounts)
|
558
578
|
labels[labels==allLabels[index]] = 0
|
559
579
|
return labels
|
@@ -844,9 +864,8 @@ def _split_indices(indices, ngpus):
|
|
844
864
|
return parts
|
845
865
|
|
846
866
|
def get_labels(pre_final, labels):
|
847
|
-
numos = np.unique(pre_final)
|
848
867
|
final = np.zeros_like(pre_final)
|
849
|
-
for k in
|
868
|
+
for k in unique(pre_final)[1:]:
|
850
869
|
final[pre_final == k] = labels[k]
|
851
870
|
return final
|
852
871
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
##########################################################################
|
2
2
|
## ##
|
3
|
-
## Copyright (c) 2019-
|
3
|
+
## Copyright (c) 2019-2025 Philipp Lösel. All rights reserved. ##
|
4
4
|
## ##
|
5
5
|
## This file is part of the open source project biomedisa. ##
|
6
6
|
## ##
|
@@ -41,7 +41,7 @@ from tensorflow.keras.utils import to_categorical
|
|
41
41
|
from tensorflow.keras.callbacks import Callback, ModelCheckpoint, EarlyStopping
|
42
42
|
from biomedisa.features.DataGenerator import DataGenerator
|
43
43
|
from biomedisa.features.PredictDataGenerator import PredictDataGenerator
|
44
|
-
from biomedisa.features.biomedisa_helper import (
|
44
|
+
from biomedisa.features.biomedisa_helper import (unique,
|
45
45
|
img_resize, load_data, save_data, set_labels_to_zero, id_generator, unique_file_path)
|
46
46
|
from biomedisa.features.remove_outlier import clean, fill
|
47
47
|
from biomedisa.features.active_contour import activeContour
|
@@ -319,9 +319,8 @@ def make_unet(input_shape, nb_labels, filters='32-64-128-256-512', resnet=False)
|
|
319
319
|
return model
|
320
320
|
|
321
321
|
def get_labels(arr, allLabels):
|
322
|
-
np_unique = np.unique(arr)
|
323
322
|
final = np.zeros_like(arr)
|
324
|
-
for k in
|
323
|
+
for k in unique(arr):
|
325
324
|
final[arr == k] = allLabels[k]
|
326
325
|
return final
|
327
326
|
|
@@ -412,7 +411,7 @@ def load_training_data(bm, img_list, label_list, channels, img_in=None, label_in
|
|
412
411
|
argmin_z,argmax_z,argmin_y,argmax_y,argmin_x,argmax_x = predict_blocksize(label, x_puffer, y_puffer, z_puffer)
|
413
412
|
label = label[argmin_z:argmax_z,argmin_y:argmax_y,argmin_x:argmax_x].copy()
|
414
413
|
if bm.scaling:
|
415
|
-
label_values, counts =
|
414
|
+
label_values, counts = unique(label, return_counts=True)
|
416
415
|
print(f'{os.path.basename(label_names[0])}:', 'Labels:', label_values[1:], 'Sizes:', counts[1:])
|
417
416
|
label = img_resize(label, bm.z_scale, bm.y_scale, bm.x_scale, labels=True)
|
418
417
|
|
@@ -514,7 +513,7 @@ def load_training_data(bm, img_list, label_list, channels, img_in=None, label_in
|
|
514
513
|
argmin_z,argmax_z,argmin_y,argmax_y,argmin_x,argmax_x = predict_blocksize(a, x_puffer, y_puffer, z_puffer)
|
515
514
|
a = np.copy(a[argmin_z:argmax_z,argmin_y:argmax_y,argmin_x:argmax_x], order='C')
|
516
515
|
if bm.scaling:
|
517
|
-
label_values, counts =
|
516
|
+
label_values, counts = unique(a, return_counts=True)
|
518
517
|
print(f'{os.path.basename(label_names[k])}:', 'Labels:', label_values[1:], 'Sizes:', counts[1:])
|
519
518
|
a = img_resize(a, bm.z_scale, bm.y_scale, bm.x_scale, labels=True)
|
520
519
|
label = np.append(label, a, axis=0)
|
@@ -587,7 +586,7 @@ def load_training_data(bm, img_list, label_list, channels, img_in=None, label_in
|
|
587
586
|
else:
|
588
587
|
# get labels
|
589
588
|
if allLabels is None:
|
590
|
-
allLabels =
|
589
|
+
allLabels = unique(label)
|
591
590
|
index = np.argwhere(allLabels<0)
|
592
591
|
allLabels = np.delete(allLabels, index)
|
593
592
|
|
@@ -987,7 +986,7 @@ def train_segmentation(bm):
|
|
987
986
|
'dim_img': (zsh, ysh, xsh),
|
988
987
|
'n_classes': nb_labels,
|
989
988
|
'n_channels': bm.channels,
|
990
|
-
'augment': (bm.flip_x, bm.flip_y, bm.flip_z, bm.swapaxes, bm.rotate),
|
989
|
+
'augment': (bm.flip_x, bm.flip_y, bm.flip_z, bm.swapaxes, bm.rotate, bm.rotate3d),
|
991
990
|
'patch_normalization': bm.patch_normalization,
|
992
991
|
'separation': bm.separation}
|
993
992
|
|
@@ -999,7 +998,7 @@ def train_segmentation(bm):
|
|
999
998
|
val_metrics = Metrics(bm, bm.val_img_data, bm.val_label_data, list_IDs_val_fg, (zsh_val, ysh_val, xsh_val), nb_labels, False)
|
1000
999
|
else:
|
1001
1000
|
params['dim_img'] = (zsh_val, ysh_val, xsh_val)
|
1002
|
-
params['augment'] = (False, False, False, False, 0)
|
1001
|
+
params['augment'] = (False, False, False, False, 0, False)
|
1003
1002
|
validation_generator = DataGenerator(bm.val_img_data, bm.val_label_data, list_IDs_val_fg, list_IDs_val_bg, True, False, False, **params)
|
1004
1003
|
|
1005
1004
|
# monitor dice score on training data
|
@@ -30,7 +30,7 @@
|
|
30
30
|
import os
|
31
31
|
import biomedisa
|
32
32
|
from biomedisa.features.biomedisa_helper import (load_data, save_data,
|
33
|
-
unique_file_path, silent_remove)
|
33
|
+
unique_file_path, silent_remove, unique)
|
34
34
|
import numpy as np
|
35
35
|
from scipy import ndimage
|
36
36
|
import argparse
|
@@ -60,7 +60,7 @@ def reduce_blocksize(data):
|
|
60
60
|
|
61
61
|
def clean(image, threshold=0.1):
|
62
62
|
image_i = np.copy(image, order='C')
|
63
|
-
allLabels =
|
63
|
+
allLabels = unique(image_i)
|
64
64
|
mask = np.empty_like(image_i)
|
65
65
|
s = [[[0,0,0], [0,1,0], [0,0,0]], [[0,1,0], [1,1,1], [0,1,0]], [[0,0,0], [0,1,0], [0,0,0]]]
|
66
66
|
for k in allLabels[1:]:
|
@@ -99,7 +99,7 @@ def clean(image, threshold=0.1):
|
|
99
99
|
|
100
100
|
def fill(image, threshold=0.9):
|
101
101
|
image_i = np.copy(image, order='C')
|
102
|
-
allLabels =
|
102
|
+
allLabels = unique(image_i)
|
103
103
|
mask = np.empty_like(image_i)
|
104
104
|
s = [[[0,0,0], [0,1,0], [0,0,0]], [[0,1,0], [1,1,1], [0,1,0]], [[0,0,0], [0,1,0], [0,0,0]]]
|
105
105
|
for k in allLabels[1:]:
|
@@ -132,17 +132,18 @@ if __name__ == '__main__':
|
|
132
132
|
labelData = labelData[datamin_z:datamax_z,datamin_y:datamax_y,datamin_x:datamax_x].copy()
|
133
133
|
|
134
134
|
# interpolation
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
135
|
+
if np.any(labelData):
|
136
|
+
results = smart_interpolation(data, labelData, uncertainty=args.uncertainty, allaxis=args.allaxis, smooth=args.smooth)
|
137
|
+
|
138
|
+
# append results
|
139
|
+
final[blockmin_z:blockmax_z,blockmin_y:blockmax_y,blockmin_x:blockmax_x] \
|
140
|
+
= results['regular'][blockmin_z-datamin_z:blockmax_z-datamin_z,blockmin_y-datamin_y:blockmax_y-datamin_y,blockmin_x-datamin_x:blockmax_x-datamin_x]
|
141
|
+
if 'smooth' in results and results['smooth'] is not None:
|
142
|
+
final_smooth[blockmin_z:blockmax_z,blockmin_y:blockmax_y,blockmin_x:blockmax_x] \
|
143
|
+
= results['smooth'][blockmin_z-datamin_z:blockmax_z-datamin_z,blockmin_y-datamin_y:blockmax_y-datamin_y,blockmin_x-datamin_x:blockmax_x-datamin_x]
|
144
|
+
if 'uncertainty' in results and results['uncertainty'] is not None:
|
145
|
+
final_uncertainty[blockmin_z:blockmax_z,blockmin_y:blockmax_y,blockmin_x:blockmax_x] \
|
146
|
+
= results['uncertainty'][blockmin_z-datamin_z:blockmax_z-datamin_z,blockmin_y-datamin_y:blockmax_y-datamin_y,blockmin_x-datamin_x:blockmax_x-datamin_x]
|
146
147
|
|
147
148
|
# path to regular result
|
148
149
|
filename, extension = os.path.splitext(os.path.basename(args.path_to_data))
|
biomedisa/interpolation.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/python3
|
2
2
|
##########################################################################
|
3
3
|
## ##
|
4
|
-
## Copyright (c) 2019-
|
4
|
+
## Copyright (c) 2019-2025 Philipp Lösel. All rights reserved. ##
|
5
5
|
## ##
|
6
6
|
## This file is part of the open source project biomedisa. ##
|
7
7
|
## ##
|
@@ -165,13 +165,8 @@ def smart_interpolation(data, labelData, nbrw=10, sorw=4000, acwe=False, acwe_al
|
|
165
165
|
bm.imageSize = int(bm.data.nbytes * 10e-7)
|
166
166
|
|
167
167
|
# add boundaries
|
168
|
-
|
169
|
-
|
170
|
-
tmp[1:-1, 1:-1, 1:-1] = bm.labelData
|
171
|
-
bm.labelData = tmp.copy(order='C')
|
172
|
-
tmp = np.zeros((1+zsh+1, 1+ysh+1, 1+xsh+1), dtype=bm.data.dtype)
|
173
|
-
tmp[1:-1, 1:-1, 1:-1] = bm.data
|
174
|
-
bm.data = tmp.copy(order='C')
|
168
|
+
bm.data = np.pad(bm.data, pad_width=1, mode='constant', constant_values=0)
|
169
|
+
bm.labelData = np.pad(bm.labelData, pad_width=1, mode='constant', constant_values=0)
|
175
170
|
bm.zsh, bm.ysh, bm.xsh = bm.data.shape
|
176
171
|
|
177
172
|
# check if labeled slices are adjacent
|
biomedisa/mesh.py
CHANGED
@@ -30,7 +30,7 @@
|
|
30
30
|
import os
|
31
31
|
import numpy as np
|
32
32
|
import biomedisa
|
33
|
-
from biomedisa.features.biomedisa_helper import load_data, unique_file_path
|
33
|
+
from biomedisa.features.biomedisa_helper import load_data, unique_file_path, unique
|
34
34
|
from biomedisa.features.django_env import create_pid_object
|
35
35
|
from vtk.util.numpy_support import vtk_to_numpy, numpy_to_vtk
|
36
36
|
from stl import mesh
|
@@ -107,7 +107,7 @@ def save_mesh(path_to_result, labels, x_res=1, y_res=1, z_res=1,
|
|
107
107
|
|
108
108
|
# get labels
|
109
109
|
zsh, ysh, xsh = labels.shape
|
110
|
-
allLabels =
|
110
|
+
allLabels = unique(labels)
|
111
111
|
b = np.empty_like(labels)
|
112
112
|
arr = np.empty((0,3,3))
|
113
113
|
nTotalCells = [0]
|
@@ -1,27 +1,27 @@
|
|
1
1
|
biomedisa/__init__.py,sha256=hw4mzEjGFXm-vxus2DBfKFW0nKoG0ibL5SH6ShfchrY,1526
|
2
2
|
biomedisa/__main__.py,sha256=a1--8vhtztWEloHVtbM43FZLCfrFo4BELgdsgtWE8ls,536
|
3
|
-
biomedisa/deeplearning.py,sha256=
|
4
|
-
biomedisa/interpolation.py,sha256=
|
5
|
-
biomedisa/mesh.py,sha256=
|
6
|
-
biomedisa/features/DataGenerator.py,sha256=
|
3
|
+
biomedisa/deeplearning.py,sha256=J7i3Sz0mJOSbImQ16QsflF6O-CZEr_Qf0HIcCvWZNa0,29138
|
4
|
+
biomedisa/interpolation.py,sha256=MR9rrnF_cRXF8kltUFgVoeu89Zd8hGoGcFprkoUcURg,17074
|
5
|
+
biomedisa/mesh.py,sha256=ArBsKtf2m-KlWNUFMFRJgoiMcKJnHuUMtHI5NvQd4kQ,16067
|
6
|
+
biomedisa/features/DataGenerator.py,sha256=pAq_xGky49Y1_VYVLcNcTJ4JmJAn4orIDxGBlQmYTKs,19627
|
7
7
|
biomedisa/features/DataGeneratorCrop.py,sha256=KtGqNadghOd59wIU9hATM_5YgSks95rS1kJ2lsSSX7w,6612
|
8
8
|
biomedisa/features/PredictDataGenerator.py,sha256=JH8SPGQm-Y7_Drec2fw3jBUupvpIkQ1FvkDXP7mUjDY,4074
|
9
9
|
biomedisa/features/PredictDataGeneratorCrop.py,sha256=HF5tJbGtlJMHr7lMT9IiIdLG2CTjXstbKoOjlZJ93Is,3431
|
10
10
|
biomedisa/features/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
biomedisa/features/active_contour.py,sha256=FnPuvYck_KL4xYRFqwzm4Grdm288EdlcLFt88E0OtqA,17938
|
12
12
|
biomedisa/features/assd.py,sha256=q9NUQXEoA4Pi3d8b5fmys615CWu06Sm0N9-OGwJOFnw,6537
|
13
|
-
biomedisa/features/biomedisa_helper.py,sha256=
|
13
|
+
biomedisa/features/biomedisa_helper.py,sha256=pryGkMxAFdSDFpVF46DssUynmoyr1uLgKat9U_lFizw,33313
|
14
14
|
biomedisa/features/create_slices.py,sha256=uSDH1OcEYc5BFPZHSy3UpS4P2DuoVnxOZ-l7wmyT_Po,13108
|
15
15
|
biomedisa/features/crop_helper.py,sha256=ng0zc7csK23n1rr07adzxCS5OHvchqn20OI0EeRLzs8,24343
|
16
16
|
biomedisa/features/curvop_numba.py,sha256=AjKQJcUBoURTB8pq1HmugQYpBwBELthhcEu51_r_xPI,7049
|
17
17
|
biomedisa/features/django_env.py,sha256=LNrZ6rBHZ5I0FaWa5xN8K-ASPgq0r5dGDEUI56HzJxE,8615
|
18
|
-
biomedisa/features/keras_helper.py,sha256=
|
18
|
+
biomedisa/features/keras_helper.py,sha256=zykmixj1EktjQ-yFzRhO9Zhz49462mWec6P5731o-ZM,69496
|
19
19
|
biomedisa/features/nc_reader.py,sha256=RoRMwu3ELSNfoV3qZtaT2OWACnXb2EhNFu_DAF1T93o,7406
|
20
20
|
biomedisa/features/pid.py,sha256=Jmn1VIp0fBlgBrqZ-yUIQVVb5-NAxNBdibXALVr2PPI,2545
|
21
21
|
biomedisa/features/process_image.py,sha256=VtS3fGDvglqJiiJLPK1toe76J58j914NJ8XQKg3CRwo,11091
|
22
22
|
biomedisa/features/pycuda_test.py,sha256=UGAGIz_dgcCJkzjyCqnMlflp-WJPzpCtFQmE9C5DwIo,3275
|
23
|
-
biomedisa/features/remove_outlier.py,sha256=
|
24
|
-
biomedisa/features/split_volume.py,sha256=
|
23
|
+
biomedisa/features/remove_outlier.py,sha256=xa_a4hyEYv8dZRbBrbJyVTxzBGjgsIGZDU-XY1SSYNo,16629
|
24
|
+
biomedisa/features/split_volume.py,sha256=Selyt55ailT621XKpgcJ9IOahBETFhQZYWOUuD0P7gQ,8995
|
25
25
|
biomedisa/features/amira_to_np/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
26
26
|
biomedisa/features/amira_to_np/amira_data_stream.py,sha256=JrZTyKP01CKDFB5d9BlGtSFwBgoAo0AJeAmn3pADH88,32618
|
27
27
|
biomedisa/features/amira_to_np/amira_grammar.py,sha256=z1yajLHmn-GDb-rzZ5iHlKmPZDDbO9fNqP2jXf8z3KE,14324
|
@@ -37,8 +37,8 @@ biomedisa/features/random_walk/pyopencl_large.py,sha256=q79AxG3p3qFjxfiAZfUK9I5B
|
|
37
37
|
biomedisa/features/random_walk/pyopencl_small.py,sha256=opNlS-qzOa9qWafBNJdvf6r1aRAFf7_JXf6ISDnkdXE,17068
|
38
38
|
biomedisa/features/random_walk/rw_large.py,sha256=ZnITvk00Y11ZZlGuBRaJO1EwU0wYBdEwdpj9vvXCqF4,19805
|
39
39
|
biomedisa/features/random_walk/rw_small.py,sha256=RPzZe24YrEwYelJukDjvqaoD_SyhgdriEi7uV3kZGXI,14881
|
40
|
-
biomedisa-24.8.
|
41
|
-
biomedisa-24.8.
|
42
|
-
biomedisa-24.8.
|
43
|
-
biomedisa-24.8.
|
44
|
-
biomedisa-24.8.
|
40
|
+
biomedisa-24.8.11.dist-info/LICENSE,sha256=sehayP6UhydNnmstfL4yFR3genMRdpuUh6uZVWJN1H0,14152
|
41
|
+
biomedisa-24.8.11.dist-info/METADATA,sha256=4t6agbFHiT5W4BbEUh2X7OKSZhwVMQP4VoC2VLihje4,9933
|
42
|
+
biomedisa-24.8.11.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
43
|
+
biomedisa-24.8.11.dist-info/top_level.txt,sha256=opsf1Eb4vCguPSxev4HHSeiUKCccT_C_RcUCdAYbHWQ,10
|
44
|
+
biomedisa-24.8.11.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|