1 // Copyright (C) 2020 by Yuri Victorovich. All rights reserved.
2 
3 #pragma once
4 
5 #include <QMainWindow>
6 #include <QSplitter>
7 #include <QScrollArea>
8 #include <QStackedWidget>
9 #include <QGroupBox>
10 #include "nn-widget.h"
11 #include "no-nn-is-open-widget.h"
12 #include "operators-list-widget.h"
13 #include "scale-image-widget.h"
14 #include "data-table-2d.h"
15 #include <QLabel>
16 #include <QPushButton>
17 #include <QCheckBox>
18 #include <QComboBox>
19 #include <QLineEdit>
20 #include <QVBoxLayout>
21 #include <QGridLayout>
22 #include <QMenuBar>
23 #include <QStatusBar>
24 #include <QPixmap>
25 #include <QRectF>
26 #if defined(USE_PERFTOOLS)
27 #include <QTimer>
28 #endif
29 
30 #include "plugin-manager.h"
31 #include "plugin-interface.h"
32 #include "nn-types.h"
33 
34 #include <vector>
35 #include <array>
36 #include <memory>
37 
38 class MainWindow : public QMainWindow {
39 	Q_OBJECT
40 
41 public:
42 	MainWindow();
43 	~MainWindow();
44 
45 	bool loadModelFile(const QString &filePath);
46 
47 private: // fields
48 	// widgets
49 	QSplitter                        mainSplitter;
50 	// Lhs
51 	QScrollArea                        svgScrollArea;
52 	NnWidget                             nnWidget;
53 	// Rhs
54 	QWidget                            rhsWidget;
55 	QVBoxLayout                          rhsLayout;
56 	// Rhs/Source
57 	QGroupBox                            sourceWidget; // optionally visible
58 	QHBoxLayout                            sourceLayout;
59 	QWidget                                sourceDetails;
60 	QGridLayout                              sourceDetailsLayout;
61 	QLabel                                   sourceImageFileNameLabel;
62 	QLabel                                   sourceImageFileNameText;
63 	QLabel                                   sourceImageFileSizeLabel;
64 	QLabel                                   sourceImageFileSizeText;
65 	QLabel                                   sourceImageSizeLabel;
66 	QLabel                                   sourceImageSizeText;
67 	QLabel                                   sourceImageCurrentRegionLabel;
68 	QLabel                                   sourceImageCurrentRegionText;
69 	QLabel                                   outputInterpretationSummaryLineEdit;
70 	QWidget                                  scaleImageWidget;
71 	QHBoxLayout                                scaleImageLayout;
72 	QWidget                                    spacerScaleWidget;
73 	QLabel                                     scaleImageLabel;
74 	ScaleImageWidget                           scaleImageSpinBoxes;
75 	// Rhs/Source/Effects
76 	QGroupBox                                sourceApplyEffectsWidget;
77 	QGridLayout                                sourceApplyEffectsLayout;
78 	QLabel                                     sourceEffectFlipHorizontallyLabel;
79 	QCheckBox                                  sourceEffectFlipHorizontallyCheckBox;
80 	QLabel                                     sourceEffectFlipVerticallyLabel;
81 	QCheckBox                                  sourceEffectFlipVerticallyCheckBox;
82 	QLabel                                     sourceEffectMakeGrayscaleLabel;
83 	QCheckBox                                  sourceEffectMakeGrayscaleCheckBox;
84 	QLabel                                     sourceEffectConvolutionLabel;
85 	QWidget                                    sourceEffectConvolutionParamsWidget;
86 	QHBoxLayout                                  sourceEffectConvolutionParamsLayout;
87 	QComboBox                                    sourceEffectConvolutionTypeComboBox;
88 	QComboBox                                    sourceEffectConvolutionCountComboBox;
89 	// Rhs/Source/Compute
90 	QWidget                                  computeWidget;
91 	QHBoxLayout                                computeLayout;
92 	QPushButton                                computeButton;
93 	QComboBox                                  computeRegionComboBox;
94 	QWidget                                  computeByWidget;
95 	QHBoxLayout                                computeByLayout;
96 	QLabel                                     inputNormalizationLabel;
97 	QComboBox                                  inputNormalizationRangeComboBox;
98 	QComboBox                                  inputNormalizationColorOrderComboBox;
99 	QWidget                                    spacer1Widget;
100 	QLabel                                     computationTimeLabel;
101 	QWidget                                    spacer2Widget;
102 	QLabel                                     outputInterpretationLabel;
103 	QComboBox                                  outputInterpretationKindComboBox;
104 	QWidget                                    spacer3Widget;
105 	QPushButton                                clearComputationResults;
106 	QStackedWidget                         sourceImageStack;
107 	QScrollArea                              sourceImageScrollArea;
108 	QLabel                                     sourceImage;       // index#0
109 	std::unique_ptr<QLabel>                  interpretationImage; // index#1: only exists when the interpretation image is possible
110 	// Rhs/NN details
111 	QStackedWidget                       nnDetailsStack;
112 	QGroupBox                              nnNetworkDetails;   // page#0: network
113 	QGridLayout                              nnNetworkDetailsLayout;
114 	QLabel                                   nnNetworkDescriptionLabel;
115 	QLabel                                   nnNetworkDescriptionText;
116 	QLabel                                   nnNetworkComplexityLabel;
117 	QLabel                                   nnNetworkComplexityText;
118 	QLabel                                   nnNetworkFileSizeLabel;
119 	QLabel                                   nnNetworkFileSizeText;
120 	QLabel                                   nnNetworkNumberInsOutsLabel;
121 	QLabel                                   nnNetworkNumberInsOutsText;
122 	QLabel                                   nnNetworkNumberOperatorsLabel;
123 	QLabel                                   nnNetworkNumberOperatorsText;
124 	QLabel                                   nnNetworkStaticDataLabel;
125 	QLabel                                   nnNetworkStaticDataText;
126 	QLabel                                   nnNetworkOperatorsListLabel;
127 	OperatorsListWidget                      nnNetworkOperatorsListWidget;
128 	QGroupBox                              nnOperatorDetails; // page#1: operator
129 	QGridLayout                              nnOperatorDetailsLayout;
130 	QLabel                                   nnOperatorTypeLabel;
131 	QLabel                                   nnOperatorTypeValue;
132 	QLabel                                   nnOperatorOptionsLabel;
133 	QLabel                                   nnOperatorInputsLabel;
134 	QLabel                                   nnOperatorOutputsLabel;
135 	QLabel                                   nnOperatorComplexityLabel;
136 	QLabel                                   nnOperatorComplexityValue;
137 	QLabel                                   nnOperatorStaticDataLabel;
138 	QLabel                                   nnOperatorStaticDataValue;
139 	QLabel                                   nnOperatorDataRatioLabel;
140 	QLabel                                   nnOperatorDataRatioValue;
141 	QWidget                                  nnOperatorDetailsSpacer;
142 	QGroupBox                              nnTensorDetails;   // page#2: tensor
143 	int                                      nnCurrentTensorId;
144 	QGridLayout                              nnTensorDetailsLayout;
145 	QLabel                                   nnTensorKindLabel;
146 	QLabel                                   nnTensorKindValue;
147 	QLabel                                   nnTensorShapeLabel;
148 	QLabel                                   nnTensorShapeValue;
149 	QLabel                                   nnTensorTypeLabel;
150 	QLabel                                   nnTensorTypeValue;
151 	QPushButton                              nnTensorSaveDataButton;
152 	QLabel                                   nnTensorDataPlaceholder;
153 	QLabel                                   nnTensorDataPlaceholder1DnotImplemented;
154 	std::unique_ptr<DataTable2DBase>         nnTensorData2D;
155 	QGroupBox                            noNnIsOpenGroupBox; // optionally visible
156 	QVBoxLayout                            noNnIsOpenLayout;
157 	NoNnIsOpenWidget                       noNnIsOpenWidget;
158 
159 	QMenuBar                         menuBar;
160 	QStatusBar                       statusBar;
161 #if defined(USE_PERFTOOLS)
162 	QLabel                           memoryUseLabel;
163 	QTimer                           memoryUseTimer;
164 #endif
165 
166 	const PluginManager::Plugin*                   plugin;    // plugin in use for the model
167 	std::unique_ptr<PluginInterface>               pluginInterface; // the file is opened through this handle
168 	std::unique_ptr<const PluginInterface::Model>  model;     // the model from the file that is currently open
169 
170 	// data associated with a specific input data (image) currently loaded by the user (static tensors from the model aren't here)
171 	TensorShape                      sourceTensorShape;
172 	std::shared_ptr<float>           sourceTensorDataAsLoaded; // original image that was loaded by the user
173 	std::shared_ptr<float>           sourceTensorDataAsUsed;   // image that is used as an input of NN, might be different if effects are applied
174 	std::unique_ptr<std::vector<std::shared_ptr<const float>>>   tensorData; // tensors corresponding to the currently used image, shared because reshape/input often shared
175 
176 	std::vector<std::unique_ptr<QWidget>>   tempDetailWidgets;
177 
178 	unsigned                         scaleImageWidthPct;    // percentage to scale the image to show on the screen
179 	unsigned                         scaleImageHeightPct;
180 	int                              self; // to prevent signals from programmatically changed values
181 
182 private: // types
183 	enum HowLong {Temporary, Permanent};
184 
185 private: // private methods
186 	bool haveImageOpen() const;
187 	void showNetworkDetails();
188 	void showOperatorDetails(PluginInterface::OperatorId operatorId);
189 	void showTensorDetails(PluginInterface::TensorId tensorId);
190 	void showTensorDetails(PluginInterface::TensorId tensorId, const char *label);
191 	void showInputDetails(PluginInterface::TensorId tensorId);
192 	void showOutputDetails(PluginInterface::TensorId tensorId);
193 	void removeTableIfAny();
194 	void openImageFile(const QString &imageFileName);
195 	void openImagePixmap(const QPixmap &imagePixmap, const QString &sourceName);
196 	void clearInputImageDisplay();
197 	void clearComputedTensorData(HowLong howLong);
198 	void effectsChanged();
199 	void inputNormalizationChanged();
200 	void inputParamsChanged();
201 	float* applyEffects(const float *image, const TensorShape &shape,
202 		bool flipHorizontally, bool flipVertically, bool makeGrayscale,
203 		const std::tuple<TensorShape,std::vector<float>> &convolution, unsigned convolutionCount) const;
204 	void clearEffects();
205 	void updateNetworkDetailsPage();
206 	void updateSourceImageOnScreen();
207 	void updateCurrentRegionText();
208 	void updateResultInterpretation();
209 	void updateResultInterpretationSummaryText(bool enable, const QString &oneLine, const QString &details);
210 	std::array<unsigned,4> getVisibleImageRegion() const;
211 	void updateSectionWidgetsVisibility();
212 	void onOpenNeuralNetworkFileUserIntent();
213 	void closeNeuralNetwork();
214 	static QLabel* makeTextSelectable(QLabel *label);
215 	void showNnTensorData2D();
216 	void clearNnTensorData2D();
217 };
218 
219