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.
- napari_musa/Widget_DataManager.py +864 -0
- napari_musa/Widgets_DataVisualization.py +257 -0
- napari_musa/Widgets_EndmembersExtraction.py +382 -0
- napari_musa/Widgets_Fusion.py +458 -0
- napari_musa/Widgets_NMF.py +265 -0
- napari_musa/Widgets_PCA.py +212 -0
- napari_musa/Widgets_UMAP.py +463 -0
- napari_musa/_version.py +34 -0
- napari_musa/main.py +150 -0
- napari_musa/modules/D_illuminants.mat +0 -0
- napari_musa/modules/data.py +48 -0
- napari_musa/modules/functions.py +1331 -0
- napari_musa/modules/plot.py +581 -0
- napari_musa/napari.yaml +15 -0
- napari_musa-1.0.0.dist-info/METADATA +156 -0
- napari_musa-1.0.0.dist-info/RECORD +20 -0
- napari_musa-1.0.0.dist-info/WHEEL +5 -0
- napari_musa-1.0.0.dist-info/entry_points.txt +2 -0
- napari_musa-1.0.0.dist-info/licenses/LICENSE +28 -0
- napari_musa-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -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!"))
|