biomedisa 2024.5.14__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/__init__.py +53 -0
- biomedisa/__main__.py +18 -0
- biomedisa/biomedisa_features/DataGenerator.py +299 -0
- biomedisa/biomedisa_features/DataGeneratorCrop.py +121 -0
- biomedisa/biomedisa_features/PredictDataGenerator.py +87 -0
- biomedisa/biomedisa_features/PredictDataGeneratorCrop.py +74 -0
- biomedisa/biomedisa_features/__init__.py +0 -0
- biomedisa/biomedisa_features/active_contour.py +434 -0
- biomedisa/biomedisa_features/amira_to_np/__init__.py +0 -0
- biomedisa/biomedisa_features/amira_to_np/amira_data_stream.py +980 -0
- biomedisa/biomedisa_features/amira_to_np/amira_grammar.py +369 -0
- biomedisa/biomedisa_features/amira_to_np/amira_header.py +290 -0
- biomedisa/biomedisa_features/amira_to_np/amira_helper.py +72 -0
- biomedisa/biomedisa_features/assd.py +167 -0
- biomedisa/biomedisa_features/biomedisa_helper.py +801 -0
- biomedisa/biomedisa_features/create_slices.py +286 -0
- biomedisa/biomedisa_features/crop_helper.py +586 -0
- biomedisa/biomedisa_features/curvop_numba.py +149 -0
- biomedisa/biomedisa_features/django_env.py +172 -0
- biomedisa/biomedisa_features/keras_helper.py +1219 -0
- biomedisa/biomedisa_features/nc_reader.py +179 -0
- biomedisa/biomedisa_features/pid.py +52 -0
- biomedisa/biomedisa_features/process_image.py +253 -0
- biomedisa/biomedisa_features/pycuda_test.py +84 -0
- biomedisa/biomedisa_features/random_walk/__init__.py +0 -0
- biomedisa/biomedisa_features/random_walk/gpu_kernels.py +183 -0
- biomedisa/biomedisa_features/random_walk/pycuda_large.py +826 -0
- biomedisa/biomedisa_features/random_walk/pycuda_large_allx.py +806 -0
- biomedisa/biomedisa_features/random_walk/pycuda_small.py +414 -0
- biomedisa/biomedisa_features/random_walk/pycuda_small_allx.py +493 -0
- biomedisa/biomedisa_features/random_walk/pyopencl_large.py +760 -0
- biomedisa/biomedisa_features/random_walk/pyopencl_small.py +441 -0
- biomedisa/biomedisa_features/random_walk/rw_large.py +390 -0
- biomedisa/biomedisa_features/random_walk/rw_small.py +310 -0
- biomedisa/biomedisa_features/remove_outlier.py +399 -0
- biomedisa/biomedisa_features/split_volume.py +274 -0
- biomedisa/deeplearning.py +519 -0
- biomedisa/interpolation.py +371 -0
- biomedisa/mesh.py +406 -0
- biomedisa-2024.5.14.dist-info/LICENSE +191 -0
- biomedisa-2024.5.14.dist-info/METADATA +306 -0
- biomedisa-2024.5.14.dist-info/RECORD +44 -0
- biomedisa-2024.5.14.dist-info/WHEEL +5 -0
- biomedisa-2024.5.14.dist-info/top_level.txt +1 -0
@@ -0,0 +1,149 @@
|
|
1
|
+
##########################################################################
|
2
|
+
## ##
|
3
|
+
## Copyright (c) 2024 Philipp Lösel. All rights reserved. ##
|
4
|
+
## ##
|
5
|
+
## This file is part of the open source project biomedisa. ##
|
6
|
+
## ##
|
7
|
+
## Licensed under the European Union Public Licence (EUPL) ##
|
8
|
+
## v1.2, or - as soon as they will be approved by the ##
|
9
|
+
## European Commission - subsequent versions of the EUPL; ##
|
10
|
+
## ##
|
11
|
+
## You may redistribute it and/or modify it under the terms ##
|
12
|
+
## of the EUPL v1.2. You may not use this work except in ##
|
13
|
+
## compliance with this Licence. ##
|
14
|
+
## ##
|
15
|
+
## You can obtain a copy of the Licence at: ##
|
16
|
+
## ##
|
17
|
+
## https://joinup.ec.europa.eu/page/eupl-text-11-12 ##
|
18
|
+
## ##
|
19
|
+
## Unless required by applicable law or agreed to in ##
|
20
|
+
## writing, software distributed under the Licence is ##
|
21
|
+
## distributed on an "AS IS" basis, WITHOUT WARRANTIES ##
|
22
|
+
## OR CONDITIONS OF ANY KIND, either express or implied. ##
|
23
|
+
## ##
|
24
|
+
## See the Licence for the specific language governing ##
|
25
|
+
## permissions and limitations under the Licence. ##
|
26
|
+
## ##
|
27
|
+
##########################################################################
|
28
|
+
|
29
|
+
import numpy as np
|
30
|
+
import numba
|
31
|
+
|
32
|
+
@numba.jit(nopython=True)
|
33
|
+
def evolution(mean, A, data, alpha):
|
34
|
+
zsh, ysh, xsh = A.shape
|
35
|
+
B = np.copy(A)
|
36
|
+
for k in range(1, zsh-1):
|
37
|
+
for l in range(1, ysh-1):
|
38
|
+
for m in range(1, xsh-1):
|
39
|
+
refLabel = A[k,l,m]
|
40
|
+
finLabel = refLabel
|
41
|
+
img = data[k,l,m]
|
42
|
+
if refLabel == 0:
|
43
|
+
ref = alpha * abs(mean[refLabel] - img)
|
44
|
+
else:
|
45
|
+
ref = abs(mean[refLabel] - img)
|
46
|
+
for n in range(-1, 2):
|
47
|
+
for o in range(-1, 2):
|
48
|
+
for p in range(-1, 2):
|
49
|
+
tmpLabel = A[k+n, l+o, m+p]
|
50
|
+
if tmpLabel != refLabel:
|
51
|
+
if tmpLabel == 0:
|
52
|
+
val = alpha * abs(mean[tmpLabel] - img)
|
53
|
+
else:
|
54
|
+
val = abs(mean[tmpLabel] - img)
|
55
|
+
if val < ref:
|
56
|
+
ref = val
|
57
|
+
finLabel = tmpLabel
|
58
|
+
B[k,l,m] = finLabel
|
59
|
+
return B
|
60
|
+
|
61
|
+
@numba.jit(nopython=True)
|
62
|
+
def erosion(start, final, _P3, zsh, ysh, xsh, label):
|
63
|
+
for plane in range(1, zsh-1):
|
64
|
+
for row in range(1, ysh-1):
|
65
|
+
for column in range(1, xsh-1):
|
66
|
+
found = 0
|
67
|
+
for n in range(-1, 2):
|
68
|
+
for o in range(-1, 2):
|
69
|
+
for p in range(-1, 2):
|
70
|
+
if start[plane+n, row+o, column+p] != label:
|
71
|
+
found = 1
|
72
|
+
if start[plane, row, column] == label and found == 1:
|
73
|
+
t, found = 0, 0
|
74
|
+
while t < 9 and found == 0:
|
75
|
+
value = 0
|
76
|
+
for k in range(3):
|
77
|
+
for l in range(3):
|
78
|
+
for m in range(3):
|
79
|
+
if _P3[t,k,l,m] == 1:
|
80
|
+
value += abs(start[plane-1+k, row-1+l, column-1+m] - label)
|
81
|
+
if value == 0:
|
82
|
+
found = 1
|
83
|
+
t += 1
|
84
|
+
if found == 0:
|
85
|
+
subLabel = label
|
86
|
+
for n in range(-1, 2):
|
87
|
+
for o in range(-1, 2):
|
88
|
+
for p in range(-1, 2):
|
89
|
+
tmpLabel = start[plane+n, row+o, column+p]
|
90
|
+
if tmpLabel != label:
|
91
|
+
subLabel = tmpLabel
|
92
|
+
final[plane, row, column] = subLabel
|
93
|
+
return start, final
|
94
|
+
|
95
|
+
@numba.jit(nopython=True)
|
96
|
+
def dilation(start, final, _P3, zsh, ysh, xsh, label):
|
97
|
+
for plane in range(1, zsh-1):
|
98
|
+
for row in range(1, ysh-1):
|
99
|
+
for column in range(1, xsh-1):
|
100
|
+
found = 0
|
101
|
+
for n in range(-1, 2):
|
102
|
+
for o in range(-1, 2):
|
103
|
+
for p in range(-1, 2):
|
104
|
+
if start[plane+n, row+o, column+p] == label:
|
105
|
+
found = 1
|
106
|
+
if start[plane, row, column] != label and found == 1:
|
107
|
+
t, found = 0, 0
|
108
|
+
while t < 9 and found == 0:
|
109
|
+
value = 0
|
110
|
+
for k in range(3):
|
111
|
+
for l in range(3):
|
112
|
+
for m in range(3):
|
113
|
+
if _P3[t,k,l,m] == 1 and start[plane-1+k, row-1+l, column-1+m] != label:
|
114
|
+
value += 0
|
115
|
+
else:
|
116
|
+
value += 1
|
117
|
+
if value == 0:
|
118
|
+
found = 1
|
119
|
+
t += 1
|
120
|
+
if found == 0:
|
121
|
+
final[plane, row, column] = label
|
122
|
+
return start, final
|
123
|
+
|
124
|
+
def curvop(start, steps, label, allLabels):
|
125
|
+
zsh, ysh, xsh = start.shape
|
126
|
+
final = np.copy(start, order='C')
|
127
|
+
_P3 = np.zeros((9,3,3,3), dtype=np.int32)
|
128
|
+
_P3[0,:,:,1] = 1
|
129
|
+
_P3[1,:,1,:] = 1
|
130
|
+
_P3[2,1,:,:] = 1
|
131
|
+
_P3[3,:,[0,1,2],[0,1,2]] = 1
|
132
|
+
_P3[4,:,[0,1,2],[2,1,0]] = 1
|
133
|
+
_P3[5,[0,1,2],:,[0,1,2]] = 1
|
134
|
+
_P3[6,[0,1,2],:,[2,1,0]] = 1
|
135
|
+
_P3[7,[0,1,2],[0,1,2],:] = 1
|
136
|
+
_P3[8,[0,1,2],[2,1,0],:] = 1
|
137
|
+
for k in range(steps):
|
138
|
+
if k % 2 == 0:
|
139
|
+
start, final = erosion(start, final, _P3, zsh, ysh, xsh, label)
|
140
|
+
start = np.copy(final, order='C')
|
141
|
+
final, start = dilation(final, start, _P3, zsh, ysh, xsh, label)
|
142
|
+
final = np.copy(start, order='C')
|
143
|
+
else:
|
144
|
+
start, final = dilation(start, final, _P3, zsh, ysh, xsh, label)
|
145
|
+
start = np.copy(final, order='C')
|
146
|
+
final, start = erosion(final, start, _P3, zsh, ysh, xsh, label)
|
147
|
+
final = np.copy(start, order='C')
|
148
|
+
return start
|
149
|
+
|
@@ -0,0 +1,172 @@
|
|
1
|
+
##########################################################################
|
2
|
+
## ##
|
3
|
+
## Copyright (c) 2024 Philipp Lösel. All rights reserved. ##
|
4
|
+
## ##
|
5
|
+
## This file is part of the open source project biomedisa. ##
|
6
|
+
## ##
|
7
|
+
## Licensed under the European Union Public Licence (EUPL) ##
|
8
|
+
## v1.2, or - as soon as they will be approved by the ##
|
9
|
+
## European Commission - subsequent versions of the EUPL; ##
|
10
|
+
## ##
|
11
|
+
## You may redistribute it and/or modify it under the terms ##
|
12
|
+
## of the EUPL v1.2. You may not use this work except in ##
|
13
|
+
## compliance with this Licence. ##
|
14
|
+
## ##
|
15
|
+
## You can obtain a copy of the Licence at: ##
|
16
|
+
## ##
|
17
|
+
## https://joinup.ec.europa.eu/page/eupl-text-11-12 ##
|
18
|
+
## ##
|
19
|
+
## Unless required by applicable law or agreed to in ##
|
20
|
+
## writing, software distributed under the Licence is ##
|
21
|
+
## distributed on an "AS IS" basis, WITHOUT WARRANTIES ##
|
22
|
+
## OR CONDITIONS OF ANY KIND, either express or implied. ##
|
23
|
+
## ##
|
24
|
+
## See the Licence for the specific language governing ##
|
25
|
+
## permissions and limitations under the Licence. ##
|
26
|
+
## ##
|
27
|
+
##########################################################################
|
28
|
+
|
29
|
+
import sys, os
|
30
|
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
31
|
+
import subprocess
|
32
|
+
|
33
|
+
def create_error_object(message, remote=False, queue=None, img_id=None):
|
34
|
+
|
35
|
+
# remote server
|
36
|
+
if remote:
|
37
|
+
with open(BASE_DIR + f'/log/error_{queue}', 'w') as errorfile:
|
38
|
+
print(message, file=errorfile)
|
39
|
+
|
40
|
+
# local server
|
41
|
+
else:
|
42
|
+
import django
|
43
|
+
django.setup()
|
44
|
+
from biomedisa_app.models import Upload
|
45
|
+
from biomedisa_app.views import send_error_message
|
46
|
+
image = Upload.objects.get(pk=img_id)
|
47
|
+
Upload.objects.create(user=image.user, project=image.project, log=1, imageType=None, shortfilename=message)
|
48
|
+
send_error_message(image.user.username, image.shortfilename, message)
|
49
|
+
|
50
|
+
# stop processing
|
51
|
+
image.path_to_model = ''
|
52
|
+
image.status = 0
|
53
|
+
image.pid = 0
|
54
|
+
image.save()
|
55
|
+
|
56
|
+
def create_pid_object(pid, remote=False, queue=None, img_id=None, path_to_model=''):
|
57
|
+
|
58
|
+
# remote server
|
59
|
+
if remote:
|
60
|
+
with open(BASE_DIR + f'/log/pid_{queue}', 'w') as pidfile:
|
61
|
+
print(pid, file=pidfile)
|
62
|
+
|
63
|
+
# local server
|
64
|
+
else:
|
65
|
+
import django
|
66
|
+
django.setup()
|
67
|
+
from biomedisa_app.models import Upload
|
68
|
+
image = Upload.objects.get(pk=img_id)
|
69
|
+
image.path_to_model = path_to_model
|
70
|
+
image.pid = pid
|
71
|
+
image.save()
|
72
|
+
|
73
|
+
def post_processing(path_to_final, time_str, server_name, remote, queue, dice=1.0, path_to_model=None, path_to_uq=None, path_to_smooth=None, path_to_cropped_image=None, uncertainty=False, smooth=False, img_id=None, label_id=None, train=False, predict=False, validation=False):
|
74
|
+
|
75
|
+
# remote server
|
76
|
+
if remote:
|
77
|
+
with open(BASE_DIR + f'/log/config_{queue}', 'w') as configfile:
|
78
|
+
print(path_to_final, path_to_uq, path_to_smooth, uncertainty, smooth, str(time_str).replace(' ','-'), server_name, path_to_model, path_to_cropped_image, dice, file=configfile)
|
79
|
+
|
80
|
+
# local server
|
81
|
+
else:
|
82
|
+
import django
|
83
|
+
django.setup()
|
84
|
+
from biomedisa_app.models import Upload
|
85
|
+
from biomedisa_app.views import send_notification
|
86
|
+
from biomedisa_features.active_contour import init_active_contour
|
87
|
+
from biomedisa_features.remove_outlier import init_remove_outlier
|
88
|
+
from biomedisa_features.create_slices import create_slices
|
89
|
+
from redis import Redis
|
90
|
+
from rq import Queue
|
91
|
+
|
92
|
+
# get object
|
93
|
+
image = Upload.objects.get(pk=img_id)
|
94
|
+
|
95
|
+
if train:
|
96
|
+
# create model object
|
97
|
+
shortfilename = os.path.basename(path_to_model)
|
98
|
+
filename = 'images/' + image.user.username + '/' + shortfilename
|
99
|
+
Upload.objects.create(pic=filename, user=image.user, project=image.project, imageType=4, shortfilename=shortfilename)
|
100
|
+
|
101
|
+
if validation:
|
102
|
+
# create acc object
|
103
|
+
shortfilename = os.path.basename(path_to_model.replace('.h5','_acc.png'))
|
104
|
+
filename = 'images/' + image.user.username + '/' + shortfilename
|
105
|
+
Upload.objects.create(pic=filename, user=image.user, project=image.project, imageType=6, shortfilename=shortfilename)
|
106
|
+
|
107
|
+
# create loss object
|
108
|
+
shortfilename = os.path.basename(path_to_model.replace('.h5','_loss.png'))
|
109
|
+
filename = 'images/' + image.user.username + '/' + shortfilename
|
110
|
+
Upload.objects.create(pic=filename, user=image.user, project=image.project, imageType=6, shortfilename=shortfilename)
|
111
|
+
|
112
|
+
else:
|
113
|
+
# create final objects
|
114
|
+
shortfilename = os.path.basename(path_to_final)
|
115
|
+
filename = 'images/' + image.user.username + '/' + shortfilename
|
116
|
+
final = Upload.objects.create(pic=filename, user=image.user, project=image.project, final=1, active=1, imageType=3, shortfilename=shortfilename)
|
117
|
+
final.friend = final.id
|
118
|
+
final.save()
|
119
|
+
|
120
|
+
if path_to_cropped_image:
|
121
|
+
shortfilename = os.path.basename(path_to_cropped_image)
|
122
|
+
filename = 'images/' + image.user.username + '/' + shortfilename
|
123
|
+
Upload.objects.create(pic=filename, user=image.user, project=image.project, final=9, active=0, imageType=3, shortfilename=shortfilename, friend=final.id)
|
124
|
+
|
125
|
+
if uncertainty:
|
126
|
+
shortfilename = os.path.basename(path_to_uq)
|
127
|
+
filename = 'images/' + image.user.username + '/' + shortfilename
|
128
|
+
uncertainty_obj = Upload.objects.create(pic=filename, user=image.user, project=image.project, final=4, imageType=3, shortfilename=shortfilename, friend=final.id)
|
129
|
+
|
130
|
+
if smooth:
|
131
|
+
shortfilename = os.path.basename(path_to_smooth)
|
132
|
+
filename = 'images/' + image.user.username + '/' + shortfilename
|
133
|
+
smooth_obj = Upload.objects.create(pic=filename, user=image.user, project=image.project, final=5, imageType=3, shortfilename=shortfilename, friend=final.id)
|
134
|
+
|
135
|
+
# create allaxes warning
|
136
|
+
if dice < 0.3:
|
137
|
+
Upload.objects.create(user=image.user, project=image.project,
|
138
|
+
log=1, imageType=None, shortfilename='Bad result! Activate "All axes" if you labeled axes other than the xy-plane.')
|
139
|
+
|
140
|
+
# acwe
|
141
|
+
if not (os.path.splitext(path_to_final)[1]=='.tar' or path_to_final[-7:]=='.tar.gz'):
|
142
|
+
q = Queue('acwe', connection=Redis())
|
143
|
+
job = q.enqueue_call(init_active_contour, args=(img_id, final.id, label_id, True,), timeout=-1)
|
144
|
+
job = q.enqueue_call(init_active_contour, args=(img_id, final.id, label_id,), timeout=-1)
|
145
|
+
|
146
|
+
# cleanup
|
147
|
+
if not (os.path.splitext(path_to_final)[1]=='.tar' or path_to_final[-7:]=='.tar.gz'):
|
148
|
+
q = Queue('cleanup', connection=Redis())
|
149
|
+
job = q.enqueue_call(init_remove_outlier, args=(img_id, final.id, label_id,), timeout=-1)
|
150
|
+
if smooth:
|
151
|
+
job = q.enqueue_call(init_remove_outlier, args=(img_id, smooth_obj.id, label_id, False,), timeout=-1)
|
152
|
+
|
153
|
+
# create slices
|
154
|
+
q = Queue('slices', connection=Redis())
|
155
|
+
job = q.enqueue_call(create_slices, args=(image.pic.path, final.pic.path,), timeout=-1)
|
156
|
+
if path_to_cropped_image:
|
157
|
+
q = Queue('slices', connection=Redis())
|
158
|
+
job = q.enqueue_call(create_slices, args=(path_to_cropped_image, None,), timeout=-1)
|
159
|
+
if smooth:
|
160
|
+
job = q.enqueue_call(create_slices, args=(image.pic.path, smooth_obj.pic.path,), timeout=-1)
|
161
|
+
if uncertainty:
|
162
|
+
job = q.enqueue_call(create_slices, args=(uncertainty_obj.pic.path, None,), timeout=-1)
|
163
|
+
|
164
|
+
# send notification
|
165
|
+
send_notification(image.user.username, image.shortfilename, time_str, server_name, train, predict)
|
166
|
+
|
167
|
+
# stop processing
|
168
|
+
image.path_to_model = ''
|
169
|
+
image.status = 0
|
170
|
+
image.pid = 0
|
171
|
+
image.save()
|
172
|
+
|