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,72 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
import sys
|
5
|
+
import re
|
6
|
+
|
7
|
+
import numpy as np
|
8
|
+
|
9
|
+
from .amira_header import AmiraHeader
|
10
|
+
from .amira_data_stream import DataStreams, write_amira
|
11
|
+
|
12
|
+
class AmiraFile(object):
|
13
|
+
"""Convenience class to handle Amira files
|
14
|
+
|
15
|
+
This class aggregates user-level classes from the :py:mod:`ahds.header` and :py:mod:`ahds.data_stream` modules
|
16
|
+
into a single class with a simple interface :py:meth:`AmiraFile.header` for the header and :py:attr:`AmiraFile.data_streams`
|
17
|
+
data streams attribute.
|
18
|
+
"""
|
19
|
+
def __init__(self, fn, *args, **kwargs):
|
20
|
+
self._fn = fn
|
21
|
+
if fn is not None:
|
22
|
+
self._header = AmiraHeader.from_file(self._fn, *args, **kwargs)
|
23
|
+
else:
|
24
|
+
self._header = None
|
25
|
+
self._data_streams = None # only populate on call to read() method
|
26
|
+
|
27
|
+
@property
|
28
|
+
def header(self):
|
29
|
+
return self._header
|
30
|
+
|
31
|
+
@property
|
32
|
+
def data_streams(self):
|
33
|
+
return self._data_streams
|
34
|
+
|
35
|
+
def read(self, *args, **kwargs):
|
36
|
+
self._data_streams = DataStreams(self._fn, self._header, *args, **kwargs)
|
37
|
+
|
38
|
+
#-------------------------------------------------------------------------------
|
39
|
+
# reads amira file and returns
|
40
|
+
# - data as list of ndarray
|
41
|
+
# - header as ndarray from byte array
|
42
|
+
#
|
43
|
+
# raises ValueError for error
|
44
|
+
def amira_to_np(fname):
|
45
|
+
try:
|
46
|
+
af = AmiraFile(fname)
|
47
|
+
raw_header = af.header.raw_header # raw_header is byte array
|
48
|
+
raw_header = np.frombuffer(raw_header, dtype=np.dtype('b')) # return as ndarray
|
49
|
+
|
50
|
+
af.read()
|
51
|
+
num_streams = len(af.data_streams)
|
52
|
+
data = []
|
53
|
+
for i in range(num_streams):
|
54
|
+
data.append(af.data_streams[i+1].to_volume())
|
55
|
+
except Exception as e:
|
56
|
+
raise ValueError("amira_to_np: parsing error or amira file not supported. info: %s" % str(e))
|
57
|
+
|
58
|
+
return data, raw_header
|
59
|
+
|
60
|
+
# writes amira file from
|
61
|
+
# - output amira filename
|
62
|
+
# - data as list of ndarray
|
63
|
+
# - header as ndarray
|
64
|
+
#
|
65
|
+
# raises ValueError for error
|
66
|
+
def np_to_amira(fname, data, header):
|
67
|
+
try:
|
68
|
+
write_amira(fname, header, data)
|
69
|
+
except Exception as e:
|
70
|
+
raise ValueError("np_to_amira: parsing error or am file not supported. info: %s" % str(e))
|
71
|
+
|
72
|
+
return 0
|
@@ -0,0 +1,167 @@
|
|
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
|
+
import pycuda.driver as cuda
|
32
|
+
import pycuda.autoinit
|
33
|
+
import pycuda.gpuarray as gpuarray
|
34
|
+
from pycuda.compiler import SourceModule
|
35
|
+
|
36
|
+
def min_distances(a, b, xsh, ysh):
|
37
|
+
|
38
|
+
code = """
|
39
|
+
__global__ void Funktion(int *a, int *b, int *distance, int a_shape, int b_shape, int xsh, int ysh) {
|
40
|
+
|
41
|
+
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
42
|
+
|
43
|
+
if (index < a_shape) {
|
44
|
+
|
45
|
+
int i = a[index];
|
46
|
+
int z_a = i / (xsh * ysh);
|
47
|
+
int y_a = (i % (xsh * ysh)) / xsh;
|
48
|
+
int x_a = (i % (xsh * ysh)) % xsh;
|
49
|
+
|
50
|
+
i = b[0];
|
51
|
+
int z_b = i / (xsh * ysh);
|
52
|
+
int y_b = (i % (xsh * ysh)) / xsh;
|
53
|
+
int x_b = (i % (xsh * ysh)) % xsh;
|
54
|
+
|
55
|
+
int min_dist = (z_b - z_a)*(z_b - z_a) + (y_b - y_a)*(y_b - y_a) + (x_b - x_a)*(x_b - x_a);
|
56
|
+
|
57
|
+
for (int k = 1; k < b_shape; k++) {
|
58
|
+
|
59
|
+
i = b[k];
|
60
|
+
z_b = i / (xsh * ysh);
|
61
|
+
y_b = (i % (xsh * ysh)) / xsh;
|
62
|
+
x_b = (i % (xsh * ysh)) % xsh;
|
63
|
+
|
64
|
+
int tmp = (z_b - z_a)*(z_b - z_a) + (y_b - y_a)*(y_b - y_a) + (x_b - x_a)*(x_b - x_a);
|
65
|
+
if (tmp < min_dist) {
|
66
|
+
min_dist = tmp;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
distance[index] = min_dist;
|
71
|
+
|
72
|
+
}
|
73
|
+
}
|
74
|
+
"""
|
75
|
+
mod = SourceModule(code)
|
76
|
+
func = mod.get_function("Funktion")
|
77
|
+
|
78
|
+
x_grid = (a.size // 256) + 1
|
79
|
+
|
80
|
+
a_gpu = gpuarray.to_gpu(a.astype(np.int32))
|
81
|
+
b_gpu = gpuarray.to_gpu(b.astype(np.int32))
|
82
|
+
|
83
|
+
distance_gpu = gpuarray.zeros(a.size, dtype=np.int32)
|
84
|
+
|
85
|
+
a_shape_gpu = np.int32(a.size)
|
86
|
+
b_shape_gpu = np.int32(b.size)
|
87
|
+
|
88
|
+
xsh_gpu = np.int32(xsh)
|
89
|
+
ysh_gpu = np.int32(ysh)
|
90
|
+
|
91
|
+
func(a_gpu, b_gpu, distance_gpu, a_shape_gpu, b_shape_gpu, xsh_gpu, ysh_gpu, block = (256,1,1), grid = (x_grid,1,1))
|
92
|
+
|
93
|
+
return distance_gpu.get()
|
94
|
+
|
95
|
+
@numba.jit(nopython=True)
|
96
|
+
def nonzero(a, indices, zsh, ysh, xsh):
|
97
|
+
s = 0
|
98
|
+
for k in range(zsh):
|
99
|
+
for l in range(ysh):
|
100
|
+
for m in range(xsh):
|
101
|
+
if a[k,l,m] == 1:
|
102
|
+
indices[s] = k*ysh*xsh + l*xsh + m
|
103
|
+
s += 1
|
104
|
+
return indices
|
105
|
+
|
106
|
+
def ASSD_one_label(a, b, label):
|
107
|
+
|
108
|
+
# consider label of interest only
|
109
|
+
tmp = np.zeros_like(a)
|
110
|
+
tmp[a==label] = 1
|
111
|
+
a = np.copy(tmp, order='C')
|
112
|
+
tmp = np.zeros_like(b)
|
113
|
+
tmp[b==label] = 1
|
114
|
+
b = np.copy(tmp, order='C')
|
115
|
+
|
116
|
+
# get gradients
|
117
|
+
zsh, ysh, xsh = a.shape
|
118
|
+
a_gradient = np.sum(np.abs(np.gradient(a)), axis=0)
|
119
|
+
b_gradient = np.sum(np.abs(np.gradient(b)), axis=0)
|
120
|
+
a_gradient = a_gradient.astype(np.float32)
|
121
|
+
b_gradient = b_gradient.astype(np.float32)
|
122
|
+
|
123
|
+
# get surfaces
|
124
|
+
a_surface = np.zeros_like(a)
|
125
|
+
b_surface = np.zeros_like(b)
|
126
|
+
a_surface[np.logical_and(a_gradient>0, a>0)] = 1
|
127
|
+
b_surface[np.logical_and(b_gradient>0, b>0)] = 1
|
128
|
+
|
129
|
+
# size of surfaces
|
130
|
+
a_size = np.sum(a_surface)
|
131
|
+
b_size = np.sum(b_surface)
|
132
|
+
|
133
|
+
# min distances from a_to_b
|
134
|
+
a_save = np.copy(a_surface, order='C')
|
135
|
+
a_surface[b_surface==1] = 0
|
136
|
+
a_surface = np.copy(a_surface, order='C')
|
137
|
+
b_surface = np.copy(b_surface, order='C')
|
138
|
+
if np.sum(a_surface) == 0:
|
139
|
+
distances_a_to_b = 0
|
140
|
+
else:
|
141
|
+
#a_indices = np.nonzero(a_surface.flatten())[0]
|
142
|
+
#b_indices = np.nonzero(b_surface.flatten())[0]
|
143
|
+
a_indices = nonzero(a_surface, np.zeros(np.sum(a_surface), dtype=np.int32), zsh, ysh, xsh)
|
144
|
+
b_indices = nonzero(b_surface, np.zeros(np.sum(b_surface), dtype=np.int32), zsh, ysh, xsh)
|
145
|
+
distances_a_to_b = min_distances(a_indices, b_indices, xsh, ysh)
|
146
|
+
distances_a_to_b = np.sqrt(distances_a_to_b)
|
147
|
+
|
148
|
+
# min distances from b_to_a
|
149
|
+
b_surface[a_save==1] = 0
|
150
|
+
a_surface = np.copy(a_save, order='C')
|
151
|
+
b_surface = np.copy(b_surface, order='C')
|
152
|
+
if np.sum(b_surface) == 0:
|
153
|
+
distances_b_to_a = 0
|
154
|
+
else:
|
155
|
+
#a_indices = np.nonzero(a_save.flatten())[0]
|
156
|
+
#b_indices = np.nonzero(b_surface.flatten())[0]
|
157
|
+
a_indices = nonzero(a_surface, np.zeros(np.sum(a_surface), dtype=np.int32), zsh, ysh, xsh)
|
158
|
+
b_indices = nonzero(b_surface, np.zeros(np.sum(b_surface), dtype=np.int32), zsh, ysh, xsh)
|
159
|
+
distances_b_to_a = min_distances(b_indices, a_indices, xsh, ysh)
|
160
|
+
distances_b_to_a = np.sqrt(distances_b_to_a)
|
161
|
+
|
162
|
+
# hausdorff
|
163
|
+
hausdorff = max(np.amax(distances_a_to_b), np.amax(distances_b_to_a))
|
164
|
+
|
165
|
+
# return distances
|
166
|
+
return np.sum(distances_a_to_b) + np.sum(distances_b_to_a), a_size + b_size, hausdorff
|
167
|
+
|