forked from napari/napari
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprogress_bar_segmentation_.py
167 lines (135 loc) · 5.03 KB
/
progress_bar_segmentation_.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
"""
Progress bar segmentation
=========================
Use napari's tqdm wrapper to display the progress of long-running operations
in the viewer.
.. tags:: gui
"""
import numpy as np
from qtpy.QtWidgets import QPushButton, QVBoxLayout, QWidget
from skimage.filters import (
threshold_isodata,
threshold_li,
threshold_otsu,
threshold_triangle,
threshold_yen,
)
from skimage.measure import label
import napari
from napari.utils import progress
# we will try each of these thresholds on our image
all_thresholds = [
threshold_isodata,
threshold_li,
threshold_otsu,
threshold_triangle,
threshold_yen,
]
viewer = napari.Viewer()
# load cells data and take just nuclei
membrane, cell_nuclei = viewer.open_sample('napari', 'cells3d')
cell_nuclei = cell_nuclei.data
def try_thresholds():
"""Tries each threshold, and adds result to viewer."""
if 'Binarised' in viewer.layers:
del viewer.layers['Binarised']
thresholded_nuclei = []
# we wrap our iterable with `progress`
# this will automatically add a progress bar to our activity dock
for threshold_func in progress(all_thresholds):
current_threshold = threshold_func(cell_nuclei)
binarised_im = cell_nuclei > current_threshold
thresholded_nuclei.append(binarised_im)
# uncomment if processing is too fast
# from time import sleep
# sleep(0.5)
# working with a wrapped iterable, the progress bar will be closed
# as soon as the iteration is complete
binarised_nuclei = np.stack(thresholded_nuclei)
viewer.add_labels(
binarised_nuclei,
color={1: 'lightgreen'},
opacity=0.7,
name="Binarised",
blending='translucent',
)
# In the previous example, we were able to see the progress bar, but were not
# able to control it. By using `progress` within a context manager, we can
# manipulate the `progress` object and still get the benefit of automatic
# clean up
def segment_binarised_ims():
"""Segments each of the binarised ims.
Uses `progress` within a context manager allowing us to manipulate
the progress bar within the loop
"""
if 'Binarised' not in viewer.layers:
raise TypeError("Cannot segment before thresholding")
if 'Segmented' in viewer.layers:
del viewer.layers['Segmented']
binarised_data = viewer.layers['Binarised'].data
segmented_nuclei = []
# using the `with` keyword we can use `progress` inside a context manager
# `progress` inherits from tqdm and therefore provides the same API
# e.g. we can provide the miniters argument if we want to see the
# progress bar update with each iteration
with progress(binarised_data, miniters=0) as pbar:
for i, binarised_cells in enumerate(pbar):
# this allows us to manipulate the pbar object within the loop
# e.g. setting the description.
pbar.set_description(all_thresholds[i].__name__.split("_")[1])
labelled_im = label(binarised_cells)
segmented_nuclei.append(labelled_im)
# uncomment if processing is too fast
# from time import sleep
# sleep(0.5)
# progress bar is still automatically closed
segmented_nuclei = np.stack(segmented_nuclei)
viewer.add_labels(
segmented_nuclei,
name="Segmented",
blending='translucent',
)
viewer.layers['Binarised'].visible = False
# we can also manually control `progress` objects using their
# `update` method (inherited from tqdm)
def process_ims():
"""
First performs thresholding, then segmentation on our image.
Manually updates a `progress` object.
"""
if 'Binarised' in viewer.layers:
del viewer.layers['Binarised']
if 'Segmented' in viewer.layers:
del viewer.layers['Segmented']
# we instantiate a manually controlled `progress` object
# by just passing a total with no iterable
with progress(total=2) as pbar:
pbar.set_description("Thresholding")
try_thresholds()
# once one processing step is complete, we increment
# the value of our progress bar
pbar.update(1)
pbar.set_description("Segmenting")
segment_binarised_ims()
pbar.update(1)
# uncomment this line to see the 100% progress bar
# from time import sleep
# sleep(0.5)
button_layout = QVBoxLayout()
process_btn = QPushButton("Full Process")
process_btn.clicked.connect(process_ims)
button_layout.addWidget(process_btn)
thresh_btn = QPushButton("1.Threshold")
thresh_btn.clicked.connect(try_thresholds)
button_layout.addWidget(thresh_btn)
segment_btn = QPushButton("2.Segment")
segment_btn.clicked.connect(segment_binarised_ims)
button_layout.addWidget(segment_btn)
action_widget = QWidget()
action_widget.setLayout(button_layout)
action_widget.setObjectName("Segmentation")
viewer.window.add_dock_widget(action_widget)
# showing the activity dock so we can see the progress bars
viewer.window._status_bar._toggle_activity_dock(True)
if __name__ == '__main__':
napari.run()