nettracer3d 0.6.4__py3-none-any.whl → 0.6.6__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.
- nettracer3d/morphology.py +207 -5
- nettracer3d/nettracer.py +48 -6
- nettracer3d/nettracer_gui.py +291 -76
- nettracer3d/segmenter.py +239 -164
- nettracer3d/smart_dilate.py +2 -31
- {nettracer3d-0.6.4.dist-info → nettracer3d-0.6.6.dist-info}/METADATA +5 -11
- {nettracer3d-0.6.4.dist-info → nettracer3d-0.6.6.dist-info}/RECORD +11 -11
- {nettracer3d-0.6.4.dist-info → nettracer3d-0.6.6.dist-info}/WHEEL +0 -0
- {nettracer3d-0.6.4.dist-info → nettracer3d-0.6.6.dist-info}/entry_points.txt +0 -0
- {nettracer3d-0.6.4.dist-info → nettracer3d-0.6.6.dist-info}/licenses/LICENSE +0 -0
- {nettracer3d-0.6.4.dist-info → nettracer3d-0.6.6.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -1399,55 +1399,128 @@ class ImageViewerWindow(QMainWindow):
|
|
|
1399
1399
|
print(f"An error has occured: {e}")
|
|
1400
1400
|
|
|
1401
1401
|
def handle_seperate(self):
|
|
1402
|
-
|
|
1402
|
+
print("Note: I search each selected label one at a time and then split it with the ndimage.label method which uses C but still has to search the entire array each time, I may be a very slow with big operations :)")
|
|
1403
1403
|
try:
|
|
1404
|
-
|
|
1404
|
+
# Handle nodes
|
|
1405
1405
|
if len(self.clicked_values['nodes']) > 0:
|
|
1406
|
-
self.create_highlight_overlay(node_indices
|
|
1407
|
-
max_val = np.max(my_network.nodes)
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1406
|
+
self.create_highlight_overlay(node_indices=self.clicked_values['nodes'])
|
|
1407
|
+
max_val = np.max(my_network.nodes) + 1
|
|
1408
|
+
|
|
1409
|
+
# Create a boolean mask for highlighted values
|
|
1410
|
+
self.highlight_overlay = self.highlight_overlay != 0
|
|
1411
|
+
|
|
1412
|
+
# Create array with just the highlighted values
|
|
1413
|
+
highlighted_nodes = self.highlight_overlay * my_network.nodes
|
|
1414
|
+
|
|
1415
|
+
# Get unique values in the highlighted regions (excluding 0)
|
|
1416
|
+
vals = list(np.unique(highlighted_nodes))
|
|
1417
|
+
if vals[0] == 0:
|
|
1418
|
+
del vals[0]
|
|
1419
|
+
|
|
1420
|
+
# Process each value separately
|
|
1421
|
+
for val in vals:
|
|
1422
|
+
# Create a mask for this value
|
|
1423
|
+
val_mask = my_network.nodes == val
|
|
1424
|
+
|
|
1425
|
+
# Create an array without this value
|
|
1426
|
+
temp = my_network.nodes - (val_mask * val)
|
|
1427
|
+
|
|
1428
|
+
# Label the connected components for this value
|
|
1429
|
+
labeled_mask, num_components = n3d.label_objects(val_mask)
|
|
1430
|
+
|
|
1431
|
+
if num_components > 1:
|
|
1432
|
+
# Set appropriate dtype based on max value
|
|
1433
|
+
if max_val + num_components < 256:
|
|
1434
|
+
dtype = np.uint8
|
|
1435
|
+
elif max_val + num_components < 65536:
|
|
1436
|
+
dtype = np.uint16
|
|
1437
|
+
labeled_mask = labeled_mask.astype(dtype)
|
|
1438
|
+
temp = temp.astype(dtype)
|
|
1439
|
+
else:
|
|
1440
|
+
dtype = np.uint32
|
|
1441
|
+
labeled_mask = labeled_mask.astype(dtype)
|
|
1442
|
+
temp = temp.astype(dtype)
|
|
1443
|
+
|
|
1444
|
+
# Add new labels to the temporary array
|
|
1445
|
+
mask_nonzero = labeled_mask != 0
|
|
1446
|
+
labeled_mask = labeled_mask + max_val - 1 # -1 because we'll restore the first component
|
|
1447
|
+
labeled_mask = labeled_mask * mask_nonzero
|
|
1448
|
+
|
|
1449
|
+
# Restore original value for first component
|
|
1450
|
+
first_component = labeled_mask == max_val
|
|
1451
|
+
labeled_mask = labeled_mask - (first_component * (max_val - val))
|
|
1452
|
+
|
|
1453
|
+
# Add labeled components back to the array
|
|
1454
|
+
my_network.nodes = temp + labeled_mask
|
|
1455
|
+
|
|
1456
|
+
# Update max value for next iteration
|
|
1457
|
+
max_val += num_components - 1 # -1 because we kept one original label
|
|
1458
|
+
|
|
1423
1459
|
self.load_channel(0, my_network.nodes, True)
|
|
1424
|
-
|
|
1460
|
+
|
|
1461
|
+
# Handle edges
|
|
1425
1462
|
if len(self.clicked_values['edges']) > 0:
|
|
1426
|
-
self.create_highlight_overlay(edge_indices
|
|
1427
|
-
max_val = np.max(my_network.edges)
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1463
|
+
self.create_highlight_overlay(edge_indices=self.clicked_values['edges'])
|
|
1464
|
+
max_val = np.max(my_network.edges) + 1
|
|
1465
|
+
|
|
1466
|
+
# Create a boolean mask for highlighted values
|
|
1467
|
+
self.highlight_overlay = self.highlight_overlay != 0
|
|
1468
|
+
|
|
1469
|
+
# Create array with just the highlighted values
|
|
1470
|
+
highlighted_edges = self.highlight_overlay * my_network.edges
|
|
1471
|
+
|
|
1472
|
+
# Get unique values in the highlighted regions (excluding 0)
|
|
1473
|
+
vals = list(np.unique(highlighted_edges))
|
|
1474
|
+
if vals[0] == 0:
|
|
1475
|
+
del vals[0]
|
|
1476
|
+
|
|
1477
|
+
# Process each value separately
|
|
1478
|
+
for val in vals:
|
|
1479
|
+
# Create a mask for this value
|
|
1480
|
+
val_mask = my_network.edges == val
|
|
1481
|
+
|
|
1482
|
+
# Create an array without this value
|
|
1483
|
+
temp = my_network.edges - (val_mask * val)
|
|
1484
|
+
|
|
1485
|
+
# Label the connected components for this value
|
|
1486
|
+
labeled_mask, num_components = n3d.label_objects(val_mask)
|
|
1487
|
+
|
|
1488
|
+
if num_components > 1:
|
|
1489
|
+
# Set appropriate dtype based on max value
|
|
1490
|
+
if max_val + num_components < 256:
|
|
1491
|
+
dtype = np.uint8
|
|
1492
|
+
elif max_val + num_components < 65536:
|
|
1493
|
+
dtype = np.uint16
|
|
1494
|
+
labeled_mask = labeled_mask.astype(dtype)
|
|
1495
|
+
temp = temp.astype(dtype)
|
|
1496
|
+
else:
|
|
1497
|
+
dtype = np.uint32
|
|
1498
|
+
labeled_mask = labeled_mask.astype(dtype)
|
|
1499
|
+
temp = temp.astype(dtype)
|
|
1500
|
+
|
|
1501
|
+
# Add new labels to the temporary array
|
|
1502
|
+
mask_nonzero = labeled_mask != 0
|
|
1503
|
+
labeled_mask = labeled_mask + max_val - 1 # -1 because we'll restore the first component
|
|
1504
|
+
labeled_mask = labeled_mask * mask_nonzero
|
|
1505
|
+
|
|
1506
|
+
# Restore original value for first component
|
|
1507
|
+
first_component = labeled_mask == max_val
|
|
1508
|
+
labeled_mask = labeled_mask - (first_component * (max_val - val))
|
|
1509
|
+
|
|
1510
|
+
# Add labeled components back to the array
|
|
1511
|
+
my_network.edges = temp + labeled_mask
|
|
1512
|
+
|
|
1513
|
+
# Update max value for next iteration
|
|
1514
|
+
max_val += num_components - 1 # -1 because we kept one original label
|
|
1515
|
+
|
|
1443
1516
|
self.load_channel(1, my_network.edges, True)
|
|
1517
|
+
|
|
1444
1518
|
self.highlight_overlay = None
|
|
1445
1519
|
self.update_display()
|
|
1446
1520
|
print("Network is not updated automatically, please recompute if necessary. Identities are not automatically updated.")
|
|
1447
1521
|
self.show_centroid_dialog()
|
|
1448
|
-
|
|
1449
1522
|
except Exception as e:
|
|
1450
|
-
print(f"Error
|
|
1523
|
+
print(f"Error separating: {e}")
|
|
1451
1524
|
|
|
1452
1525
|
|
|
1453
1526
|
|
|
@@ -2392,6 +2465,8 @@ class ImageViewerWindow(QMainWindow):
|
|
|
2392
2465
|
random_action.triggered.connect(self.show_random_dialog)
|
|
2393
2466
|
vol_action = stats_menu.addAction("Calculate Volumes")
|
|
2394
2467
|
vol_action.triggered.connect(self.volumes)
|
|
2468
|
+
rad_action = stats_menu.addAction("Calculate Radii")
|
|
2469
|
+
rad_action.triggered.connect(self.show_rad_dialog)
|
|
2395
2470
|
inter_action = stats_menu.addAction("Calculate Node < > Edge Interaction")
|
|
2396
2471
|
inter_action.triggered.connect(self.show_interaction_dialog)
|
|
2397
2472
|
overlay_menu = analysis_menu.addMenu("Data/Overlays")
|
|
@@ -3312,8 +3387,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
3312
3387
|
|
|
3313
3388
|
|
|
3314
3389
|
except Exception as e:
|
|
3315
|
-
|
|
3316
|
-
print(traceback.format_exc())
|
|
3390
|
+
|
|
3317
3391
|
if not data:
|
|
3318
3392
|
from PyQt6.QtWidgets import QMessageBox
|
|
3319
3393
|
QMessageBox.critical(
|
|
@@ -3825,6 +3899,9 @@ class ImageViewerWindow(QMainWindow):
|
|
|
3825
3899
|
dialog = RandomDialog(self)
|
|
3826
3900
|
dialog.exec()
|
|
3827
3901
|
|
|
3902
|
+
def show_rad_dialog(self):
|
|
3903
|
+
dialog = RadDialog(self)
|
|
3904
|
+
dialog.exec()
|
|
3828
3905
|
|
|
3829
3906
|
def show_interaction_dialog(self):
|
|
3830
3907
|
dialog = InteractionDialog(self)
|
|
@@ -4241,16 +4318,21 @@ class CustomTableView(QTableView):
|
|
|
4241
4318
|
self.parent.clicked_values['edges'] = []
|
|
4242
4319
|
self.parent.clicked_values['nodes'].append(value)
|
|
4243
4320
|
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4321
|
+
try:
|
|
4322
|
+
# Highlight the value in both tables if it exists
|
|
4323
|
+
self.highlight_value_in_table(self.parent.network_table, value, column)
|
|
4324
|
+
self.highlight_value_in_table(self.parent.selection_table, value, column)
|
|
4325
|
+
except:
|
|
4326
|
+
pass
|
|
4247
4327
|
else:
|
|
4248
4328
|
print(f"Node {value} not found in centroids dictionary")
|
|
4249
4329
|
|
|
4250
4330
|
elif column == 2: # Third column is edges
|
|
4331
|
+
if my_network.edge_centroids is None:
|
|
4332
|
+
self.parent.show_centroid_dialog()
|
|
4333
|
+
|
|
4251
4334
|
if value in my_network.edge_centroids:
|
|
4252
|
-
|
|
4253
|
-
self.parent.show_centroid_dialog()
|
|
4335
|
+
|
|
4254
4336
|
# Get centroid coordinates (Z, Y, X)
|
|
4255
4337
|
centroid = my_network.edge_centroids[value]
|
|
4256
4338
|
# Set the active channel to edges (1)
|
|
@@ -4271,9 +4353,12 @@ class CustomTableView(QTableView):
|
|
|
4271
4353
|
self.parent.clicked_values['edges'] = []
|
|
4272
4354
|
self.parent.clicked_values['edges'].append(value)
|
|
4273
4355
|
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4356
|
+
try:
|
|
4357
|
+
# Highlight the value in both tables if it exists
|
|
4358
|
+
self.highlight_value_in_table(self.parent.network_table, value, column)
|
|
4359
|
+
self.highlight_value_in_table(self.parent.selection_table, value, column)
|
|
4360
|
+
except:
|
|
4361
|
+
pass
|
|
4277
4362
|
else:
|
|
4278
4363
|
print(f"Edge {value} not found in centroids dictionary")
|
|
4279
4364
|
else: #If highlighting paired elements
|
|
@@ -4905,6 +4990,52 @@ class ArbitraryDialog(QDialog):
|
|
|
4905
4990
|
continue
|
|
4906
4991
|
|
|
4907
4992
|
return processed_values
|
|
4993
|
+
|
|
4994
|
+
def handle_find_action(self, mode, value):
|
|
4995
|
+
"""Handle the Find action."""
|
|
4996
|
+
|
|
4997
|
+
# Determine if we're looking for a node or edge
|
|
4998
|
+
if mode == 0:
|
|
4999
|
+
|
|
5000
|
+
if my_network.node_centroids is None:
|
|
5001
|
+
self.parent().show_centroid_dialog()
|
|
5002
|
+
|
|
5003
|
+
if value in my_network.node_centroids:
|
|
5004
|
+
# Get centroid coordinates (Z, Y, X)
|
|
5005
|
+
centroid = my_network.node_centroids[value]
|
|
5006
|
+
# Set the active channel to nodes (0)
|
|
5007
|
+
self.parent().set_active_channel(0)
|
|
5008
|
+
# Toggle on the nodes channel if it's not already visible
|
|
5009
|
+
if not self.parent().channel_visible[0]:
|
|
5010
|
+
self.parent().channel_buttons[0].setChecked(True)
|
|
5011
|
+
self.parent().toggle_channel(0)
|
|
5012
|
+
# Navigate to the Z-slice
|
|
5013
|
+
self.parent().slice_slider.setValue(int(centroid[0]))
|
|
5014
|
+
print(f"Found node {value} at Z-slice {centroid[0]}")
|
|
5015
|
+
|
|
5016
|
+
else:
|
|
5017
|
+
print(f"Node {value} not found in centroids dictionary")
|
|
5018
|
+
|
|
5019
|
+
else: # edges
|
|
5020
|
+
if my_network.edge_centroids is None:
|
|
5021
|
+
self.parent().show_centroid_dialog()
|
|
5022
|
+
|
|
5023
|
+
if value in my_network.edge_centroids:
|
|
5024
|
+
|
|
5025
|
+
# Get centroid coordinates (Z, Y, X)
|
|
5026
|
+
centroid = my_network.edge_centroids[value]
|
|
5027
|
+
# Set the active channel to edges (1)
|
|
5028
|
+
self.parent().set_active_channel(1)
|
|
5029
|
+
# Toggle on the edges channel if it's not already visible
|
|
5030
|
+
if not self.parent().channel_visible[1]:
|
|
5031
|
+
self.parent().channel_buttons[1].setChecked(True)
|
|
5032
|
+
self.parent().toggle_channel(1)
|
|
5033
|
+
# Navigate to the Z-slice
|
|
5034
|
+
self.parent().slice_slider.setValue(int(centroid[0]))
|
|
5035
|
+
print(f"Found edge {value} at Z-slice {centroid[0]}")
|
|
5036
|
+
|
|
5037
|
+
else:
|
|
5038
|
+
print(f"Edge {value} not found in centroids dictionary")
|
|
4908
5039
|
|
|
4909
5040
|
def process_selections(self):
|
|
4910
5041
|
"""Process the selection and deselection inputs."""
|
|
@@ -4940,11 +5071,21 @@ class ArbitraryDialog(QDialog):
|
|
|
4940
5071
|
except:
|
|
4941
5072
|
pass #Forgive mistakes
|
|
4942
5073
|
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
5074
|
+
select_list.reverse()
|
|
5075
|
+
|
|
5076
|
+
self.parent().clicked_values[mode].extend(select_list)
|
|
5077
|
+
|
|
5078
|
+
select_list.reverse()
|
|
5079
|
+
|
|
5080
|
+
try:
|
|
5081
|
+
if mode == 'nodes':
|
|
5082
|
+
self.handle_find_action(0, select_list[0])
|
|
5083
|
+
self.parent().handle_info(sort = 'node')
|
|
5084
|
+
elif mode == 'edges':
|
|
5085
|
+
self.handle_find_action(1, select_list[0])
|
|
5086
|
+
self.parent().handle_info(sort = 'edge')
|
|
5087
|
+
except:
|
|
5088
|
+
pass
|
|
4948
5089
|
|
|
4949
5090
|
self.parent().clicked_values[mode] = list(set(self.parent().clicked_values[mode]))
|
|
4950
5091
|
|
|
@@ -4964,6 +5105,8 @@ class ArbitraryDialog(QDialog):
|
|
|
4964
5105
|
|
|
4965
5106
|
except Exception as e:
|
|
4966
5107
|
QMessageBox.critical(self, "Error", f"Error processing selections: {str(e)}")
|
|
5108
|
+
import traceback
|
|
5109
|
+
print(traceback.format_exc())
|
|
4967
5110
|
|
|
4968
5111
|
class Show3dDialog(QDialog):
|
|
4969
5112
|
def __init__(self, parent=None):
|
|
@@ -5257,8 +5400,10 @@ class ShuffleDialog(QDialog):
|
|
|
5257
5400
|
|
|
5258
5401
|
try:
|
|
5259
5402
|
if accepted_mode == 4:
|
|
5260
|
-
|
|
5261
|
-
|
|
5403
|
+
try:
|
|
5404
|
+
self.parent().highlight_overlay = n3d.binarize(target_data)
|
|
5405
|
+
except:
|
|
5406
|
+
self.parent().highlight_overay = None
|
|
5262
5407
|
else:
|
|
5263
5408
|
self.parent().load_channel(accepted_mode, channel_data = target_data, data = True)
|
|
5264
5409
|
except:
|
|
@@ -5271,11 +5416,12 @@ class ShuffleDialog(QDialog):
|
|
|
5271
5416
|
self.parent().highlight_overlay = n3d.binarize(active_data)
|
|
5272
5417
|
except:
|
|
5273
5418
|
self.parent().highlight_overlay = None
|
|
5419
|
+
else:
|
|
5420
|
+
self.parent().load_channel(accepted_target, channel_data = active_data, data = True)
|
|
5274
5421
|
except:
|
|
5275
5422
|
pass
|
|
5276
5423
|
|
|
5277
|
-
|
|
5278
|
-
self.parent().load_channel(accepted_target, channel_data = active_data, data = True)
|
|
5424
|
+
|
|
5279
5425
|
|
|
5280
5426
|
|
|
5281
5427
|
self.parent().update_display()
|
|
@@ -5604,6 +5750,50 @@ class RandomDialog(QDialog):
|
|
|
5604
5750
|
|
|
5605
5751
|
self.accept()
|
|
5606
5752
|
|
|
5753
|
+
class RadDialog(QDialog):
|
|
5754
|
+
|
|
5755
|
+
def __init__(self, parent=None):
|
|
5756
|
+
|
|
5757
|
+
super().__init__(parent)
|
|
5758
|
+
self.setWindowTitle("Obtain Radii of Active Image? (Returns Largest Radius for Each Labeled Object)")
|
|
5759
|
+
self.setModal(True)
|
|
5760
|
+
|
|
5761
|
+
layout = QFormLayout(self)
|
|
5762
|
+
|
|
5763
|
+
# GPU checkbox (default False)
|
|
5764
|
+
self.GPU = QPushButton("GPU")
|
|
5765
|
+
self.GPU.setCheckable(True)
|
|
5766
|
+
self.GPU.setChecked(False)
|
|
5767
|
+
layout.addRow("Use GPU:", self.GPU)
|
|
5768
|
+
|
|
5769
|
+
|
|
5770
|
+
# Add Run button
|
|
5771
|
+
run_button = QPushButton("Calculate")
|
|
5772
|
+
run_button.clicked.connect(self.rads)
|
|
5773
|
+
layout.addWidget(run_button)
|
|
5774
|
+
|
|
5775
|
+
def rads(self):
|
|
5776
|
+
|
|
5777
|
+
try:
|
|
5778
|
+
GPU = self.GPU.isChecked()
|
|
5779
|
+
|
|
5780
|
+
active_data = self.parent().channel_data[self.parent().active_channel]
|
|
5781
|
+
|
|
5782
|
+
radii = n3d.estimate_object_radii(active_data, gpu=GPU)
|
|
5783
|
+
|
|
5784
|
+
for key, val in radii.items():
|
|
5785
|
+
|
|
5786
|
+
radii[key] = [val, val * (my_network.xy_scale**2) * my_network.z_scale]
|
|
5787
|
+
|
|
5788
|
+
self.parent().format_for_upperright_table(radii, title = '~Radii of Objects', metric='ObjectID', value=['Largest Radius (Voxels)', 'Largest Radius (Scaled)'])
|
|
5789
|
+
|
|
5790
|
+
self.accept()
|
|
5791
|
+
|
|
5792
|
+
except Exception as e:
|
|
5793
|
+
print(f"Error: {e}")
|
|
5794
|
+
|
|
5795
|
+
|
|
5796
|
+
|
|
5607
5797
|
|
|
5608
5798
|
|
|
5609
5799
|
class InteractionDialog(QDialog):
|
|
@@ -6318,7 +6508,7 @@ class SLabelDialog(QDialog):
|
|
|
6318
6508
|
# GPU checkbox (default True)
|
|
6319
6509
|
self.GPU = QPushButton("GPU")
|
|
6320
6510
|
self.GPU.setCheckable(True)
|
|
6321
|
-
self.GPU.setChecked(
|
|
6511
|
+
self.GPU.setChecked(False)
|
|
6322
6512
|
layout.addRow("Use GPU:", self.GPU)
|
|
6323
6513
|
|
|
6324
6514
|
self.down_factor = QLineEdit("")
|
|
@@ -6558,16 +6748,16 @@ class MachineWindow(QMainWindow):
|
|
|
6558
6748
|
self.GPU.setChecked(False)
|
|
6559
6749
|
self.GPU.clicked.connect(self.toggle_GPU)
|
|
6560
6750
|
self.use_gpu = False
|
|
6561
|
-
self.two = QPushButton("Train By 2D Slice Patterns
|
|
6751
|
+
self.two = QPushButton("Train By 2D Slice Patterns")
|
|
6562
6752
|
self.two.setCheckable(True)
|
|
6563
|
-
self.two.setChecked(
|
|
6753
|
+
self.two.setChecked(False)
|
|
6564
6754
|
self.two.clicked.connect(self.toggle_two)
|
|
6565
|
-
self.use_two =
|
|
6755
|
+
self.use_two = False
|
|
6566
6756
|
self.three = QPushButton("Train by 3D Patterns")
|
|
6567
6757
|
self.three.setCheckable(True)
|
|
6568
|
-
self.three.setChecked(
|
|
6758
|
+
self.three.setChecked(True)
|
|
6569
6759
|
self.three.clicked.connect(self.toggle_three)
|
|
6570
|
-
processing_layout.addWidget(self.GPU)
|
|
6760
|
+
#processing_layout.addWidget(self.GPU) [Decided to hold off on this until its more robust]
|
|
6571
6761
|
processing_layout.addWidget(self.two)
|
|
6572
6762
|
processing_layout.addWidget(self.three)
|
|
6573
6763
|
processing_group.setLayout(processing_layout)
|
|
@@ -6600,7 +6790,7 @@ class MachineWindow(QMainWindow):
|
|
|
6600
6790
|
full_button.clicked.connect(self.segment)
|
|
6601
6791
|
segmentation_layout.addWidget(seg_button)
|
|
6602
6792
|
#segmentation_layout.addWidget(self.pause_button) # <--- for some reason the segmenter preview is still running even when killed, may be regenerating itself somewhere. May or may not actually try to resolve this because this feature isnt that necessary.
|
|
6603
|
-
segmentation_layout.addWidget(self.lock_button)
|
|
6793
|
+
#segmentation_layout.addWidget(self.lock_button) # Also turned this off
|
|
6604
6794
|
segmentation_layout.addWidget(full_button)
|
|
6605
6795
|
segmentation_group.setLayout(segmentation_layout)
|
|
6606
6796
|
|
|
@@ -7387,7 +7577,7 @@ class SmartDilateDialog(QDialog):
|
|
|
7387
7577
|
# GPU checkbox (default True)
|
|
7388
7578
|
self.GPU = QPushButton("GPU")
|
|
7389
7579
|
self.GPU.setCheckable(True)
|
|
7390
|
-
self.GPU.setChecked(
|
|
7580
|
+
self.GPU.setChecked(False)
|
|
7391
7581
|
layout.addRow("Use GPU:", self.GPU)
|
|
7392
7582
|
|
|
7393
7583
|
self.down_factor = QLineEdit("")
|
|
@@ -7615,6 +7805,18 @@ class HoleDialog(QDialog):
|
|
|
7615
7805
|
|
|
7616
7806
|
layout = QFormLayout(self)
|
|
7617
7807
|
|
|
7808
|
+
# auto checkbox (default True)
|
|
7809
|
+
self.headon = QPushButton("Head-on")
|
|
7810
|
+
self.headon.setCheckable(True)
|
|
7811
|
+
self.headon.setChecked(False)
|
|
7812
|
+
layout.addRow("Only Use 2D Slicing Dimension:", self.headon)
|
|
7813
|
+
|
|
7814
|
+
# auto checkbox (default True)
|
|
7815
|
+
self.borders = QPushButton("Borders")
|
|
7816
|
+
self.borders.setCheckable(True)
|
|
7817
|
+
self.borders.setChecked(True)
|
|
7818
|
+
layout.addRow("Fill Small Holes Along Borders:", self.borders)
|
|
7819
|
+
|
|
7618
7820
|
# Add Run button
|
|
7619
7821
|
run_button = QPushButton("Run Fill Holes")
|
|
7620
7822
|
run_button.clicked.connect(self.run_holes)
|
|
@@ -7628,10 +7830,15 @@ class HoleDialog(QDialog):
|
|
|
7628
7830
|
active_data = self.parent().channel_data[self.parent().active_channel]
|
|
7629
7831
|
if active_data is None:
|
|
7630
7832
|
raise ValueError("No active image selected")
|
|
7833
|
+
|
|
7834
|
+
borders = self.borders.isChecked()
|
|
7835
|
+
headon = self.headon.isChecked()
|
|
7631
7836
|
|
|
7632
7837
|
# Call dilate method with parameters
|
|
7633
7838
|
result = n3d.fill_holes_3d(
|
|
7634
|
-
active_data
|
|
7839
|
+
active_data,
|
|
7840
|
+
head_on = headon,
|
|
7841
|
+
fill_borders = borders
|
|
7635
7842
|
)
|
|
7636
7843
|
|
|
7637
7844
|
self.parent().load_channel(self.parent().active_channel, result, True)
|
|
@@ -7889,7 +8096,7 @@ class WatershedDialog(QDialog):
|
|
|
7889
8096
|
# GPU checkbox (default True)
|
|
7890
8097
|
self.gpu = QPushButton("GPU")
|
|
7891
8098
|
self.gpu.setCheckable(True)
|
|
7892
|
-
self.gpu.setChecked(
|
|
8099
|
+
self.gpu.setChecked(False)
|
|
7893
8100
|
layout.addRow("Use GPU:", self.gpu)
|
|
7894
8101
|
|
|
7895
8102
|
# Smallest radius (empty by default)
|
|
@@ -8758,15 +8965,23 @@ class CentroidDialog(QDialog):
|
|
|
8758
8965
|
my_network.save_edge_centroids(directory = directory)
|
|
8759
8966
|
|
|
8760
8967
|
elif chan == 0:
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8968
|
+
try:
|
|
8969
|
+
my_network.calculate_node_centroids(
|
|
8970
|
+
down_factor = downsample
|
|
8971
|
+
)
|
|
8972
|
+
my_network.save_node_centroids(directory = directory)
|
|
8973
|
+
except:
|
|
8974
|
+
pass
|
|
8765
8975
|
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8976
|
+
try:
|
|
8977
|
+
|
|
8978
|
+
my_network.calculate_edge_centroids(
|
|
8979
|
+
down_factor = downsample
|
|
8980
|
+
)
|
|
8981
|
+
my_network.save_edge_centroids(directory = directory)
|
|
8982
|
+
|
|
8983
|
+
except:
|
|
8984
|
+
pass
|
|
8770
8985
|
|
|
8771
8986
|
if hasattr(my_network, 'node_centroids') and my_network.node_centroids is not None:
|
|
8772
8987
|
try:
|