mainwindow.cpp
6.18 KB
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QFileDialog>
#include "stim/visualization/colormap.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
s = new SpectrumWindow(this);
}
void MainWindow::loadImage(QString fileName){
std::string file = fileName.toUtf8().constData();
//load a dummy hyperspectral image for debugging
hsi.open(file, file + ".hdr");
//initialize the size of the main window
//resize(hsi.header.samples+2, hsi.header.lines + ui->menuBar->size().height());
//fill the x axis with wavelength numbers from the hsi
x = QVector<double>::fromStdVector(hsi.header.wavelength);
//load the middle band as the default
load_band(x.size()/2);
//set the pick position to the center of the image
px = py = 0.5;
//create a graphics scene to store the image and any drawn UI elements
scene = new QGraphicsScene(this);
//send the scene to the QGraphicsView object for display
ui->graphicsView->setScene(scene);
//create and show the spectrum window
load_spectrum();
s->initPlot(x.first(), x.last(), 0, 1, hsi.header.wavelength_units.c_str(), "Absorbance");
s->show();
//draw everything
draw_viewport();
}
/// Update the image viewing widget so that it always fills the main window
void MainWindow::resizeEvent(QResizeEvent* event){
//get the current window size
QSize winsize = event->size();
//get the current position of the QGraphicsView object
QPoint imagepos = ui->graphicsView->pos();
//calculate the maximum allowable image width and height given the user's selected window size
unsigned int maxwidth = winsize.width() - imagepos.x();
unsigned int maxheight = winsize.height() - imagepos.y();
//get the size of the image
QSize imagesize = image.size();
//calculate the aspect ratio
//float aspect = imagesize.width() / imagesize.height();
float width_ratio = imagesize.width() / maxwidth;
float height_ratio = imagesize.height() / maxheight;
//if the width requires the largest scaling
if(width_ratio >= height_ratio)
main_image = image.scaledToWidth(maxwidth);
else
main_image = image.scaledToHeight(maxheight);
//update the size of the QGraphicsView object
// the QGraphicsView will be either the size of the image or
// the size of the window (whichever is smaller)
QSize viewsize = QSize( main_image.width()+2, main_image.height()+2 );
ui->graphicsView->setFixedSize(viewsize.width(), viewsize.height());
draw_viewport();
}
/// Update everything associated with when the image is clicked
void MainWindow::mousePressEvent(QMouseEvent * event){
//get the window position of the click
QPoint winp = event->pos();
//get the position of the QGraphicsView object (upper left corner of the image)
QPoint viewp = ui->graphicsView->pos();
//get the size of the menu bar
int menu_height = ui->menuBar->size().height();
//calculate the position of the click in the graphics view
QPoint imagep = winp - viewp - QPoint(0, menu_height);
//get the size of the graphics view object
QSize viewsize = ui->graphicsView->size();
//calculate the position of the point in the image space [0, 1]
px = (float)imagep.x() / (float) viewsize.width();
py = (float)imagep.y() / (float) viewsize.height();
//load the spectrum associated with p
load_spectrum();
draw_viewport();
}
void MainWindow::mousePressSpectrum(double px, double py){
//calculate the band to be loaded
// this will be the closest band to x
unsigned int c = 0;
double diff = abs(px - x[0]);
for(unsigned int i=1; i<x.size(); i++){
if( abs(px - x[i]) < diff ){
c = i;
diff = px - x[i];
}
}
//load the correct band
load_band(c);
//re-draw the viewport to display it
draw_viewport();
}
void MainWindow::load_band(unsigned int i){
//calculate the number of values in the band image
unsigned int N = hsi.header.samples * hsi.header.lines;
//allocate space to store the band data
float* band = (float*) malloc(N * sizeof(float));
//allocate space to store the image (colormap) data
unsigned char* buffer = (unsigned char*) malloc(N * 3 * sizeof(unsigned char));
//load the band data from the HSI
hsi.band_index(band, i);
//convert the band data to an image
stim::cpu2cpu<float>(band, buffer, N, stim::cmBrewer);
//store the color data in the image member variable
image = QPixmap::fromImage(
QImage(
buffer,
hsi.header.samples,
hsi.header.lines,
QImage::Format_RGB888
)
);
//get the main image size
QSize main_size = main_image.size();
//scale the band image
main_image = image.scaledToHeight(main_size.height());
//free the buffer and band memory
free(buffer);
free(band);
}
void MainWindow::draw_viewport(){
scene->clear();
//add the image to the scene
scene->addPixmap(main_image);
//I'm not sure what this does...
scene->setSceneRect(main_image.rect());
//draw the overlay indicating the selected pixel
draw_overlay();
//draw the spectrum
draw_spectrum();
}
//draws an overlay over the image showing details that include the selected pixel
void MainWindow::draw_overlay(){
//get the size of the QGraphicsView object
QSize image_size = ui->graphicsView->size();
//calculate the pixel position (index) into the main image
QPoint pi = QPoint(px * image_size.width(), py * image_size.height());
scene->addLine(0, pi.y(), image_size.width(), pi.y());
scene->addLine(pi.x(), 0, pi.x(), image_size.height());
}
/// Loads the spectrum from the picked point of the HSI and stores it in the member variable y
void MainWindow::load_spectrum(){
//allocate the appropriate amount of memory for the spectrum
float* temp_y = (float*) malloc(x.size() * sizeof(float));
//pixel position in the band image
QPoint pi = QPoint(px * image.width(), py * image.height());
//load the spectrum from the HSI
hsi.spectrum(temp_y, pi.x(), pi.y());
//clear the previous spectrum
y.clear();
//copy the values into the member variable y
for(int i = 0; i < x.size(); i++)
y.push_back(temp_y[i]);
}
void MainWindow::draw_spectrum(){
//plot the saved spectrum
s->plotSpectrum(x, y);
}
MainWindow::~MainWindow(){
delete ui;
}
void MainWindow::on_actionLoad_triggered()
{
QString fileName = QFileDialog::getOpenFileName(0, "Open ENVI File");
loadImage(fileName);
}