cellects 0.1.0.dev1__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.
- cellects/__init__.py +0 -0
- cellects/__main__.py +49 -0
- cellects/config/__init__.py +0 -0
- cellects/config/all_vars_dict.py +154 -0
- cellects/core/__init__.py +0 -0
- cellects/core/cellects_paths.py +30 -0
- cellects/core/cellects_threads.py +1464 -0
- cellects/core/motion_analysis.py +1931 -0
- cellects/core/one_image_analysis.py +1065 -0
- cellects/core/one_video_per_blob.py +679 -0
- cellects/core/program_organizer.py +1347 -0
- cellects/core/script_based_run.py +154 -0
- cellects/gui/__init__.py +0 -0
- cellects/gui/advanced_parameters.py +1258 -0
- cellects/gui/cellects.py +189 -0
- cellects/gui/custom_widgets.py +789 -0
- cellects/gui/first_window.py +449 -0
- cellects/gui/if_several_folders_window.py +239 -0
- cellects/gui/image_analysis_window.py +1909 -0
- cellects/gui/required_output.py +232 -0
- cellects/gui/video_analysis_window.py +656 -0
- cellects/icons/__init__.py +0 -0
- cellects/icons/cellects_icon.icns +0 -0
- cellects/icons/cellects_icon.ico +0 -0
- cellects/image_analysis/__init__.py +0 -0
- cellects/image_analysis/cell_leaving_detection.py +54 -0
- cellects/image_analysis/cluster_flux_study.py +102 -0
- cellects/image_analysis/extract_exif.py +61 -0
- cellects/image_analysis/fractal_analysis.py +184 -0
- cellects/image_analysis/fractal_functions.py +108 -0
- cellects/image_analysis/image_segmentation.py +272 -0
- cellects/image_analysis/morphological_operations.py +867 -0
- cellects/image_analysis/network_functions.py +1244 -0
- cellects/image_analysis/one_image_analysis_threads.py +289 -0
- cellects/image_analysis/progressively_add_distant_shapes.py +246 -0
- cellects/image_analysis/shape_descriptors.py +981 -0
- cellects/utils/__init__.py +0 -0
- cellects/utils/formulas.py +881 -0
- cellects/utils/load_display_save.py +1016 -0
- cellects/utils/utilitarian.py +516 -0
- cellects-0.1.0.dev1.dist-info/LICENSE.odt +0 -0
- cellects-0.1.0.dev1.dist-info/METADATA +131 -0
- cellects-0.1.0.dev1.dist-info/RECORD +46 -0
- cellects-0.1.0.dev1.dist-info/WHEEL +5 -0
- cellects-0.1.0.dev1.dist-info/entry_points.txt +2 -0
- cellects-0.1.0.dev1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
This is the third main widget of the GUI of Cellects
|
|
4
|
+
It process the video analysis computations by running threads connected to the program_organizer,
|
|
5
|
+
especially, most computation are then processed by the MotionAnalysis class
|
|
6
|
+
"""
|
|
7
|
+
import logging
|
|
8
|
+
import numpy as np
|
|
9
|
+
import cv2
|
|
10
|
+
from PySide6 import QtWidgets, QtCore
|
|
11
|
+
|
|
12
|
+
from cellects.core.cellects_threads import (
|
|
13
|
+
RunAllThread, OneArenaThread, VideoReaderThread, ChangeOneRepResultThread,
|
|
14
|
+
WriteVideoThread)
|
|
15
|
+
from cellects.gui.custom_widgets import (
|
|
16
|
+
MainTabsType, InsertImage, FullScreenImage, PButton, Spinbox,
|
|
17
|
+
Combobox, Checkbox, FixedText)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class VideoAnalysisWindow(MainTabsType):
|
|
21
|
+
def __init__(self, parent, night_mode):
|
|
22
|
+
super().__init__(parent, night_mode)
|
|
23
|
+
logging.info("Initialize VideoAnalysisWindow")
|
|
24
|
+
self.setParent(parent)
|
|
25
|
+
self.data_tab.set_not_in_use()
|
|
26
|
+
self.image_tab.set_not_usable()
|
|
27
|
+
self.video_tab.set_in_use()
|
|
28
|
+
self.data_tab.clicked.connect(self.data_tab_is_clicked)
|
|
29
|
+
self.image_tab.clicked.connect(self.image_tab_is_clicked)
|
|
30
|
+
self.thread = {}
|
|
31
|
+
self.thread['VideoReader'] = VideoReaderThread(self.parent())
|
|
32
|
+
self.thread['OneArena'] = OneArenaThread(self.parent())
|
|
33
|
+
self.thread['ChangeOneRepResult'] = ChangeOneRepResultThread(self.parent())
|
|
34
|
+
self.thread['RunAll'] = RunAllThread(self.parent())
|
|
35
|
+
self.previous_arena = 0
|
|
36
|
+
|
|
37
|
+
self.layout = QtWidgets.QGridLayout()
|
|
38
|
+
self.grid_widget = QtWidgets.QWidget()
|
|
39
|
+
|
|
40
|
+
# self.title = FixedText('Video tracking', police=30, night_mode=self.parent().po.all['night_mode'])
|
|
41
|
+
# self.title.setAlignment(QtCore.Qt.AlignHCenter)
|
|
42
|
+
curr_row_main_layout = 0
|
|
43
|
+
ncol = 1
|
|
44
|
+
# self.layout.addWidget(self.title, curr_row_main_layout, 0, 2, ncol)
|
|
45
|
+
# curr_row_main_layout += 2
|
|
46
|
+
self.layout.addItem(self.vertical_space, curr_row_main_layout, 0, 1, ncol)
|
|
47
|
+
curr_row_main_layout += 1
|
|
48
|
+
#
|
|
49
|
+
# self.layout.addWidget(self.arena_widget, curr_row_main_layout, 0)
|
|
50
|
+
# curr_row_main_layout += 1
|
|
51
|
+
|
|
52
|
+
# Open subtitle
|
|
53
|
+
self.general_step_widget = QtWidgets.QWidget()
|
|
54
|
+
self.general_step_layout = QtWidgets.QHBoxLayout()
|
|
55
|
+
self.current_step = 0
|
|
56
|
+
self.general_step_label = FixedText('Step 1: Tune parameters to improve Detection', night_mode=self.parent().po.all['night_mode'])
|
|
57
|
+
self.general_step_button = PButton('Done', night_mode=self.parent().po.all['night_mode'])
|
|
58
|
+
self.general_step_button.clicked.connect(self.step_done_is_clicked)
|
|
59
|
+
self.general_step_layout.addItem(self.horizontal_space)
|
|
60
|
+
self.general_step_layout.addWidget(self.general_step_label)
|
|
61
|
+
self.general_step_layout.addWidget(self.general_step_button)
|
|
62
|
+
self.general_step_layout.addItem(self.horizontal_space)
|
|
63
|
+
self.general_step_widget.setLayout(self.general_step_layout)
|
|
64
|
+
self.layout.addWidget(self.general_step_widget, curr_row_main_layout, 0, 1, ncol)
|
|
65
|
+
curr_row_main_layout += 1
|
|
66
|
+
|
|
67
|
+
# Open central widget
|
|
68
|
+
self.video_display_widget = QtWidgets.QWidget()
|
|
69
|
+
self.video_display_layout = QtWidgets.QHBoxLayout()
|
|
70
|
+
self.video_display_layout.addItem(self.horizontal_space)
|
|
71
|
+
# Open left widget
|
|
72
|
+
self.left_options_widget = QtWidgets.QWidget()
|
|
73
|
+
self.left_options_layout = QtWidgets.QVBoxLayout()
|
|
74
|
+
self.left_options_widget.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
75
|
+
# self.left_options_widget.setFixedWidth(420)
|
|
76
|
+
|
|
77
|
+
self.arena_widget = QtWidgets.QWidget()
|
|
78
|
+
self.arena_layout = QtWidgets.QHBoxLayout()
|
|
79
|
+
self.arena_label = FixedText('Arena to analyze:',
|
|
80
|
+
tip="Among selected folders, choose a arena from the first folder\nThen, click on *Quick (or *Full) detection* to load and analyse one arena\nFinally, click on *Read* to see the resulting analysis\n\nSupplementary information:\nLoading will be faster if videos are already saved as ind_*.npy\n*Post processing* automatically runs *Detection* and *Detection* automatically runs *Load One arena*\nEach being faster than the previous one",
|
|
81
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
82
|
+
# if isinstance(self.parent().po.all['sample_number_per_folder'], int):
|
|
83
|
+
# self.parent().po.all['folder_number'] = 1
|
|
84
|
+
# if self.parent().po.all['folder_number'] > 1:
|
|
85
|
+
# sample_size = self.parent().po.all['sample_number_per_folder']
|
|
86
|
+
# else:
|
|
87
|
+
sample_size = self.parent().po.all['sample_number_per_folder'][0]
|
|
88
|
+
if self.parent().po.all['arena'] > sample_size:
|
|
89
|
+
self.parent().po.all['arena'] = 1
|
|
90
|
+
|
|
91
|
+
self.arena = Spinbox(min=1, max=1000000, val=self.parent().po.all['arena'],
|
|
92
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
93
|
+
self.arena.valueChanged.connect(self.arena_changed)
|
|
94
|
+
|
|
95
|
+
# self.arena_layout.addItem(self.horizontal_space)
|
|
96
|
+
self.arena_layout.addWidget(self.arena_label)
|
|
97
|
+
self.arena_layout.addWidget(self.arena)
|
|
98
|
+
# self.arena_layout.addItem(self.horizontal_space)
|
|
99
|
+
self.arena_widget.setLayout(self.arena_layout)
|
|
100
|
+
# self.arena_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
101
|
+
self.left_options_layout.addWidget(self.arena_widget)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
self.growth_per_frame_widget = QtWidgets.QWidget()
|
|
105
|
+
self.growth_per_frame_layout = QtWidgets.QHBoxLayout()
|
|
106
|
+
try:
|
|
107
|
+
self.parent().po.vars['maximal_growth_factor']
|
|
108
|
+
except KeyError:
|
|
109
|
+
self.parent().po.vars['maximal_growth_factor'] = 0.02
|
|
110
|
+
self.parent().po.vars['repeat_video_smoothing'] = self.parent().po.vars['iterate_smoothing']
|
|
111
|
+
self.maximal_growth_factor = Spinbox(min=0, max=0.5, val=self.parent().po.vars['maximal_growth_factor'],
|
|
112
|
+
decimals=3, night_mode=self.parent().po.all['night_mode'])
|
|
113
|
+
self.maximal_growth_factor_label = FixedText('Maximal growth factor:',
|
|
114
|
+
tip="This factor should be tried and increased (resp. decreases)\nif the analysis underestimates (resp. overestimates) the cell size.\nThe maximal growth factor is a proportion of pixels in the image. \nIt tells Cellects how much the cell(s) can possibly move or grow from one image to the next.\nIn other words, this is the upper limit of the proportion of the image\nthat can change from being the background to being covered by the cell(s).",
|
|
115
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
116
|
+
self.maximal_growth_factor.valueChanged.connect(self.maximal_growth_factor_changed)
|
|
117
|
+
self.growth_per_frame_layout.addWidget(self.maximal_growth_factor_label)
|
|
118
|
+
self.growth_per_frame_layout.addWidget(self.maximal_growth_factor)
|
|
119
|
+
# self.growth_per_frame_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
120
|
+
self.growth_per_frame_widget.setLayout(self.growth_per_frame_layout)
|
|
121
|
+
self.left_options_layout.addWidget(self.growth_per_frame_widget)
|
|
122
|
+
|
|
123
|
+
self.iterate_widget = QtWidgets.QWidget()
|
|
124
|
+
self.iterate_layout = QtWidgets.QHBoxLayout()
|
|
125
|
+
self.repeat_video_smoothing = Spinbox(min=0, max=10, val=self.parent().po.vars['repeat_video_smoothing'],
|
|
126
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
127
|
+
self.repeat_video_smoothing_label = FixedText('Repeat video smoothing:',
|
|
128
|
+
tip="Increase (with steps of 1) if video noise is the source of detection failure",
|
|
129
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
130
|
+
self.repeat_video_smoothing.valueChanged.connect(self.repeat_video_smoothing_changed)
|
|
131
|
+
self.iterate_layout.addWidget(self.repeat_video_smoothing_label)
|
|
132
|
+
self.iterate_layout.addWidget(self.repeat_video_smoothing)
|
|
133
|
+
# self.iterate_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
134
|
+
self.iterate_widget.setLayout(self.iterate_layout)
|
|
135
|
+
self.left_options_layout.addWidget(self.iterate_widget)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
self.select_option_label = FixedText('Segmentation method:',
|
|
139
|
+
tip='Select the option allowing the best cell delimitation.',
|
|
140
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
141
|
+
self.select_option = Combobox([], night_mode=self.parent().po.all['night_mode'])
|
|
142
|
+
self.select_option_label.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
143
|
+
self.select_option.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
144
|
+
self.select_option.setFixedWidth(175)
|
|
145
|
+
# self.select_option_label.setFixedWidth(265)
|
|
146
|
+
# self.select_option.setFixedWidth(150)
|
|
147
|
+
self.select_option.addItem("1. Frame by frame")
|
|
148
|
+
self.select_option.addItem("2. Dynamical threshold")
|
|
149
|
+
self.select_option.addItem("3. Dynamical slope")
|
|
150
|
+
self.select_option.addItem("4. Threshold and Slope")
|
|
151
|
+
self.select_option.addItem("5. Threshold or Slope")
|
|
152
|
+
# for option in range(5):
|
|
153
|
+
# self.select_option.addItem(f"Option {option + 1}")
|
|
154
|
+
self.select_option.setCurrentIndex(self.parent().po.all['video_option'])
|
|
155
|
+
self.select_option.currentTextChanged.connect(self.option_changed)
|
|
156
|
+
# self.select_option_label.setVisible(self.parent().po.vars["color_number"] == 2)
|
|
157
|
+
# self.select_option.setVisible(self.parent().po.vars["color_number"] == 2)
|
|
158
|
+
|
|
159
|
+
# Open the choose best option row layout
|
|
160
|
+
self.options_row_widget = QtWidgets.QWidget()
|
|
161
|
+
self.options_row_layout = QtWidgets.QHBoxLayout()
|
|
162
|
+
# self.options_row_layout.addItem(self.horizontal_space)
|
|
163
|
+
self.options_row_layout.addWidget(self.select_option_label)
|
|
164
|
+
self.options_row_layout.addWidget(self.select_option)
|
|
165
|
+
# self.options_row_layout.addItem(self.horizontal_space)
|
|
166
|
+
self.options_row_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
167
|
+
self.options_row_layout.setAlignment(QtCore.Qt.AlignVCenter)
|
|
168
|
+
self.options_row_widget.setLayout(self.options_row_layout)
|
|
169
|
+
self.left_options_layout.addWidget(self.options_row_widget)
|
|
170
|
+
|
|
171
|
+
# Close left widget
|
|
172
|
+
self.left_options_widget.setLayout(self.left_options_layout)
|
|
173
|
+
self.video_display_layout.addWidget(self.left_options_widget)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# Add the central video display widget
|
|
177
|
+
self.display_image = np.zeros((self.parent().im_max_height, self.parent().im_max_width, 3), np.uint8)
|
|
178
|
+
self.display_image = InsertImage(self.display_image, self.parent().im_max_height, self.parent().im_max_width)
|
|
179
|
+
self.display_image.mousePressEvent = self.full_screen_display
|
|
180
|
+
self.video_display_layout.addWidget(self.display_image)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# Open right widget
|
|
184
|
+
self.right_options_widget = QtWidgets.QWidget()
|
|
185
|
+
self.right_options_layout = QtWidgets.QVBoxLayout()
|
|
186
|
+
self.right_options_widget.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
187
|
+
# self.right_options_widget.setFixedWidth(420)
|
|
188
|
+
|
|
189
|
+
self.compute_all_options_label = FixedText('Compute all options',
|
|
190
|
+
tip='Uncheck to do a Post processing on only one option and earn computation time\nSelecting one of the remaining options will display the result from a Detection',
|
|
191
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
192
|
+
self.compute_all_options_cb = Checkbox(self.parent().po.all['compute_all_options'])
|
|
193
|
+
self.compute_all_options_cb.setStyleSheet("margin-left:0%; margin-right:0%;")
|
|
194
|
+
self.compute_all_options_cb.stateChanged.connect(self.compute_all_options_check)
|
|
195
|
+
self.all_options_row_widget = QtWidgets.QWidget()
|
|
196
|
+
self.all_options_row_layout = QtWidgets.QHBoxLayout()
|
|
197
|
+
self.all_options_row_layout.addWidget(self.compute_all_options_cb)
|
|
198
|
+
self.all_options_row_layout.addWidget(self.compute_all_options_label)
|
|
199
|
+
self.all_options_row_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
200
|
+
self.all_options_row_layout.setAlignment(QtCore.Qt.AlignVCenter)
|
|
201
|
+
self.all_options_row_widget.setLayout(self.all_options_row_layout)
|
|
202
|
+
self.right_options_layout.addWidget(self.all_options_row_widget)
|
|
203
|
+
|
|
204
|
+
self.load_one_arena = PButton('Load One arena', night_mode=self.parent().po.all['night_mode'])
|
|
205
|
+
self.load_one_arena.clicked.connect(self.load_one_arena_is_clicked)
|
|
206
|
+
self.detection = PButton('Detection', night_mode=self.parent().po.all['night_mode'])
|
|
207
|
+
self.detection.clicked.connect(self.detection_is_clicked)
|
|
208
|
+
self.read = PButton('Read', night_mode=self.parent().po.all['night_mode'])
|
|
209
|
+
self.read.clicked.connect(self.read_is_clicked)
|
|
210
|
+
self.read.setVisible(False)
|
|
211
|
+
self.right_options_layout.addWidget(self.load_one_arena, alignment=QtCore.Qt.AlignCenter)
|
|
212
|
+
self.right_options_layout.addWidget(self.detection, alignment=QtCore.Qt.AlignCenter)
|
|
213
|
+
self.right_options_layout.addWidget(self.read, alignment=QtCore.Qt.AlignCenter)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
self.right_options_layout.addItem(self.horizontal_space)
|
|
217
|
+
self.right_options_widget.setLayout(self.right_options_layout)
|
|
218
|
+
self.video_display_layout.addWidget(self.right_options_widget)
|
|
219
|
+
self.video_display_layout.addItem(self.horizontal_space)
|
|
220
|
+
# Close central widget
|
|
221
|
+
self.video_display_widget.setLayout(self.video_display_layout)
|
|
222
|
+
# self.video_display_widget.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
|
|
223
|
+
# self.video_display_widget.setAlignment(QtCore.Qt.AlignHCenter)
|
|
224
|
+
# self.video_display_widget.setFixedHeight(500)
|
|
225
|
+
self.layout.addWidget(self.video_display_widget, curr_row_main_layout, 0)
|
|
226
|
+
curr_row_main_layout += 1
|
|
227
|
+
|
|
228
|
+
# Open Second step row
|
|
229
|
+
self.second_step_widget = QtWidgets.QWidget()
|
|
230
|
+
self.second_step_layout = QtWidgets.QHBoxLayout()
|
|
231
|
+
self.second_step_layout.addItem(self.horizontal_space)
|
|
232
|
+
self.second_step_widget.setVisible(False)
|
|
233
|
+
|
|
234
|
+
self.fading_widget = QtWidgets.QWidget()
|
|
235
|
+
self.fading_layout = QtWidgets.QHBoxLayout()
|
|
236
|
+
self.do_fading = Checkbox(self.parent().po.vars['do_fading'])
|
|
237
|
+
self.do_fading.setStyleSheet("margin-left:0%; margin-right:0%;")
|
|
238
|
+
self.do_fading.stateChanged.connect(self.do_fading_check)
|
|
239
|
+
self.fading = Spinbox(min=- 1, max=1, val=self.parent().po.vars['fading'], decimals=2,
|
|
240
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
241
|
+
self.fading_label = FixedText('Fading detection',
|
|
242
|
+
tip="Set a value between -1 and 1\nnear - 1: it will never detect when the cell leaves an area\nnear 1: it may stop detecting cell (because cell will be considered left from any area)",
|
|
243
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
244
|
+
self.fading.valueChanged.connect(self.fading_changed)
|
|
245
|
+
# self.fading.setVisible(self.parent().po.vars['do_fading'])
|
|
246
|
+
self.fading_layout.addWidget(self.do_fading)
|
|
247
|
+
self.fading_layout.addWidget(self.fading_label)
|
|
248
|
+
self.fading_layout.addWidget(self.fading)
|
|
249
|
+
self.fading_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
250
|
+
self.fading_widget.setLayout(self.fading_layout)
|
|
251
|
+
self.second_step_layout.addWidget(self.fading_widget)
|
|
252
|
+
|
|
253
|
+
self.post_processing = PButton('Post processing', night_mode=self.parent().po.all['night_mode'])
|
|
254
|
+
self.post_processing.clicked.connect(self.post_processing_is_clicked)
|
|
255
|
+
self.second_step_layout.addWidget(self.post_processing)
|
|
256
|
+
# self.second_step_layout.addWidget(self.post_processing, alignment=QtCore.Qt.AlignCenter)
|
|
257
|
+
|
|
258
|
+
self.save_one_result = PButton('Save One Result', night_mode=self.parent().po.all['night_mode'])
|
|
259
|
+
self.save_one_result.clicked.connect(self.save_one_result_is_clicked)
|
|
260
|
+
self.second_step_layout.addWidget(self.save_one_result)
|
|
261
|
+
# self.second_step_layout.addWidget(self.save_one_result, alignment=QtCore.Qt.AlignCenter)
|
|
262
|
+
|
|
263
|
+
# Close Second step row
|
|
264
|
+
self.second_step_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
265
|
+
self.second_step_layout.addItem(self.horizontal_space)
|
|
266
|
+
self.second_step_widget.setLayout(self.second_step_layout)
|
|
267
|
+
self.layout.addItem(self.vertical_space, curr_row_main_layout, 0, 1, ncol)
|
|
268
|
+
curr_row_main_layout += 1
|
|
269
|
+
self.layout.addWidget(self.second_step_widget, curr_row_main_layout, 0)
|
|
270
|
+
curr_row_main_layout += 1
|
|
271
|
+
|
|
272
|
+
# Open last options row widget
|
|
273
|
+
self.last_options_widget = QtWidgets.QWidget()
|
|
274
|
+
self.last_options_layout = QtWidgets.QHBoxLayout()
|
|
275
|
+
self.last_options_layout.addItem(self.horizontal_space)
|
|
276
|
+
|
|
277
|
+
# # advanced mode widget
|
|
278
|
+
# self.advanced_mode_widget = QtWidgets.QWidget()
|
|
279
|
+
# self.advanced_mode_layout = QtWidgets.QHBoxLayout()
|
|
280
|
+
# advanced_mode = self.parent().po.all['expert_mode']
|
|
281
|
+
# self.advanced_mode_cb = Checkbox(self.parent().po.all['expert_mode'])
|
|
282
|
+
# self.advanced_mode_cb.setStyleSheet("margin-left:0%; margin-right:0%;")
|
|
283
|
+
# self.advanced_mode_cb.stateChanged.connect(self.advanced_mode_check)
|
|
284
|
+
# self.advanced_mode_label = FixedText('Go to step 2 directly', align='l',
|
|
285
|
+
# tip="Allow the user to try Post processing before having tuned the parameters related to Detection.",
|
|
286
|
+
# night_mode=self.parent().po.all['night_mode'])
|
|
287
|
+
# # self.advanced_mode_label.setAlignment(QtCore.Qt.AlignTop)
|
|
288
|
+
# self.advanced_mode_layout.addWidget(self.advanced_mode_cb)
|
|
289
|
+
# self.advanced_mode_layout.addWidget(self.advanced_mode_label)
|
|
290
|
+
# self.advanced_mode_layout.addItem(self.horizontal_space)
|
|
291
|
+
# self.advanced_mode_layout.setAlignment(QtCore.Qt.AlignHCenter)
|
|
292
|
+
# self.advanced_mode_widget.setLayout(self.advanced_mode_layout)
|
|
293
|
+
# self.last_options_layout.addWidget(self.advanced_mode_widget)
|
|
294
|
+
|
|
295
|
+
self.advanced_parameters = PButton('Advanced Parameters', night_mode=self.parent().po.all['night_mode'])
|
|
296
|
+
self.advanced_parameters.clicked.connect(self.advanced_parameters_is_clicked)
|
|
297
|
+
self.last_options_layout.addWidget(self.advanced_parameters)
|
|
298
|
+
|
|
299
|
+
# Required Outputs widget
|
|
300
|
+
self.required_outputs = PButton('Required Outputs', night_mode=self.parent().po.all['night_mode'])
|
|
301
|
+
self.required_outputs.clicked.connect(self.required_outputs_is_clicked)
|
|
302
|
+
self.last_options_layout.addWidget(self.required_outputs)
|
|
303
|
+
|
|
304
|
+
# Save all choices widget
|
|
305
|
+
self.save_all_vars = PButton('Save all choices', night_mode=self.parent().po.all['night_mode'])
|
|
306
|
+
self.save_all_vars.clicked.connect(self.save_current_settings)
|
|
307
|
+
self.last_options_layout.addWidget(self.save_all_vars)
|
|
308
|
+
|
|
309
|
+
# Close last options widget
|
|
310
|
+
self.last_options_layout.addItem(self.horizontal_space)
|
|
311
|
+
self.last_options_widget.setLayout(self.last_options_layout)
|
|
312
|
+
self.layout.addWidget(self.last_options_widget, curr_row_main_layout, 0)
|
|
313
|
+
curr_row_main_layout += 1
|
|
314
|
+
|
|
315
|
+
self.message = QtWidgets.QLabel(self)
|
|
316
|
+
self.message.setText('')
|
|
317
|
+
self.message.setStyleSheet("color: rgb(230, 145, 18)")
|
|
318
|
+
self.message.setAlignment(QtCore.Qt.AlignLeft)
|
|
319
|
+
|
|
320
|
+
self.previous = PButton('Previous', night_mode=self.parent().po.all['night_mode'])
|
|
321
|
+
self.previous.clicked.connect(self.previous_is_clicked)
|
|
322
|
+
|
|
323
|
+
self.run_all = PButton('Run All', night_mode=self.parent().po.all['night_mode'])
|
|
324
|
+
self.run_all.clicked.connect(self.run_all_is_clicked)
|
|
325
|
+
|
|
326
|
+
# Open last row widget
|
|
327
|
+
self.last_row_widget = QtWidgets.QWidget()
|
|
328
|
+
self.last_row_layout = QtWidgets.QHBoxLayout()
|
|
329
|
+
self.last_row_layout.addWidget(self.previous)
|
|
330
|
+
self.last_row_layout.addItem(self.horizontal_space)
|
|
331
|
+
self.last_row_layout.addWidget(self.message)
|
|
332
|
+
self.last_row_layout.addWidget(self.run_all)
|
|
333
|
+
# Close last row widget
|
|
334
|
+
self.last_row_widget.setLayout(self.last_row_layout)
|
|
335
|
+
self.layout.addItem(self.vertical_space, curr_row_main_layout, 0, 1, ncol)
|
|
336
|
+
self.layout.addWidget(self.last_row_widget, curr_row_main_layout, 0)
|
|
337
|
+
|
|
338
|
+
self.grid_widget.setLayout(self.layout)
|
|
339
|
+
self.Vlayout.addItem(self.vertical_space)
|
|
340
|
+
self.Vlayout.addWidget(self.grid_widget)
|
|
341
|
+
self.setLayout(self.Vlayout)
|
|
342
|
+
# self.advanced_mode_check()
|
|
343
|
+
|
|
344
|
+
def display_conditionally_visible_widgets(self):
|
|
345
|
+
self.select_option_label.setVisible(self.parent().po.vars["color_number"] == 2)
|
|
346
|
+
self.select_option.setVisible(self.parent().po.vars["color_number"] == 2)
|
|
347
|
+
self.fading.setVisible(self.parent().po.vars['do_fading'])
|
|
348
|
+
|
|
349
|
+
def step_done_is_clicked(self):
|
|
350
|
+
self.current_step += 1
|
|
351
|
+
if self.current_step == 1:
|
|
352
|
+
self.general_step_label.setText('Step 2: Tune fading and advanced parameters to improve Post processing')
|
|
353
|
+
self.general_step_label.setToolTip('Post processing is slower than Detection.\nIt improves detection with the following optional algorithms:\n - Fading detection\n - Correct errors around initial shape\n - Organism internal oscillation period\n - Connect distant shape\n - Appearing cell selection')
|
|
354
|
+
self.second_step_widget.setVisible(True)
|
|
355
|
+
self.fading.setVisible(self.parent().po.vars['do_fading'])
|
|
356
|
+
self.save_one_result.setVisible(False)
|
|
357
|
+
elif self.current_step == 2:
|
|
358
|
+
self.general_step_label.setText('Step 3: Run the full analysis or save the result of one arena.')
|
|
359
|
+
self.general_step_label.setToolTip('Once all settings are correct for a arena, click on "Run All" to start the full analysis.\nIf the detection is unsatisfactory for a arena, you can repeat the detection for this\narena and save the results by clicking "Save One Result".\nRepeat the process for as many arenas as necessary.')
|
|
360
|
+
self.save_one_result.setVisible(True)
|
|
361
|
+
self.general_step_button.setVisible(False)
|
|
362
|
+
|
|
363
|
+
def reset_general_step(self):
|
|
364
|
+
self.current_step = 0
|
|
365
|
+
self.general_step_label.setText('Step 1: Tune parameters to improve Detection')
|
|
366
|
+
self.general_step_label.setToolTip('Detection uses only the visible parameters and those\npreviously determined on the first or last image.')
|
|
367
|
+
self.general_step_button.setVisible(True)
|
|
368
|
+
self.second_step_widget.setVisible(False)
|
|
369
|
+
|
|
370
|
+
def full_screen_display(self, event):
|
|
371
|
+
self.popup_img = FullScreenImage(self.parent().image_to_display, self.parent().screen_width, self.parent().screen_height)
|
|
372
|
+
self.popup_img.show()
|
|
373
|
+
|
|
374
|
+
def option_changed(self):
|
|
375
|
+
"""
|
|
376
|
+
Update the video, save parameters
|
|
377
|
+
:return:
|
|
378
|
+
"""
|
|
379
|
+
self.parent().po.all['video_option'] = self.select_option.currentIndex()
|
|
380
|
+
self.parent().po.vars['frame_by_frame_segmentation'] = False
|
|
381
|
+
self.parent().po.vars['do_threshold_segmentation'] = False
|
|
382
|
+
self.parent().po.vars['do_slope_segmentation'] = False
|
|
383
|
+
|
|
384
|
+
if self.parent().po.vars['color_number'] > 2 or self.parent().po.all['video_option'] == 0:
|
|
385
|
+
logging.info(f"This option will detect {self.parent().po.vars['color_number']} distinct luminosity groups for each frame.")
|
|
386
|
+
self.parent().po.vars['frame_by_frame_segmentation'] = True
|
|
387
|
+
else:
|
|
388
|
+
self.parent().po.vars['frame_by_frame_segmentation'] = False
|
|
389
|
+
if self.parent().po.all['video_option'] == 1:
|
|
390
|
+
logging.info(f"This option will detect cell(s) using a dynamic threshold algorithm with a maximal growth factor of {self.parent().po.vars['maximal_growth_factor']}")
|
|
391
|
+
self.parent().po.vars['do_threshold_segmentation'] = True
|
|
392
|
+
elif self.parent().po.all['video_option'] == 2:
|
|
393
|
+
logging.info(f"This option will detect cell(s) using a dynamic slope algorithm with a maximal growth factor of {self.parent().po.vars['maximal_growth_factor']}")
|
|
394
|
+
self.parent().po.vars['do_slope_segmentation'] = True
|
|
395
|
+
elif self.parent().po.all['video_option'] > 2:
|
|
396
|
+
self.parent().po.vars['do_threshold_segmentation'] = True
|
|
397
|
+
self.parent().po.vars['do_slope_segmentation'] = True
|
|
398
|
+
if self.parent().po.all['video_option'] == 3:
|
|
399
|
+
logging.info(f"This option will detect cell(s) using the dynamic threshold AND slope algorithms with a maximal growth factor of {self.parent().po.vars['maximal_growth_factor']}")
|
|
400
|
+
self.parent().po.vars['true_if_use_light_AND_slope_else_OR'] = True
|
|
401
|
+
elif self.parent().po.all['video_option'] == 4:
|
|
402
|
+
logging.info(f"This option will detect cell(s) using the dynamic threshold OR slope algorithms with a maximal growth factor of {self.parent().po.vars['maximal_growth_factor']}")
|
|
403
|
+
self.parent().po.vars['true_if_use_light_AND_slope_else_OR'] = False
|
|
404
|
+
# self.parent().po.motion
|
|
405
|
+
|
|
406
|
+
# def advanced_mode_check(self):
|
|
407
|
+
# advanced_mode = self.advanced_mode_cb.isChecked()
|
|
408
|
+
# self.parent().po.all['expert_mode'] = advanced_mode
|
|
409
|
+
# self.second_step_widget.setVisible(advanced_mode or self.current_step > 0)
|
|
410
|
+
# if advanced_mode:
|
|
411
|
+
# if self.current_step == 0:
|
|
412
|
+
# self.current_step += 1
|
|
413
|
+
# self.general_step_label.setText('Step 2: Tune fading and advanced parameters to improve Post processing')
|
|
414
|
+
# self.save_one_result.setVisible(self.current_step == 2)
|
|
415
|
+
|
|
416
|
+
# self.maximal_growth_factor.setVisible(advanced_mode)
|
|
417
|
+
# self.maximal_growth_factor_label.setVisible(advanced_mode)
|
|
418
|
+
# self.fading.setVisible(advanced_mode)
|
|
419
|
+
# self.fading_label.setVisible(advanced_mode)
|
|
420
|
+
# self.repeat_video_smoothing.setVisible(advanced_mode)
|
|
421
|
+
# self.repeat_video_smoothing_label.setVisible(advanced_mode)
|
|
422
|
+
|
|
423
|
+
def data_tab_is_clicked(self):
|
|
424
|
+
if self.thread['VideoReader'].isRunning() or self.thread['OneArena'].isRunning() or self.thread['ChangeOneRepResult'].isRunning() or self.parent().firstwindow.thread["RunAll"].isRunning():
|
|
425
|
+
self.message.setText("Wait for the analysis to end, or restart Cellects")
|
|
426
|
+
else:
|
|
427
|
+
self.parent().last_tab = "data_specifications"
|
|
428
|
+
self.parent().change_widget(0) # FirstWidget
|
|
429
|
+
|
|
430
|
+
def image_tab_is_clicked(self):
|
|
431
|
+
if self.image_tab.state != "not_usable":
|
|
432
|
+
if self.thread['VideoReader'].isRunning() or self.thread['OneArena'].isRunning() or self.thread[
|
|
433
|
+
'ChangeOneRepResult'].isRunning() or self.parent().firstwindow.thread["RunAll"].isRunning():
|
|
434
|
+
self.message.setText("Wait for the analysis to end, or restart Cellects")
|
|
435
|
+
else:
|
|
436
|
+
self.parent().last_tab = "video_analysis"
|
|
437
|
+
self.parent().change_widget(2)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def required_outputs_is_clicked(self):
|
|
441
|
+
self.parent().last_is_first = False
|
|
442
|
+
self.parent().change_widget(4) # RequiredOutput
|
|
443
|
+
|
|
444
|
+
def advanced_parameters_is_clicked(self):
|
|
445
|
+
self.parent().last_is_first = False
|
|
446
|
+
self.parent().widget(5).update_csc_editing_display()
|
|
447
|
+
self.parent().change_widget(5) # AdvancedParameters
|
|
448
|
+
|
|
449
|
+
def previous_is_clicked(self):
|
|
450
|
+
if self.parent().last_tab == "data_specifications":
|
|
451
|
+
self.parent().change_widget(0) # FirstWidget
|
|
452
|
+
elif self.parent().last_tab == "image_analysis":
|
|
453
|
+
self.parent().change_widget(2) # ThirdWidget
|
|
454
|
+
self.parent().last_tab = "video_analysis"
|
|
455
|
+
# self.parent().change_widget(2) # SecondWidget
|
|
456
|
+
|
|
457
|
+
def save_all_vars_thread(self):
|
|
458
|
+
if not self.parent().thread['SaveAllVars'].isRunning():
|
|
459
|
+
self.parent().thread['SaveAllVars'].start() # SaveAllVarsThreadInThirdWidget
|
|
460
|
+
|
|
461
|
+
def save_current_settings(self):
|
|
462
|
+
self.parent().po.vars['maximal_growth_factor'] = self.maximal_growth_factor.value()
|
|
463
|
+
self.parent().po.vars['repeat_video_smoothing'] = int(np.round(self.repeat_video_smoothing.value()))
|
|
464
|
+
self.parent().po.vars['do_fading'] = self.do_fading.isChecked()
|
|
465
|
+
self.parent().po.vars['fading'] = self.fading.value()
|
|
466
|
+
self.parent().po.all['compute_all_options'] = self.compute_all_options_cb.isChecked()
|
|
467
|
+
self.option_changed()
|
|
468
|
+
self.save_all_vars_thread()
|
|
469
|
+
|
|
470
|
+
def repeat_video_smoothing_changed(self):
|
|
471
|
+
self.parent().po.vars['repeat_video_smoothing'] = int(np.round(self.repeat_video_smoothing.value()))
|
|
472
|
+
# self.save_all_vars_is_clicked()
|
|
473
|
+
|
|
474
|
+
def do_fading_check(self):
|
|
475
|
+
self.parent().po.vars['do_fading'] = self.do_fading.isChecked()
|
|
476
|
+
self.fading.setVisible(self.parent().po.vars['do_fading'])
|
|
477
|
+
|
|
478
|
+
def fading_changed(self):
|
|
479
|
+
self.parent().po.vars['fading'] = self.fading.value()
|
|
480
|
+
# self.save_all_vars_is_clicked()
|
|
481
|
+
|
|
482
|
+
def maximal_growth_factor_changed(self):
|
|
483
|
+
self.parent().po.vars['maximal_growth_factor'] = self.maximal_growth_factor.value()
|
|
484
|
+
# self.save_all_vars_is_clicked()
|
|
485
|
+
|
|
486
|
+
def arena_changed(self):
|
|
487
|
+
"""
|
|
488
|
+
Put motion to None allows the class OneArenaThread to load the selected arena
|
|
489
|
+
"""
|
|
490
|
+
if not self.thread['VideoReader'].isRunning() and not self.thread['OneArena'].isRunning() and not self.thread['ChangeOneRepResult'].isRunning():
|
|
491
|
+
self.parent().po.motion = None
|
|
492
|
+
self.reset_general_step()
|
|
493
|
+
self.parent().po.computed_video_options = np.zeros(5, bool)
|
|
494
|
+
self.parent().po.all['arena'] = int(np.round(self.arena.value()))
|
|
495
|
+
|
|
496
|
+
def load_one_arena_is_clicked(self):
|
|
497
|
+
self.reset_general_step()
|
|
498
|
+
# self.save_all_vars_is_clicked()
|
|
499
|
+
self.parent().po.load_quick_full = 0
|
|
500
|
+
self.run_one_arena_thread()
|
|
501
|
+
|
|
502
|
+
def compute_all_options_check(self):
|
|
503
|
+
self.parent().po.all['compute_all_options'] = self.compute_all_options_cb.isChecked()
|
|
504
|
+
|
|
505
|
+
def detection_is_clicked(self):
|
|
506
|
+
self.reset_general_step()
|
|
507
|
+
# self.save_all_vars_is_clicked()
|
|
508
|
+
self.parent().po.load_quick_full = 1
|
|
509
|
+
self.run_one_arena_thread()
|
|
510
|
+
|
|
511
|
+
def post_processing_is_clicked(self):
|
|
512
|
+
# self.save_all_vars_is_clicked()
|
|
513
|
+
self.parent().po.load_quick_full = 2
|
|
514
|
+
logging.info(self.parent().po.vars['maximal_growth_factor'])
|
|
515
|
+
self.run_one_arena_thread()
|
|
516
|
+
|
|
517
|
+
def run_one_arena_thread(self):
|
|
518
|
+
"""
|
|
519
|
+
Make sure that the previous thread is not running and start the OneArenaThread
|
|
520
|
+
According to the button clicked, this class will only load, load and quick segment,
|
|
521
|
+
or load, quickly segment and fully detect the cell(s) dynamic
|
|
522
|
+
"""
|
|
523
|
+
if self.thread['OneArena']._isRunning:
|
|
524
|
+
self.thread['OneArena'].stop()
|
|
525
|
+
self.save_current_settings()
|
|
526
|
+
if self.previous_arena != self.parent().po.all['arena']:
|
|
527
|
+
self.parent().po.motion = None
|
|
528
|
+
self.message.setText("Load the video and initialize analysis, wait...")
|
|
529
|
+
# if not self.parent().po.first_exp_ready_to_run:
|
|
530
|
+
# self.parent().po.use_data_to_run_cellects_quickly = True
|
|
531
|
+
self.thread['OneArena'].start() # OneArenaThreadInThirdWidget
|
|
532
|
+
self.thread['OneArena'].message_from_thread_starting.connect(self.display_message_from_thread)
|
|
533
|
+
self.thread['OneArena'].when_loading_finished.connect(self.when_loading_thread_finished)
|
|
534
|
+
self.thread['OneArena'].when_detection_finished.connect(self.when_detection_finished)
|
|
535
|
+
self.thread['OneArena'].image_from_thread.connect(self.display_image_during_thread)
|
|
536
|
+
|
|
537
|
+
def when_loading_thread_finished(self, save_loaded_video):
|
|
538
|
+
self.previous_arena = self.parent().po.all['arena']
|
|
539
|
+
# if not self.parent().po.vars['already_greyscale']:
|
|
540
|
+
# self.parent().po.motion.analysis_instance = self.parent().po.motion.visu.copy()
|
|
541
|
+
# else:
|
|
542
|
+
# self.parent().po.motion.analysis_instance = self.parent().po.motion.converted_video.copy()
|
|
543
|
+
if save_loaded_video:
|
|
544
|
+
self.thread['WriteVideo'] = WriteVideoThread(self.parent())
|
|
545
|
+
self.thread['WriteVideo'].start()
|
|
546
|
+
if self.parent().po.load_quick_full == 0:
|
|
547
|
+
self.message.setText("Loading done, you can watch the video")
|
|
548
|
+
self.read.setVisible(True)
|
|
549
|
+
|
|
550
|
+
def when_detection_finished(self, message):
|
|
551
|
+
# self.option_changed()
|
|
552
|
+
self.previous_arena = self.parent().po.all['arena']
|
|
553
|
+
if self.thread['VideoReader'].isRunning(): # VideoReaderThreadInThirdWidget
|
|
554
|
+
self.thread['VideoReader'].wait()
|
|
555
|
+
if self.parent().po.load_quick_full > 0:
|
|
556
|
+
image = self.parent().po.motion.segmentation[-1, ...]
|
|
557
|
+
if self.parent().po.motion.visu is None:
|
|
558
|
+
image = self.parent().po.motion.converted_video[-1, ...] * (1 - image)
|
|
559
|
+
image = np.round(image).astype(np.uint8)
|
|
560
|
+
image = np.stack((image, image, image), axis=2)
|
|
561
|
+
else:
|
|
562
|
+
image = np.stack((image, image, image), axis=2)
|
|
563
|
+
image = self.parent().po.motion.visu[-1, ...] * (1 - image)
|
|
564
|
+
self.parent().image_to_display = image
|
|
565
|
+
self.display_image.update_image(image)
|
|
566
|
+
|
|
567
|
+
self.message.setText(message)
|
|
568
|
+
|
|
569
|
+
self.select_option_label.setVisible(self.parent().po.vars["color_number"] == 2)
|
|
570
|
+
self.select_option.setVisible(self.parent().po.vars["color_number"] == 2)
|
|
571
|
+
self.read.setVisible(True)
|
|
572
|
+
# self.save_one_result.setVisible(True)
|
|
573
|
+
|
|
574
|
+
def display_image_during_thread(self, dictionary):
|
|
575
|
+
self.message.setText(dictionary['message'])
|
|
576
|
+
self.parent().image_to_display = dictionary['current_image']
|
|
577
|
+
self.display_image.update_image(dictionary['current_image'])
|
|
578
|
+
|
|
579
|
+
def save_one_result_is_clicked(self):
|
|
580
|
+
if self.parent().po.motion is not None:
|
|
581
|
+
if self.parent().po.load_quick_full == 2:
|
|
582
|
+
if not self.thread['OneArena'].isRunning() and not self.thread['ChangeOneRepResult'].isRunning():
|
|
583
|
+
self.message.setText(f"Arena {self.parent().po.all['arena']}: Finalize analysis and save, wait...")
|
|
584
|
+
self.thread['ChangeOneRepResult'].start() # ChangeOneRepResultThreadInThirdWidget
|
|
585
|
+
self.thread['ChangeOneRepResult'].message_from_thread.connect(self.display_message_from_thread)
|
|
586
|
+
self.message.setText("Complete analysis + change that result")
|
|
587
|
+
else:
|
|
588
|
+
self.message.setText("Wait for the analysis to end")
|
|
589
|
+
else:
|
|
590
|
+
self.message.setText("Run Post processing first")
|
|
591
|
+
else:
|
|
592
|
+
self.message.setText("Run Post processing first")
|
|
593
|
+
|
|
594
|
+
def read_is_clicked(self):
|
|
595
|
+
if self.parent().po.motion is not None:
|
|
596
|
+
if self.parent().po.motion.segmentation is not None:
|
|
597
|
+
if not self.thread['OneArena'].isRunning() and not self.thread['VideoReader'].isRunning():
|
|
598
|
+
self.thread['VideoReader'].start() # VideoReaderThreadInThirdWidget
|
|
599
|
+
self.thread['VideoReader'].message_from_thread.connect(self.display_image_during_thread)
|
|
600
|
+
# if self.parent().po.computed_video_options[self.parent().po.all['video_option']]:
|
|
601
|
+
# self.message.setText("Run detection to visualize analysis")
|
|
602
|
+
else:
|
|
603
|
+
self.message.setText("Wait for the analysis to end")
|
|
604
|
+
else:
|
|
605
|
+
self.message.setText("Run detection first")
|
|
606
|
+
else:
|
|
607
|
+
self.message.setText("Run detection first")
|
|
608
|
+
#
|
|
609
|
+
# def video_display(self, dictionary):
|
|
610
|
+
# self.drawn_image = dictionary['image']
|
|
611
|
+
# self.display_image.update_image(dictionary['image'], self.parent().po.vars['contour_color'])
|
|
612
|
+
# self.message.setText(dictionary['message'])
|
|
613
|
+
# # self.message.setText(f"Reading done, try to change parameters if necessary")
|
|
614
|
+
|
|
615
|
+
def run_all_is_clicked(self):
|
|
616
|
+
if self.thread['OneArena'].isRunning() or self.thread['ChangeOneRepResult'].isRunning():
|
|
617
|
+
self.message.setText("Wait for the current analysis to end")
|
|
618
|
+
else:
|
|
619
|
+
if self.thread['VideoReader'].isRunning():
|
|
620
|
+
self.thread['VideoReader'].wait()
|
|
621
|
+
# self.save_all_vars_is_clicked()
|
|
622
|
+
# self.save_current_settings()
|
|
623
|
+
if self.parent().firstwindow.thread["RunAll"].isRunning():
|
|
624
|
+
self.message.setText('Analysis has already begun in the first window.')
|
|
625
|
+
else:
|
|
626
|
+
if not self.thread['RunAll'].isRunning():
|
|
627
|
+
# self.save_all_vars_is_clicked()
|
|
628
|
+
self.save_current_settings()
|
|
629
|
+
self.parent().po.motion = None
|
|
630
|
+
self.parent().po.converted_video = None
|
|
631
|
+
self.parent().po.converted_video2 = None
|
|
632
|
+
self.parent().po.visu = None
|
|
633
|
+
self.message.setText("Complete analysis has started, wait...")
|
|
634
|
+
# if not self.parent().po.first_exp_ready_to_run:
|
|
635
|
+
# self.parent().po.use_data_to_run_cellects_quickly = True
|
|
636
|
+
self.thread['RunAll'].start() # RunAllThread
|
|
637
|
+
self.thread['RunAll'].message_from_thread.connect(self.display_message_from_thread)
|
|
638
|
+
self.thread['RunAll'].image_from_thread.connect(self.display_image_during_thread)
|
|
639
|
+
# self.parent().imageanalysiswindow.true_init()
|
|
640
|
+
|
|
641
|
+
def display_message_from_thread(self, text_from_thread):
|
|
642
|
+
self.message.setText(text_from_thread)
|
|
643
|
+
|
|
644
|
+
def closeEvent(self, event):
|
|
645
|
+
event.accept
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
# if __name__ == "__main__":
|
|
649
|
+
# from cellects.gui.cellects import CellectsMainWidget
|
|
650
|
+
# import sys
|
|
651
|
+
# app = QtWidgets.QApplication([])
|
|
652
|
+
# parent = CellectsMainWidget()
|
|
653
|
+
# session = VideoAnalysisWindow(parent, False)
|
|
654
|
+
# parent.insertWidget(0, session)
|
|
655
|
+
# parent.show()
|
|
656
|
+
# sys.exit(app.exec())
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
File without changes
|