nettracer3d 0.9.6__py3-none-any.whl → 0.9.8__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.
Potentially problematic release.
This version of nettracer3d might be problematic. Click here for more details.
- nettracer3d/nettracer_gui.py +17 -21
- nettracer3d/segmenter.py +12 -121
- nettracer3d/segmenter_GPU.py +12 -9
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.8.dist-info}/METADATA +3 -7
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.8.dist-info}/RECORD +9 -9
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.8.dist-info}/WHEEL +0 -0
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.8.dist-info}/entry_points.txt +0 -0
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.8.dist-info}/licenses/LICENSE +0 -0
- {nettracer3d-0.9.6.dist-info → nettracer3d-0.9.8.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -109,7 +109,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
109
109
|
self.color_dictionary['LIGHT_RED'], # Lighter red
|
|
110
110
|
self.color_dictionary['LIGHT_GREEN'], # Lighter green
|
|
111
111
|
self.color_dictionary['WHITE'], # White
|
|
112
|
-
self.color_dictionary['
|
|
112
|
+
self.color_dictionary['CYAN'] # Now cyan
|
|
113
113
|
]
|
|
114
114
|
|
|
115
115
|
|
|
@@ -2494,6 +2494,12 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2494
2494
|
|
|
2495
2495
|
self.update_display(preserve_zoom=(current_xlim, current_ylim))
|
|
2496
2496
|
|
|
2497
|
+
if self.pan_mode:
|
|
2498
|
+
self.create_pan_background()
|
|
2499
|
+
current_xlim = self.ax.get_xlim()
|
|
2500
|
+
current_ylim = self.ax.get_ylim()
|
|
2501
|
+
self.update_display_pan_mode(current_xlim, current_ylim)
|
|
2502
|
+
|
|
2497
2503
|
|
|
2498
2504
|
def toggle_zoom_mode(self):
|
|
2499
2505
|
"""Toggle zoom mode on/off."""
|
|
@@ -2501,7 +2507,9 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2501
2507
|
|
|
2502
2508
|
if self.zoom_mode:
|
|
2503
2509
|
if self.pan_mode:
|
|
2504
|
-
self.
|
|
2510
|
+
self.update_display(preserve_zoom=(self.ax.get_xlim(), self.ax.get_ylim()))
|
|
2511
|
+
self.pan_mode = False
|
|
2512
|
+
self.pan_button.setChecked(False)
|
|
2505
2513
|
|
|
2506
2514
|
self.pen_button.setChecked(False)
|
|
2507
2515
|
self.brush_mode = False
|
|
@@ -2522,11 +2530,6 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2522
2530
|
current_xlim = self.ax.get_xlim()
|
|
2523
2531
|
current_ylim = self.ax.get_ylim()
|
|
2524
2532
|
self.update_display(preserve_zoom=(current_xlim, current_ylim))
|
|
2525
|
-
if self.pan_mode:
|
|
2526
|
-
current_xlim = self.ax.get_xlim()
|
|
2527
|
-
current_ylim = self.ax.get_ylim()
|
|
2528
|
-
self.update_display(preserve_zoom=(current_xlim, current_ylim))
|
|
2529
|
-
self.pan_mode = False
|
|
2530
2533
|
|
|
2531
2534
|
else:
|
|
2532
2535
|
if self.machine_window is None:
|
|
@@ -2605,7 +2608,9 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2605
2608
|
if self.brush_mode:
|
|
2606
2609
|
|
|
2607
2610
|
if self.pan_mode:
|
|
2608
|
-
self.
|
|
2611
|
+
self.update_display(preserve_zoom=(self.ax.get_xlim(), self.ax.get_ylim()))
|
|
2612
|
+
self.pan_mode = False
|
|
2613
|
+
self.pan_button.setChecked(False)
|
|
2609
2614
|
|
|
2610
2615
|
self.pm = painting.PaintManager(parent = self)
|
|
2611
2616
|
|
|
@@ -3594,8 +3599,8 @@ class ImageViewerWindow(QMainWindow):
|
|
|
3594
3599
|
# Multi-color highlight for machine window
|
|
3595
3600
|
mask_1 = (highlight_data == 1)
|
|
3596
3601
|
mask_2 = (highlight_data == 2)
|
|
3597
|
-
rgba[mask_1] = [1, 1, 0, 0.
|
|
3598
|
-
rgba[mask_2] = [0, 0.7, 1, 0.
|
|
3602
|
+
rgba[mask_1] = [1, 1, 0, 0.3] # Yellow for 1
|
|
3603
|
+
rgba[mask_2] = [0, 0.7, 1, 0.3] # Blue for 2
|
|
3599
3604
|
|
|
3600
3605
|
return rgba
|
|
3601
3606
|
|
|
@@ -6088,17 +6093,6 @@ class ImageViewerWindow(QMainWindow):
|
|
|
6088
6093
|
pass
|
|
6089
6094
|
self.static_background = None
|
|
6090
6095
|
|
|
6091
|
-
# Your existing machine_window logic
|
|
6092
|
-
if self.machine_window is None:
|
|
6093
|
-
try:
|
|
6094
|
-
self.channel_data[4][self.current_slice, :, :] = n3d.overlay_arrays_simple(
|
|
6095
|
-
self.channel_data[self.temp_chan][self.current_slice, :, :],
|
|
6096
|
-
self.channel_data[4][self.current_slice, :, :])
|
|
6097
|
-
self.load_channel(self.temp_chan, self.channel_data[4], data=True, end_paint=True)
|
|
6098
|
-
self.channel_data[4] = None
|
|
6099
|
-
self.channel_visible[4] = False
|
|
6100
|
-
except:
|
|
6101
|
-
pass
|
|
6102
6096
|
|
|
6103
6097
|
# Get dimensions
|
|
6104
6098
|
active_channels = [i for i in range(4) if self.channel_data[i] is not None]
|
|
@@ -10991,6 +10985,8 @@ class MachineWindow(QMainWindow):
|
|
|
10991
10985
|
def toggle_brush_mode(self):
|
|
10992
10986
|
"""Toggle brush mode on/off"""
|
|
10993
10987
|
self.parent().brush_mode = self.brush_button.isChecked()
|
|
10988
|
+
if self.parent().pan_mode:
|
|
10989
|
+
self.parent().update_display(preserve_zoom=(self.parent().ax.get_xlim(), self.parent().ax.get_ylim()))
|
|
10994
10990
|
|
|
10995
10991
|
if self.parent().brush_mode:
|
|
10996
10992
|
|
nettracer3d/segmenter.py
CHANGED
|
@@ -192,10 +192,10 @@ class InteractiveSegmenter:
|
|
|
192
192
|
if image_2d is None:
|
|
193
193
|
image_2d = self.image_3d[z, :, :]
|
|
194
194
|
|
|
195
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
195
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
196
196
|
# RGB case - process each channel
|
|
197
197
|
features_per_channel = []
|
|
198
|
-
for channel in range(
|
|
198
|
+
for channel in range(image_2d.shape[-1]):
|
|
199
199
|
channel_features = self.compute_deep_feature_maps_cpu_2d(image_2d = image_2d[..., channel])
|
|
200
200
|
features_per_channel.append(channel_features)
|
|
201
201
|
|
|
@@ -308,10 +308,10 @@ class InteractiveSegmenter:
|
|
|
308
308
|
if image_2d is None:
|
|
309
309
|
image_2d = self.image_3d[z, :, :]
|
|
310
310
|
|
|
311
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
311
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
312
312
|
# RGB case - process each channel
|
|
313
313
|
features_per_channel = []
|
|
314
|
-
for channel in range(
|
|
314
|
+
for channel in range(image_2d.shape[-1]):
|
|
315
315
|
channel_features = self.compute_feature_maps_cpu_2d(image_2d = image_2d[..., channel])
|
|
316
316
|
features_per_channel.append(channel_features)
|
|
317
317
|
|
|
@@ -361,10 +361,10 @@ class InteractiveSegmenter:
|
|
|
361
361
|
if image_3d is None:
|
|
362
362
|
image_3d = self.image_3d
|
|
363
363
|
|
|
364
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
364
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
365
365
|
# RGB case - process each channel
|
|
366
366
|
features_per_channel = []
|
|
367
|
-
for channel in range(
|
|
367
|
+
for channel in range(image_3d.shape[-1]):
|
|
368
368
|
channel_features = self.compute_deep_feature_maps_cpu(image_3d[..., channel])
|
|
369
369
|
features_per_channel.append(channel_features)
|
|
370
370
|
|
|
@@ -483,127 +483,15 @@ class InteractiveSegmenter:
|
|
|
483
483
|
|
|
484
484
|
return features
|
|
485
485
|
|
|
486
|
-
def compute_deep_feature_maps_cpu_smaller(self, image_3d=None): #smaller
|
|
487
|
-
"""Optimized version using determinant instead of full eigenvalue computation. Currently not in use anywhere"""
|
|
488
|
-
if image_3d is None:
|
|
489
|
-
image_3d = self.image_3d
|
|
490
|
-
|
|
491
|
-
# Calculate total number of features (using determinant instead of 3 eigenvalues)
|
|
492
|
-
num_basic_features = 1 + len(self.sigmas) + len(self.dogs)
|
|
493
|
-
num_gradient_features = len(self.sigmas)
|
|
494
|
-
num_laplacian_features = len(self.sigmas)
|
|
495
|
-
num_hessian_features = len(self.sigmas) * 3 # determinant + trace + frobenius norm
|
|
496
|
-
|
|
497
|
-
total_features = num_basic_features + num_gradient_features + num_laplacian_features + num_hessian_features
|
|
498
|
-
|
|
499
|
-
# Pre-allocate result array
|
|
500
|
-
features = np.empty(image_3d.shape + (total_features,), dtype=image_3d.dtype)
|
|
501
|
-
features[..., 0] = image_3d
|
|
502
|
-
|
|
503
|
-
feature_idx = 1
|
|
504
|
-
|
|
505
|
-
# Cache for Gaussian filters
|
|
506
|
-
gaussian_cache = {}
|
|
507
|
-
all_sigmas = set(self.sigmas)
|
|
508
|
-
for s1, s2 in self.dogs:
|
|
509
|
-
all_sigmas.add(s1)
|
|
510
|
-
all_sigmas.add(s2)
|
|
511
|
-
|
|
512
|
-
# Pre-compute all Gaussian filters
|
|
513
|
-
for sigma in all_sigmas:
|
|
514
|
-
gaussian_cache[sigma] = ndimage.gaussian_filter(image_3d, sigma)
|
|
515
|
-
|
|
516
|
-
# Gaussian smoothing
|
|
517
|
-
for sigma in self.sigmas:
|
|
518
|
-
features[..., feature_idx] = gaussian_cache[sigma]
|
|
519
|
-
feature_idx += 1
|
|
520
|
-
|
|
521
|
-
# Difference of Gaussians
|
|
522
|
-
for s1, s2 in self.dogs:
|
|
523
|
-
features[..., feature_idx] = gaussian_cache[s1] - gaussian_cache[s2]
|
|
524
|
-
feature_idx += 1
|
|
525
|
-
|
|
526
|
-
# Gaussian gradient magnitudes
|
|
527
|
-
for sigma in self.sigmas:
|
|
528
|
-
gaussian_img = gaussian_cache[sigma]
|
|
529
|
-
gx = ndimage.sobel(gaussian_img, axis=2, mode='reflect')
|
|
530
|
-
gy = ndimage.sobel(gaussian_img, axis=1, mode='reflect')
|
|
531
|
-
gz = ndimage.sobel(gaussian_img, axis=0, mode='reflect')
|
|
532
|
-
features[..., feature_idx] = np.sqrt(gx**2 + gy**2 + gz**2)
|
|
533
|
-
feature_idx += 1
|
|
534
|
-
|
|
535
|
-
# Laplacian of Gaussian
|
|
536
|
-
for sigma in self.sigmas:
|
|
537
|
-
gaussian_img = gaussian_cache[sigma]
|
|
538
|
-
features[..., feature_idx] = ndimage.laplace(gaussian_img, mode='reflect')
|
|
539
|
-
feature_idx += 1
|
|
540
|
-
|
|
541
|
-
# Hessian-based features (much faster than full eigenvalue computation)
|
|
542
|
-
for sigma in self.sigmas:
|
|
543
|
-
gaussian_img = gaussian_cache[sigma]
|
|
544
|
-
|
|
545
|
-
# Compute second derivatives
|
|
546
|
-
hxx = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[0, 0, 2], mode='reflect')
|
|
547
|
-
hyy = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[0, 2, 0], mode='reflect')
|
|
548
|
-
hzz = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[2, 0, 0], mode='reflect')
|
|
549
|
-
hxy = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[0, 1, 1], mode='reflect')
|
|
550
|
-
hxz = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[1, 0, 1], mode='reflect')
|
|
551
|
-
hyz = ndimage.gaussian_filter(gaussian_img, sigma=0, order=[1, 1, 0], mode='reflect')
|
|
552
|
-
|
|
553
|
-
# Hessian determinant (captures overall curvature)
|
|
554
|
-
determinant = (hxx * (hyy * hzz - hyz**2) -
|
|
555
|
-
hxy * (hxy * hzz - hxz * hyz) +
|
|
556
|
-
hxz * (hxy * hyz - hyy * hxz))
|
|
557
|
-
features[..., feature_idx] = determinant
|
|
558
|
-
feature_idx += 1
|
|
559
|
-
|
|
560
|
-
# Hessian trace (sum of eigenvalues)
|
|
561
|
-
trace = hxx + hyy + hzz
|
|
562
|
-
features[..., feature_idx] = trace
|
|
563
|
-
feature_idx += 1
|
|
564
|
-
|
|
565
|
-
# Frobenius norm (overall curvature magnitude)
|
|
566
|
-
frobenius_norm = np.sqrt(hxx**2 + hyy**2 + hzz**2 + 2*(hxy**2 + hxz**2 + hyz**2))
|
|
567
|
-
features[..., feature_idx] = frobenius_norm
|
|
568
|
-
feature_idx += 1
|
|
569
|
-
|
|
570
|
-
"""
|
|
571
|
-
# Normalize features: zero-mean, unit variance per feature band
|
|
572
|
-
# Compute mean and std across spatial dimensions (0,1,2), keeping feature dimension
|
|
573
|
-
feature_means = np.mean(features, axis=(0, 1, 2), keepdims=True)
|
|
574
|
-
feature_stds = np.std(features, axis=(0, 1, 2), keepdims=True)
|
|
575
|
-
|
|
576
|
-
# Avoid division by zero for constant features
|
|
577
|
-
feature_stds = np.where(feature_stds == 0, 1, feature_stds)
|
|
578
|
-
|
|
579
|
-
# Normalize in-place for memory efficiency
|
|
580
|
-
features = (features - feature_means) / feature_stds
|
|
581
|
-
"""
|
|
582
|
-
# Normalize only morphological features, keep intensity features raw
|
|
583
|
-
intensity_features = features[..., :num_basic_features] # original + gaussians + DoGs
|
|
584
|
-
morphology_features = features[..., num_basic_features:] # gradients + laplacians + eigenvalues
|
|
585
|
-
|
|
586
|
-
# Normalize only morphological features
|
|
587
|
-
morph_means = np.mean(morphology_features, axis=(0,1,2), keepdims=True)
|
|
588
|
-
morph_stds = np.std(morphology_features, axis=(0,1,2), keepdims=True)
|
|
589
|
-
morph_stds = np.where(morph_stds == 0, 1, morph_stds)
|
|
590
|
-
morphology_features = (morphology_features - morph_means) / morph_stds
|
|
591
|
-
|
|
592
|
-
# Recombine
|
|
593
|
-
features = np.concatenate([intensity_features, morphology_features], axis=-1)
|
|
594
|
-
|
|
595
|
-
return features
|
|
596
|
-
|
|
597
|
-
|
|
598
486
|
def compute_feature_maps_cpu(self, image_3d=None): #lil
|
|
599
487
|
"""Optimized version that caches Gaussian filters to avoid redundant computation"""
|
|
600
488
|
if image_3d is None:
|
|
601
489
|
image_3d = self.image_3d
|
|
602
490
|
|
|
603
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
491
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
604
492
|
# RGB case - process each channel
|
|
605
493
|
features_per_channel = []
|
|
606
|
-
for channel in range(
|
|
494
|
+
for channel in range(image_3d.shape[-1]):
|
|
607
495
|
channel_features = self.compute_feature_maps_cpu(image_3d[..., channel])
|
|
608
496
|
features_per_channel.append(channel_features)
|
|
609
497
|
|
|
@@ -1420,7 +1308,10 @@ class InteractiveSegmenter:
|
|
|
1420
1308
|
chunk_size = max(16, min(chunk_size, min(self.image_3d.shape) // 2))
|
|
1421
1309
|
chunk_size = ((chunk_size + 7) // 16) * 16
|
|
1422
1310
|
|
|
1423
|
-
|
|
1311
|
+
try:
|
|
1312
|
+
depth, height, width = self.image_3d.shape
|
|
1313
|
+
except:
|
|
1314
|
+
depth, height, width, rgb = self.image_3d.shape
|
|
1424
1315
|
|
|
1425
1316
|
# Calculate chunk grid dimensions
|
|
1426
1317
|
z_chunks = (depth + chunk_size - 1) // chunk_size
|
nettracer3d/segmenter_GPU.py
CHANGED
|
@@ -320,10 +320,10 @@ class InteractiveSegmenter:
|
|
|
320
320
|
if image_3d is None:
|
|
321
321
|
image_3d = self.image_3d # Assuming this is already a cupy array
|
|
322
322
|
|
|
323
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
323
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
324
324
|
# RGB case - process each channel
|
|
325
325
|
features_per_channel = []
|
|
326
|
-
for channel in range(
|
|
326
|
+
for channel in range(image_3d.shape[-1]):
|
|
327
327
|
channel_features = self.compute_feature_maps_gpu(image_3d[..., channel])
|
|
328
328
|
features_per_channel.append(channel_features)
|
|
329
329
|
|
|
@@ -376,10 +376,10 @@ class InteractiveSegmenter:
|
|
|
376
376
|
if image_3d is None:
|
|
377
377
|
image_3d = self.image_3d # Assuming this is already a cupy array
|
|
378
378
|
|
|
379
|
-
if image_3d.ndim == 4 and image_3d.shape[-1] == 3:
|
|
379
|
+
if image_3d.ndim == 4 and (image_3d.shape[-1] == 3 or image_3d.shape[-1] == 4):
|
|
380
380
|
# RGB case - process each channel
|
|
381
381
|
features_per_channel = []
|
|
382
|
-
for channel in range(
|
|
382
|
+
for channel in range(image_3d.shape[-1]):
|
|
383
383
|
channel_features = self.compute_deep_feature_maps_gpu(image_3d[..., channel])
|
|
384
384
|
features_per_channel.append(channel_features)
|
|
385
385
|
|
|
@@ -507,10 +507,10 @@ class InteractiveSegmenter:
|
|
|
507
507
|
if image_2d is None:
|
|
508
508
|
image_2d = cp.asarray(self.image_3d[z, :, :])
|
|
509
509
|
|
|
510
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
510
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
511
511
|
# RGB case - process each channel
|
|
512
512
|
features_per_channel = []
|
|
513
|
-
for channel in range(
|
|
513
|
+
for channel in range(image_2d.shape[-1]):
|
|
514
514
|
channel_features = self.compute_feature_maps_gpu_2d(image_2d = image_2d[..., channel])
|
|
515
515
|
features_per_channel.append(channel_features)
|
|
516
516
|
|
|
@@ -567,10 +567,10 @@ class InteractiveSegmenter:
|
|
|
567
567
|
if image_2d is None:
|
|
568
568
|
image_2d = cp.asarray(self.image_3d[z, :, :])
|
|
569
569
|
|
|
570
|
-
if image_2d.ndim == 3 and image_2d.shape[-1] == 3:
|
|
570
|
+
if image_2d.ndim == 3 and (image_2d.shape[-1] == 3 or image_2d.shape[-1] == 4):
|
|
571
571
|
# RGB case - process each channel
|
|
572
572
|
features_per_channel = []
|
|
573
|
-
for channel in range(
|
|
573
|
+
for channel in range(image_2d.shape[-1]):
|
|
574
574
|
channel_features = self.compute_deep_feature_maps_gpu_2d(image_2d = image_2d[..., channel])
|
|
575
575
|
features_per_channel.append(channel_features)
|
|
576
576
|
|
|
@@ -1082,7 +1082,10 @@ class InteractiveSegmenter:
|
|
|
1082
1082
|
chunk_size = max(16, min(chunk_size, min(self.image_3d.shape) // 2))
|
|
1083
1083
|
chunk_size = ((chunk_size + 7) // 16) * 16
|
|
1084
1084
|
|
|
1085
|
-
|
|
1085
|
+
try:
|
|
1086
|
+
depth, height, width = self.image_3d.shape
|
|
1087
|
+
except:
|
|
1088
|
+
depth, height, width, rgb = self.image_3d.shape
|
|
1086
1089
|
|
|
1087
1090
|
# Calculate chunk grid dimensions
|
|
1088
1091
|
z_chunks = (depth + chunk_size - 1) // chunk_size
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.8
|
|
4
4
|
Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
|
|
5
5
|
Author-email: Liam McLaughlin <liamm@wustl.edu>
|
|
6
6
|
Project-URL: Documentation, https://nettracer3d.readthedocs.io/en/latest/
|
|
@@ -110,10 +110,6 @@ McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neuro
|
|
|
110
110
|
|
|
111
111
|
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
112
112
|
|
|
113
|
-
-- Version 0.9.
|
|
113
|
+
-- Version 0.9.8 Updates --
|
|
114
114
|
|
|
115
|
-
*
|
|
116
|
-
* The 'merge node id' option now offers interactive support for assisted thresholding for any new identity channels the user is trying to merge with.
|
|
117
|
-
* Bug Fixes
|
|
118
|
-
* The 'merge nodes' option now can provide centroids prior to the merge, since oftentimes objects end up on top of each other.
|
|
119
|
-
* A few other minor adjustments.
|
|
115
|
+
* Some minor bug fixes
|
|
@@ -6,20 +6,20 @@ nettracer3d/modularity.py,sha256=pborVcDBvICB2-g8lNoSVZbIReIBlfeBmjFbPYmtq7Y,224
|
|
|
6
6
|
nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
|
|
7
7
|
nettracer3d/neighborhoods.py,sha256=iIaHU1COIdRtzRpAuIQKfLGLNKYFK3dL8Vb_EeJIlEA,46459
|
|
8
8
|
nettracer3d/nettracer.py,sha256=d9Mhz-pHox5OfGGUSTrkTBJzCWCrbQvClTu2ANt-jUE,267943
|
|
9
|
-
nettracer3d/nettracer_gui.py,sha256=
|
|
9
|
+
nettracer3d/nettracer_gui.py,sha256=2OuTeJ1xnarlZAYjW9R4hvBA4ZiW_Ce0NtfTamqpbWU,628156
|
|
10
10
|
nettracer3d/network_analysis.py,sha256=kBzsVaq4dZkMe0k-VGvQIUvM-tK0ZZ8bvb-wtsugZRQ,46150
|
|
11
11
|
nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
|
|
12
12
|
nettracer3d/node_draw.py,sha256=kZcR1PekLg0riioNeGcALIXQyZ5PtHA_9MT6z7Zovdk,10401
|
|
13
13
|
nettracer3d/painting.py,sha256=K_dwngivw80r-Yyg4btKMsWGn566ZE9PnrQl986uxJE,23497
|
|
14
14
|
nettracer3d/proximity.py,sha256=WaHPwE6ypeInFO_LnMT0zaVE53jX3TJx6h7nmtYtr8U,41824
|
|
15
15
|
nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
|
|
16
|
-
nettracer3d/segmenter.py,sha256
|
|
17
|
-
nettracer3d/segmenter_GPU.py,sha256=
|
|
16
|
+
nettracer3d/segmenter.py,sha256=aOO3PwZ2UeizEIFX7N8midwzTzbEDzgM2jQ7WTdbrUg,70671
|
|
17
|
+
nettracer3d/segmenter_GPU.py,sha256=OUekQljLKPiC4d4hNZmqrRa9HSVQ6HcCnILiAfHE5Hg,78051
|
|
18
18
|
nettracer3d/simple_network.py,sha256=dkG4jpc4zzdeuoaQobgGfL3PNo6N8dGKQ5hEEubFIvA,9947
|
|
19
19
|
nettracer3d/smart_dilate.py,sha256=TvRUh6B4q4zIdCO1BWH-xgTdND5OUNmo99eyxG9oIAU,27145
|
|
20
|
-
nettracer3d-0.9.
|
|
21
|
-
nettracer3d-0.9.
|
|
22
|
-
nettracer3d-0.9.
|
|
23
|
-
nettracer3d-0.9.
|
|
24
|
-
nettracer3d-0.9.
|
|
25
|
-
nettracer3d-0.9.
|
|
20
|
+
nettracer3d-0.9.8.dist-info/licenses/LICENSE,sha256=jnNT-yBeIAKAHpYthPvLeqCzJ6nSurgnKmloVnfsjCI,764
|
|
21
|
+
nettracer3d-0.9.8.dist-info/METADATA,sha256=h-H4X4k6Yf1n9ZFgVbyYBLmXQDvcpgQncQt5QZfBh6k,6997
|
|
22
|
+
nettracer3d-0.9.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
nettracer3d-0.9.8.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
|
|
24
|
+
nettracer3d-0.9.8.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
25
|
+
nettracer3d-0.9.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|