neuro-sam 0.1.11__py3-none-any.whl → 0.1.13__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.
- neuro_sam/brightest_path_lib/visualization/tube_data.py +4 -4
- neuro_sam/napari_utils/main_widget.py +5 -2
- neuro_sam/napari_utils/segmentation_module.py +1 -99
- {neuro_sam-0.1.11.dist-info → neuro_sam-0.1.13.dist-info}/METADATA +1 -1
- {neuro_sam-0.1.11.dist-info → neuro_sam-0.1.13.dist-info}/RECORD +9 -9
- {neuro_sam-0.1.11.dist-info → neuro_sam-0.1.13.dist-info}/WHEEL +0 -0
- {neuro_sam-0.1.11.dist-info → neuro_sam-0.1.13.dist-info}/entry_points.txt +0 -0
- {neuro_sam-0.1.11.dist-info → neuro_sam-0.1.13.dist-info}/licenses/LICENSE +0 -0
- {neuro_sam-0.1.11.dist-info → neuro_sam-0.1.13.dist-info}/top_level.txt +0 -0
|
@@ -7,13 +7,13 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
7
7
|
from neuro_sam.brightest_path_lib.algorithm.waypointastar_speedup import quick_accurate_optimized_search
|
|
8
8
|
|
|
9
9
|
# Numba-optimized core functions
|
|
10
|
-
@nb.njit(cache=True
|
|
10
|
+
@nb.njit(cache=True)
|
|
11
11
|
def compute_tangent_vectors_fast(path_array):
|
|
12
12
|
"""Fast computation of tangent vectors using numba"""
|
|
13
13
|
n_points = path_array.shape[0]
|
|
14
14
|
tangents = np.zeros_like(path_array, dtype=np.float64)
|
|
15
15
|
|
|
16
|
-
for i in
|
|
16
|
+
for i in range(n_points):
|
|
17
17
|
if i == 0:
|
|
18
18
|
if n_points > 1:
|
|
19
19
|
tangent = path_array[1] - path_array[0]
|
|
@@ -84,13 +84,13 @@ def create_orthogonal_basis_fast(forward):
|
|
|
84
84
|
|
|
85
85
|
return up, right
|
|
86
86
|
|
|
87
|
-
@nb.njit(cache=True
|
|
87
|
+
@nb.njit(cache=True)
|
|
88
88
|
def sample_viewing_plane_fast(image, current_point, up, right, plane_size):
|
|
89
89
|
"""Fast viewing plane sampling with bounds checking"""
|
|
90
90
|
plane_shape = (plane_size * 2 + 1, plane_size * 2 + 1)
|
|
91
91
|
normal_plane = np.zeros(plane_shape, dtype=np.float64)
|
|
92
92
|
|
|
93
|
-
for i in
|
|
93
|
+
for i in range(plane_shape[0]):
|
|
94
94
|
for j in range(plane_shape[1]):
|
|
95
95
|
# Calculate 3D point
|
|
96
96
|
point_3d = (current_point +
|
|
@@ -971,10 +971,13 @@ class NeuroSAMWidget(QWidget):
|
|
|
971
971
|
layer = self.viewer.add_image(
|
|
972
972
|
final_stack,
|
|
973
973
|
name=layer_name,
|
|
974
|
-
colormap='gray'
|
|
975
|
-
interpolation='nearest'
|
|
974
|
+
colormap='gray'
|
|
976
975
|
)
|
|
977
976
|
|
|
977
|
+
# Set interpolation
|
|
978
|
+
layer.interpolation2d = 'nearest'
|
|
979
|
+
layer.interpolation3d = 'nearest'
|
|
980
|
+
|
|
978
981
|
# Force 2D view
|
|
979
982
|
self.viewer.dims.ndisplay = 2
|
|
980
983
|
|
|
@@ -13,61 +13,6 @@ from scipy import ndimage
|
|
|
13
13
|
from scipy.ndimage import binary_fill_holes
|
|
14
14
|
from skimage.morphology import disk, binary_closing, remove_small_objects
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
def fast_refine_dendrite_boundaries(image, dendrite_mask):
|
|
18
|
-
"""
|
|
19
|
-
Fast, lightweight boundary refinement for dendrites
|
|
20
|
-
Only basic morphological operations - no gradients
|
|
21
|
-
"""
|
|
22
|
-
if not np.any(dendrite_mask):
|
|
23
|
-
return dendrite_mask
|
|
24
|
-
|
|
25
|
-
# Simple morphological cleanup only
|
|
26
|
-
# Fill holes in dendrites (should be solid tubes)
|
|
27
|
-
filled_mask = binary_fill_holes(dendrite_mask)
|
|
28
|
-
|
|
29
|
-
# Light closing to connect nearby segments
|
|
30
|
-
closed_mask = binary_closing(filled_mask, disk(2))
|
|
31
|
-
|
|
32
|
-
# Remove very small objects
|
|
33
|
-
labeled_mask, num_labels = ndimage.label(closed_mask)
|
|
34
|
-
cleaned_mask = closed_mask.copy()
|
|
35
|
-
|
|
36
|
-
for label_id in range(1, num_labels + 1):
|
|
37
|
-
component = (labeled_mask == label_id)
|
|
38
|
-
if np.sum(component) < 20: # Small threshold for dendrites
|
|
39
|
-
cleaned_mask[component] = 0
|
|
40
|
-
|
|
41
|
-
return cleaned_mask.astype(np.uint8)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def fast_refine_dendrite_volume_boundaries(image_volume, mask_volume, brightest_path):
|
|
45
|
-
"""
|
|
46
|
-
Fast dendrite boundary refinement - only process frames that have dendrite path
|
|
47
|
-
"""
|
|
48
|
-
refined_volume = mask_volume.copy()
|
|
49
|
-
|
|
50
|
-
# Only process frames that have dendrite path
|
|
51
|
-
path_frames = set()
|
|
52
|
-
for point in brightest_path:
|
|
53
|
-
path_frames.add(int(point[0]))
|
|
54
|
-
|
|
55
|
-
print(f"Fast dendrite light cleanup on {len(path_frames)} frames with dendrite...")
|
|
56
|
-
|
|
57
|
-
for z in path_frames:
|
|
58
|
-
if 0 <= z < image_volume.shape[0] and np.any(mask_volume[z]):
|
|
59
|
-
refined_volume[z] = fast_refine_dendrite_boundaries(image_volume[z], mask_volume[z])
|
|
60
|
-
|
|
61
|
-
# Report changes
|
|
62
|
-
original_pixels = np.sum(mask_volume > 0)
|
|
63
|
-
refined_pixels = np.sum(refined_volume > 0)
|
|
64
|
-
change = refined_pixels - original_pixels
|
|
65
|
-
|
|
66
|
-
print(f"Dendrite light cleanup: {original_pixels} -> {refined_pixels} pixels ({change:+d}, {change/original_pixels*100:+.1f}%)")
|
|
67
|
-
|
|
68
|
-
return refined_volume.astype(np.uint8)
|
|
69
|
-
|
|
70
|
-
|
|
71
16
|
class SegmentationWidget(QWidget):
|
|
72
17
|
"""Widget for performing dendrite segmentation with boundary smoothing"""
|
|
73
18
|
|
|
@@ -171,34 +116,6 @@ class SegmentationWidget(QWidget):
|
|
|
171
116
|
self.patch_size_spin.setToolTip("Size of overlapping patches (128x128 recommended)")
|
|
172
117
|
patch_size_layout.addWidget(self.patch_size_spin)
|
|
173
118
|
params_layout.addLayout(patch_size_layout)
|
|
174
|
-
|
|
175
|
-
# Enable boundary cleanup for dendrites
|
|
176
|
-
self.enable_boundary_smoothing_cb = QCheckBox("Enable Light Boundary Cleanup")
|
|
177
|
-
self.enable_boundary_smoothing_cb.setChecked(False) # Disabled by default for speed
|
|
178
|
-
self.enable_boundary_smoothing_cb.setToolTip("Apply light morphological cleanup (hole filling, small object removal)")
|
|
179
|
-
params_layout.addWidget(self.enable_boundary_smoothing_cb)
|
|
180
|
-
|
|
181
|
-
# # Minimum dendrite size for noise removal
|
|
182
|
-
# min_size_layout = QHBoxLayout()
|
|
183
|
-
# min_size_layout.addWidget(QLabel("Min Dendrite Size (pixels):"))
|
|
184
|
-
# self.min_dendrite_size_spin = QSpinBox()
|
|
185
|
-
# self.min_dendrite_size_spin.setRange(50, 500)
|
|
186
|
-
# self.min_dendrite_size_spin.setValue(100)
|
|
187
|
-
# self.min_dendrite_size_spin.setToolTip("Minimum size of dendrite objects to keep (removes noise)")
|
|
188
|
-
# min_size_layout.addWidget(self.min_dendrite_size_spin)
|
|
189
|
-
# params_layout.addLayout(min_size_layout)
|
|
190
|
-
|
|
191
|
-
# Frame range
|
|
192
|
-
# self.use_full_volume_cb = QCheckBox("Process Full Volume")
|
|
193
|
-
# self.use_full_volume_cb.setChecked(False)
|
|
194
|
-
# self.use_full_volume_cb.setToolTip("Process entire volume instead of just path range")
|
|
195
|
-
# params_layout.addWidget(self.use_full_volume_cb)
|
|
196
|
-
|
|
197
|
-
# Processing method info
|
|
198
|
-
# method_info = QLabel("Method: 50% overlapping patches + optional light cleanup")
|
|
199
|
-
# method_info.setWordWrap(True)
|
|
200
|
-
# method_info.setStyleSheet("color: #0066cc; font-style: italic;")
|
|
201
|
-
# params_layout.addWidget(method_info)
|
|
202
119
|
|
|
203
120
|
params_section.setLayout(params_layout)
|
|
204
121
|
layout.addWidget(params_section)
|
|
@@ -395,8 +312,6 @@ class SegmentationWidget(QWidget):
|
|
|
395
312
|
path_data = self.state['paths'][path_id]
|
|
396
313
|
path_name = path_data['name']
|
|
397
314
|
brightest_path = path_data['data']
|
|
398
|
-
|
|
399
|
-
enable_boundary_smoothing = self.enable_boundary_smoothing_cb.isChecked()
|
|
400
315
|
|
|
401
316
|
# Get segmentation parameters
|
|
402
317
|
patch_size = self.patch_size_spin.value()
|
|
@@ -423,10 +338,7 @@ class SegmentationWidget(QWidget):
|
|
|
423
338
|
|
|
424
339
|
# Progress callback function
|
|
425
340
|
def update_progress(current, total):
|
|
426
|
-
|
|
427
|
-
progress = int((current / total) * 80) # 0-80%
|
|
428
|
-
else:
|
|
429
|
-
progress = int((current / total) * 90) # 0-90%
|
|
341
|
+
progress = int((current / total) * 90) # 0-90%
|
|
430
342
|
self.segmentation_progress.setValue(progress)
|
|
431
343
|
|
|
432
344
|
# Try to run the segmentation with overlapping patches
|
|
@@ -439,16 +351,6 @@ class SegmentationWidget(QWidget):
|
|
|
439
351
|
progress_callback=update_progress
|
|
440
352
|
)
|
|
441
353
|
|
|
442
|
-
# Apply light boundary cleanup if requested
|
|
443
|
-
if enable_boundary_smoothing and result_masks is not None:
|
|
444
|
-
self.segmentation_progress.setValue(80)
|
|
445
|
-
print("Applying light dendrite boundary cleanup...")
|
|
446
|
-
napari.utils.notifications.show_info("Light dendrite cleanup...")
|
|
447
|
-
|
|
448
|
-
refined_masks = fast_refine_dendrite_volume_boundaries(self.image, result_masks, brightest_path)
|
|
449
|
-
result_masks = refined_masks
|
|
450
|
-
self.segmentation_progress.setValue(90)
|
|
451
|
-
|
|
452
354
|
# Process the results
|
|
453
355
|
if result_masks is not None:
|
|
454
356
|
# Ensure masks are binary (0 or 1)
|
|
@@ -24,16 +24,16 @@ neuro_sam/brightest_path_lib/node/node.py,sha256=Pfq8Swm3XWu6gErJlXzN7JyJ9J4bFsv
|
|
|
24
24
|
neuro_sam/brightest_path_lib/visualization/__init__.py,sha256=WZ1QT3JqhHquh3dxwXKeQ5vmfuBj70sNI0_JBzrNKNY,195
|
|
25
25
|
neuro_sam/brightest_path_lib/visualization/flythrough.py,sha256=bs-rqgwEXUZOYUkN6FOZAl2FkcRus7Ma1jWtZ1VRA1Q,5087
|
|
26
26
|
neuro_sam/brightest_path_lib/visualization/flythrough_all.py,sha256=3MIYTl2q3oVszuaLOl-QS4zQISsCk1JlVcURCtc-pw0,17886
|
|
27
|
-
neuro_sam/brightest_path_lib/visualization/tube_data.py,sha256=
|
|
27
|
+
neuro_sam/brightest_path_lib/visualization/tube_data.py,sha256=Ual2g2mzHwGI8GStp2AsrEtiP9MdB8zdYwYFortulV8,15532
|
|
28
28
|
neuro_sam/brightest_path_lib/visualization/tube_flythrough.py,sha256=Lt5sLqvj20AiiXl8SXlt6vQlHXQXtB91-FNFGl-YmU8,9160
|
|
29
29
|
neuro_sam/napari_utils/anisotropic_scaling.py,sha256=VA6Sd9zEhIAhzjAGto2cOjE9mocNx9NFWXec2TQpvew,19266
|
|
30
30
|
neuro_sam/napari_utils/color_utils.py,sha256=Hf5R8f0rh7b9CY1VT72o3tLGfGnnjRREkX8iWsiiu7k,4243
|
|
31
31
|
neuro_sam/napari_utils/contrasting_color_system.py,sha256=a-lt_3zJLDL9YyIdWJhFDGMYzBb6yH85cV7BNCabbdI,6771
|
|
32
|
-
neuro_sam/napari_utils/main_widget.py,sha256=
|
|
32
|
+
neuro_sam/napari_utils/main_widget.py,sha256=VIsVkJ28NXyFoc97xI7d3Ykiy61nyBaMbyKHO0z3mx4,48696
|
|
33
33
|
neuro_sam/napari_utils/path_tracing_module.py,sha256=bDhSawWNMfY-Vs-Zdt8XTb90pLkD9jUBRqpbC2_6li0,44070
|
|
34
34
|
neuro_sam/napari_utils/punet_widget.py,sha256=WCAND8YLn4CA_20YW4quwcuJ_xEqPAc7GHrSBk4Anw0,16928
|
|
35
35
|
neuro_sam/napari_utils/segmentation_model.py,sha256=mHXVjksqEcxHRH5KWp5-hXLEnRHgGhwPUxyUkV8eJGM,34141
|
|
36
|
-
neuro_sam/napari_utils/segmentation_module.py,sha256=
|
|
36
|
+
neuro_sam/napari_utils/segmentation_module.py,sha256=t5BjuYnvSHHkt4zaUDQvkiCOnaYEFi6pDgtCIeMdGY0,23136
|
|
37
37
|
neuro_sam/napari_utils/visualization_module.py,sha256=JtZlBoKlfIwVLa2Sqg7b2KTr07fNlAcwR0M7fHsn2oM,24723
|
|
38
38
|
neuro_sam/punet/deepd3_model.py,sha256=nGVEqzCPz_E4cFA6QmknW2CffDcjxH7VsdYAyTdAtY0,7509
|
|
39
39
|
neuro_sam/punet/prob_unet_deepd3.py,sha256=syXNleUVrfYtmVveN9G461oAhumxsijsavps8in4VRw,14698
|
|
@@ -47,7 +47,7 @@ neuro_sam/training/train_dendrites.py,sha256=TMG4YrrQV0Q784omMziXsB71tNICEmGLYSH
|
|
|
47
47
|
neuro_sam/training/utils/__init__.py,sha256=4hbcx57NtRu8nryvXQYqmXK4hyUgUYNDz97kCw3Efs8,31
|
|
48
48
|
neuro_sam/training/utils/prompt_generation_dendrites.py,sha256=_ntzXNV1lXPrpInRKaZ5CPpq3akF2IuD1naOXbTC8TU,3201
|
|
49
49
|
neuro_sam/training/utils/stream_dendrites.py,sha256=qS_ZWrhJdW1Sg3RBjoRUJFlCV0u5X1Ns_tjYgJUjWJw,11024
|
|
50
|
-
neuro_sam-0.1.
|
|
50
|
+
neuro_sam-0.1.13.dist-info/licenses/LICENSE,sha256=akmTIN8IuZn3Y7UK_8qVQnyKDWSDcVUwB8RPGNXCojw,1068
|
|
51
51
|
sam2/__init__.py,sha256=uHyh6VzVS4F2box0rPDpN5UmOVKeQNK0CIaTKG9JQZ4,395
|
|
52
52
|
sam2/automatic_mask_generator.py,sha256=Zt8mbb4UQSMFrjOY8OwbshswOpMhaxAtdn5sTuXUw9c,18461
|
|
53
53
|
sam2/benchmark.py,sha256=m3o1BriIQuwJAx-3zQ_B0_7YLhN84G28oQSV5sGA3ak,2811
|
|
@@ -91,8 +91,8 @@ sam2/utils/__init__.py,sha256=NL2AacVHZOe41zp4kF2-ZGcUCi9zFwh1Eo9spNjN0Ko,197
|
|
|
91
91
|
sam2/utils/amg.py,sha256=t7MwkOKvcuBNu4FcjzKv9BpO0av5Zo9itZ8b3WQMpdg,12842
|
|
92
92
|
sam2/utils/misc.py,sha256=AWAMAcFhzQedcQb7HU2oRc-RqjGrK87K-MsVG21tIKI,13090
|
|
93
93
|
sam2/utils/transforms.py,sha256=ujpk9GAMYvIJIGpt87QOP88TPtrjL61liDG7DCptEUY,4885
|
|
94
|
-
neuro_sam-0.1.
|
|
95
|
-
neuro_sam-0.1.
|
|
96
|
-
neuro_sam-0.1.
|
|
97
|
-
neuro_sam-0.1.
|
|
98
|
-
neuro_sam-0.1.
|
|
94
|
+
neuro_sam-0.1.13.dist-info/METADATA,sha256=eMqJUJUL6Kur_2m4wQfR8fUiED-JIGVh18tgE57APb8,9747
|
|
95
|
+
neuro_sam-0.1.13.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
96
|
+
neuro_sam-0.1.13.dist-info/entry_points.txt,sha256=EQg0SmFbnbGGcchHq5ROmhO9pkgby72Y5G5w90WyLZI,220
|
|
97
|
+
neuro_sam-0.1.13.dist-info/top_level.txt,sha256=yPbWxFcw79sErTk8zohihUHMK9LL31i3bXir2MrS4OQ,15
|
|
98
|
+
neuro_sam-0.1.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|