napari-musa 1.0.0__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.
@@ -0,0 +1,458 @@
1
+ """ """
2
+
3
+ import sys
4
+ from os.path import dirname
5
+
6
+ sys.path.append(dirname(dirname(__file__)))
7
+ import napari
8
+ from magicgui.widgets import (
9
+ CheckBox,
10
+ ComboBox,
11
+ Container,
12
+ PushButton,
13
+ SpinBox,
14
+ )
15
+ from napari.utils.notifications import show_info
16
+ from qtpy.QtCore import QTimer
17
+ from qtpy.QtWidgets import (
18
+ QGroupBox,
19
+ QScrollArea,
20
+ QVBoxLayout,
21
+ QWidget,
22
+ )
23
+
24
+ from napari_musa.modules.functions import (
25
+ HSI2RGB,
26
+ datasets_fusion,
27
+ )
28
+
29
+
30
+ class Fusion(QWidget):
31
+ """ """
32
+
33
+ def __init__(self, viewer: napari.Viewer, data):
34
+ """ """
35
+ super().__init__()
36
+ self.viewer = viewer
37
+ self.data = data
38
+ self.init_ui()
39
+
40
+ def init_ui(self):
41
+ """ """
42
+ scroll = QScrollArea()
43
+ scroll.setWidgetResizable(True)
44
+ content_widget = QWidget()
45
+ content_layout = QVBoxLayout(content_widget)
46
+
47
+ # fusion_group = self.build_fusion_group()
48
+ # content_layout.addWidget(fusion_group)
49
+ content_layout.addWidget(self.create_fusion_controls_box())
50
+ content_layout.addWidget(self.create_midlevel_fusion_controls())
51
+ content_layout.addStretch()
52
+
53
+ scroll.setWidget(content_widget)
54
+ main_layout = QVBoxLayout(self)
55
+ main_layout.addWidget(scroll)
56
+ self.setLayout(main_layout)
57
+
58
+ def create_fusion_controls_box(self):
59
+ """ """
60
+ fusion_box = QGroupBox("Low-Level Fusion")
61
+ layout = QVBoxLayout()
62
+
63
+ self.reduced_dataset_checkbox = CheckBox(
64
+ text="Fuse the reduced datasets (Only if you have both reduced datasets)"
65
+ )
66
+
67
+ self.modes_fusion = ComboBox(
68
+ choices=[
69
+ "Frobenius norm",
70
+ "Z score",
71
+ "Z score - dataset",
72
+ "Z score - spectrum",
73
+ "SNV",
74
+ "Sum to one",
75
+ "Global min-max",
76
+ "Robust min-max",
77
+ "Pixel min-max",
78
+ ],
79
+ label="Select fusion modality",
80
+ )
81
+
82
+ self.modes_combobox_1 = ComboBox(
83
+ choices=self.data.modes, label="Select the first dataset"
84
+ )
85
+ self.modes_combobox_2 = ComboBox(
86
+ choices=self.data.modes,
87
+ label="Select the second dataset",
88
+ value="PL",
89
+ )
90
+ self.modes_combobox_3 = ComboBox(
91
+ choices=self.data.modes,
92
+ label="Select the third dataset",
93
+ value="-",
94
+ )
95
+
96
+ fusion_perform_btn = PushButton(text="Fuse the chosen datasets")
97
+ fusion_perform_btn.clicked.connect(self.fusion_perform_btn_f)
98
+
99
+ layout.addWidget(
100
+ Container(
101
+ widgets=[
102
+ self.reduced_dataset_checkbox,
103
+ self.modes_fusion,
104
+ self.modes_combobox_1,
105
+ self.modes_combobox_2,
106
+ self.modes_combobox_3,
107
+ fusion_perform_btn,
108
+ ]
109
+ ).native
110
+ )
111
+ fusion_box.setLayout(layout)
112
+ return fusion_box
113
+
114
+ def create_midlevel_fusion_controls(self):
115
+ """ """
116
+ fusion_box = QGroupBox("Mid-Level Fusion - PCA")
117
+ layout = QVBoxLayout()
118
+
119
+ self.PCA_components = SpinBox(
120
+ min=1, max=100, value=1, step=1, name="PCA components"
121
+ )
122
+
123
+ self.modes_combobox_1_MLF = ComboBox(
124
+ choices=self.data.modes, label="Select the first dataset"
125
+ )
126
+ self.modes_combobox_2_MLF = ComboBox(
127
+ choices=self.data.modes,
128
+ label="Select the second dataset",
129
+ value="PL",
130
+ )
131
+ self.modes_combobox_3_MLF = ComboBox(
132
+ choices=self.data.modes,
133
+ label="Select the third dataset",
134
+ value="-",
135
+ )
136
+
137
+ MLfusion_perform_btn = PushButton(text="Fuse the chosen datasets")
138
+ MLfusion_perform_btn.clicked.connect(self.MLfusion_perform_btn_f)
139
+
140
+ layout.addWidget(
141
+ Container(
142
+ widgets=[
143
+ self.PCA_components,
144
+ self.modes_combobox_1_MLF,
145
+ self.modes_combobox_2_MLF,
146
+ self.modes_combobox_3_MLF,
147
+ MLfusion_perform_btn,
148
+ ]
149
+ ).native
150
+ )
151
+ fusion_box.setLayout(layout)
152
+ return fusion_box
153
+
154
+ def fusion_perform_btn_f(self):
155
+ """ """
156
+ # Parameters
157
+ self.data.fusion_norm = self.modes_fusion.value # Norm used for fusion
158
+ self.data.fusion_modes = (
159
+ []
160
+ ) # Tells which datasets are fused (Refle-PL, PL1-PL2, etc.)
161
+ self.data.fusion_modes.append(self.modes_combobox_1.value)
162
+ self.data.fusion_modes.append(self.modes_combobox_2.value)
163
+ wl1 = self.data.wls[self.modes_combobox_1.value]
164
+ wl2 = self.data.wls[self.modes_combobox_2.value]
165
+ #
166
+ # If a third dataset is selected
167
+ if self.modes_combobox_3.value != "-":
168
+ self.data.fusion_modes.append(self.modes_combobox_3.value)
169
+ wl3 = self.data.wls[self.modes_combobox_1.value]
170
+ #
171
+ # If we want to fuse the reduced datasets
172
+ if self.reduced_dataset_checkbox.value:
173
+ # If 1 and 2 have the spatial reduction (should be when I have both spatial and spectral reduction)
174
+ # First are fused the spatial reduced datasets
175
+ if (
176
+ self.data.hypercubes_spatial_red.get(
177
+ self.modes_combobox_1.value
178
+ )
179
+ is not None
180
+ and self.data.hypercubes_spatial_red.get(
181
+ self.modes_combobox_2.value
182
+ )
183
+ is not None
184
+ ):
185
+ dataset1 = self.data.hypercubes_spatial_red[
186
+ self.modes_combobox_1.value
187
+ ]
188
+ dataset2 = self.data.hypercubes_spatial_red[
189
+ self.modes_combobox_2.value
190
+ ]
191
+ (
192
+ self.data.hypercubes_spatial_red[
193
+ "Fused"
194
+ ], # Fusion of spatial reduced datasets
195
+ self.data.wls["Fused"],
196
+ self.data.fusion_params,
197
+ ) = datasets_fusion(
198
+ dataset1, dataset2, wl1, wl2, norm=self.modes_fusion.value
199
+ )
200
+ # dataset1 and dataset2 for the fusion
201
+ dataset1 = self.data.hypercubes_red[self.modes_combobox_1.value]
202
+ dataset2 = self.data.hypercubes_red[self.modes_combobox_2.value]
203
+
204
+ self.data.rgb_red["Fused"] = self.data.rgb_red[
205
+ self.modes_combobox_1.value
206
+ ] # The rgb of the fused is the rgb of dataset 1
207
+ (
208
+ self.data.hypercubes_red["Fused"],
209
+ self.data.wls["Fused"],
210
+ self.data.fusion_params,
211
+ ) = datasets_fusion(
212
+ dataset1, dataset2, wl1, wl2, norm=self.modes_fusion.value
213
+ )
214
+ # If we have a third dataset
215
+ if self.modes_combobox_3.value != "-":
216
+ if (
217
+ self.data.hypercubes_spatial_red.get(
218
+ self.modes_combobox_3.value
219
+ )
220
+ is not None
221
+ ): # If we apply both spatial and spectral reduction, append 3rd spatial reduced dataset to the fused
222
+ # spatial reduced datasets
223
+ dataset3 = self.data.hypercubes_spatial_red[
224
+ self.modes_combobox_3.value
225
+ ]
226
+ (
227
+ self.data.hypercubes_spatial_red["Fused"],
228
+ self.data.wls["Fused"],
229
+ self.data.fusion_params,
230
+ ) = datasets_fusion(
231
+ self.data.hypercubes_spatial_red["Fused"],
232
+ dataset3,
233
+ self.data.wls["Fused"],
234
+ wl3,
235
+ norm=self.modes_fusion.value,
236
+ )
237
+ dataset3 = self.data.hypercubes_red[
238
+ self.modes_combobox_3.value
239
+ ]
240
+ (
241
+ self.data.hypercubes_red["Fused"],
242
+ self.data.wls["Fused"],
243
+ self.data.fusion_params,
244
+ ) = datasets_fusion(
245
+ self.data.hypercubes_red["Fused"],
246
+ dataset3,
247
+ self.data.wls["Fused"],
248
+ wl3,
249
+ norm=self.modes_fusion.value,
250
+ )
251
+ self.viewer.add_image(
252
+ self.data.hypercubes_red["Fused"].transpose(2, 0, 1),
253
+ name="Fused",
254
+ metadata={"type": "hyperspectral_cube"},
255
+ )
256
+ #
257
+ # If the dataset are not reduced
258
+ else:
259
+ dataset1 = self.data.hypercubes[self.modes_combobox_1.value]
260
+ dataset2 = self.data.hypercubes[self.modes_combobox_2.value]
261
+ if self.data.rgb.get(self.modes_combobox_1.value) is not None:
262
+ self.data.rgb["Fused"] = self.data.rgb[
263
+ self.modes_combobox_1.value
264
+ ]
265
+ else: # If we did not create the rgb of dataset 1, we compute it here
266
+ self.data.rgb[self.modes_combobox_1.value] = HSI2RGB(
267
+ self.data.wls[self.modes_combobox_1.value],
268
+ dataset1,
269
+ dataset1.shape[0],
270
+ dataset1.shape[1],
271
+ 65,
272
+ False,
273
+ )
274
+
275
+ self.viewer.add_image(
276
+ self.data.rgb[self.modes_combobox_1.value],
277
+ name=str(self.modes_combobox_1.value) + " RGB",
278
+ metadata={"type": "rgb"},
279
+ )
280
+ # Compute the fusion
281
+ (
282
+ self.data.hypercubes["Fused"],
283
+ self.data.wls["Fused"],
284
+ self.data.fusion_params,
285
+ ) = datasets_fusion(
286
+ dataset1, dataset2, wl1, wl2, norm=self.modes_fusion.value
287
+ )
288
+ # If we have a third dataset
289
+ if self.modes_combobox_3.value != "-":
290
+ dataset3 = self.data.hypercubes[self.modes_combobox_3.value]
291
+ (
292
+ self.data.hypercubes["Fused"],
293
+ self.data.wls["Fused"],
294
+ self.data.fusion_params,
295
+ ) = datasets_fusion(
296
+ self.data.hypercubes["Fused"],
297
+ dataset3,
298
+ self.data.wls["Fused"],
299
+ wl3,
300
+ norm=self.modes_fusion.value,
301
+ )
302
+ self.viewer.add_image(
303
+ self.data.hypercubes["Fused"].transpose(2, 0, 1),
304
+ name="Fused",
305
+ metadata={"type": "hyperspectral_cube"},
306
+ )
307
+ QTimer.singleShot(0, lambda: show_info("Fusion completed!"))
308
+
309
+ # xxx sistemarte
310
+ def MLfusion_perform_btn_f(self):
311
+ """ """
312
+ # Parameters
313
+ self.data.fusion_norm = self.modes_fusion.value # Norm used for fusion
314
+ self.data.fusion_modes = (
315
+ []
316
+ ) # Tells which datasets are fused (Refle-PL, PL1-PL2, etc.)
317
+ self.data.fusion_modes.append(self.modes_combobox_1.value)
318
+ self.data.fusion_modes.append(self.modes_combobox_2.value)
319
+ wl1 = self.data.wls[self.modes_combobox_1.value]
320
+ wl2 = self.data.wls[self.modes_combobox_2.value]
321
+ #
322
+ # If a third dataset is selected
323
+ if self.modes_combobox_3.value != "-":
324
+ self.data.fusion_modes.append(self.modes_combobox_3.value)
325
+ wl3 = self.data.wls[self.modes_combobox_1.value]
326
+ #
327
+ # If we want to fuse the reduced datasets
328
+ if self.reduced_dataset_checkbox.value:
329
+ # If 1 and 2 have the spatial reduction (should be when I have both spatial and spectral reduction)
330
+ # First are fused the spatial reduced datasets
331
+ if (
332
+ self.data.hypercubes_spatial_red.get(
333
+ self.modes_combobox_1.value
334
+ )
335
+ is not None
336
+ and self.data.hypercubes_spatial_red.get(
337
+ self.modes_combobox_2.value
338
+ )
339
+ is not None
340
+ ):
341
+ dataset1 = self.data.hypercubes_spatial_red[
342
+ self.modes_combobox_1.value
343
+ ]
344
+ dataset2 = self.data.hypercubes_spatial_red[
345
+ self.modes_combobox_2.value
346
+ ]
347
+ (
348
+ self.data.hypercubes_spatial_red[
349
+ "Fused"
350
+ ], # Fusion of spatial reduced datasets
351
+ self.data.wls["Fused"],
352
+ self.data.fusion_params,
353
+ ) = datasets_fusion(
354
+ dataset1, dataset2, wl1, wl2, norm=self.modes_fusion.value
355
+ )
356
+ # dataset1 and dataset2 for the fusion
357
+ dataset1 = self.data.hypercubes_red[self.modes_combobox_1.value]
358
+ dataset2 = self.data.hypercubes_red[self.modes_combobox_2.value]
359
+
360
+ self.data.rgb_red["Fused"] = self.data.rgb_red[
361
+ self.modes_combobox_1.value
362
+ ] # The rgb of the fused is the rgb of dataset 1
363
+ (
364
+ self.data.hypercubes_red["Fused"],
365
+ self.data.wls["Fused"],
366
+ self.data.fusion_params,
367
+ ) = datasets_fusion(
368
+ dataset1, dataset2, wl1, wl2, norm=self.modes_fusion.value
369
+ )
370
+ # If we have a third dataset
371
+ if self.modes_combobox_3.value != "-":
372
+ if (
373
+ self.data.hypercubes_spatial_red.get(
374
+ self.modes_combobox_3.value
375
+ )
376
+ is not None
377
+ ): # If we apply both spatial and spectral reduction, append 3rd spatial reduced dataset to the fused
378
+ # spatial reduced datasets
379
+ dataset3 = self.data.hypercubes_spatial_red[
380
+ self.modes_combobox_3.value
381
+ ]
382
+ (
383
+ self.data.hypercubes_spatial_red["Fused"],
384
+ self.data.wls["Fused"],
385
+ self.data.fusion_params,
386
+ ) = datasets_fusion(
387
+ self.data.hypercubes_spatial_red["Fused"],
388
+ dataset3,
389
+ self.data.wls["Fused"],
390
+ wl3,
391
+ norm=self.modes_fusion.value,
392
+ )
393
+ dataset3 = self.data.hypercubes_red[
394
+ self.modes_combobox_3.value
395
+ ]
396
+ (
397
+ self.data.hypercubes_red["Fused"],
398
+ self.data.wls["Fused"],
399
+ self.data.fusion_params,
400
+ ) = datasets_fusion(
401
+ self.data.hypercubes_red["Fused"],
402
+ dataset3,
403
+ self.data.wls["Fused"],
404
+ wl3,
405
+ norm=self.modes_fusion.value,
406
+ )
407
+ #
408
+ # If the dataset are not reduced
409
+ else:
410
+ dataset1 = self.data.hypercubes[self.modes_combobox_1.value]
411
+ dataset2 = self.data.hypercubes[self.modes_combobox_2.value]
412
+ if self.data.rgb.get(self.modes_combobox_1.value) is not None:
413
+ self.data.rgb["Fused"] = self.data.rgb[
414
+ self.modes_combobox_1.value
415
+ ]
416
+ else: # If we did not create the rgb of dataset 1, we compute it here
417
+ self.data.rgb[self.modes_combobox_1.value] = HSI2RGB(
418
+ self.data.wls[self.modes_combobox_1.value],
419
+ dataset1,
420
+ dataset1.shape[0],
421
+ dataset1.shape[1],
422
+ 65,
423
+ False,
424
+ )
425
+
426
+ self.viewer.add_image(
427
+ self.data.rgb[self.modes_combobox_1.value],
428
+ name=str(self.modes_combobox_1.value) + " RGB",
429
+ metadata={"type": "rgb"},
430
+ )
431
+ # Compute the fusion
432
+ (
433
+ self.data.hypercubes["Fused"],
434
+ self.data.wls["Fused"],
435
+ self.data.fusion_params,
436
+ ) = datasets_fusion(
437
+ dataset1, dataset2, wl1, wl2, norm=self.modes_fusion.value
438
+ )
439
+ # If we have a third dataset
440
+ if self.modes_combobox_3.value != "-":
441
+ dataset3 = self.data.hypercubes[self.modes_combobox_3.value]
442
+ (
443
+ self.data.hypercubes["Fused"],
444
+ self.data.wls["Fused"],
445
+ self.data.fusion_params,
446
+ ) = datasets_fusion(
447
+ self.data.hypercubes["Fused"],
448
+ dataset3,
449
+ self.data.wls["Fused"],
450
+ wl3,
451
+ norm=self.modes_fusion.value,
452
+ )
453
+ self.viewer.add_image(
454
+ self.data.hypercubes["Fused"].transpose(2, 0, 1),
455
+ name="Fused",
456
+ metadata={"type": "hyperspectral_cube"},
457
+ )
458
+ QTimer.singleShot(0, lambda: show_info("Fusion completed!"))