-
Notifications
You must be signed in to change notification settings - Fork 1
/
load.cpp
378 lines (314 loc) · 10.1 KB
/
load.cpp
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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
#include "easyfg.h"
void MainWindow::LoadAscii(QString filename, int **Array, int *width, int *height)
{
QFile file;
file.setFileName(filename);
file.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream stream(&file);
QString str;
QTextStream stream1;
QString separator = ",";
//bool lineNumberInFirstColumn = true;
char c;
*width = 0;
*height = 0;
while(!stream.atEnd()){
str = stream.readLine();
if(*height==0){
if(str.count(",") == 0){
if(str.count(" ") != 0)
separator = " ";
else
separator = "\t";
}
*width = str.count(separator)+1;
if(str.lastIndexOf(separator) == str.length()-1)
*width = *width-1;
}
stream1.setString(&str);
for(int i=0; i<*width; i++)
stream1 >> Array[i][*height] >> c;
//if(Array[0][*height] != *height+1)
//lineNumberInFirstColumn = false;
*height += 1;
}
file.close();
/*if(lineNumberInFirstColumn) // Andor ascii file has line numbering that need to be removed
{
*width = *width-1;
for(int i=0; i<*width; i++)
for(int j=0; j<*height; j++)
Array[i][j] = Array[i+1][j];
}*/
}
//Andor .sif (doesn't work for all cameras; use tiff instead)
void MainWindow::LoadSif(QString filename, int **Array, int *width, int *height)
{
int n_lines_before_data;
int version[4];
int i, j;
QString str;
QStringList list;
*width = 0;
*height = 0;
// Sif file
QFile file(filename);
file.open(QIODevice::ReadOnly);
// Streams for reading file header (text) and data
QTextStream tstream(&file);
QDataStream dstream(&file);
dstream.setFloatingPointPrecision(QDataStream::SinglePrecision); // sif data are 32 bit float
dstream.setByteOrder(QDataStream::LittleEndian);
// check if correct sif file
if(tstream.readLine() != "Andor Technology Multi-Channel File"){
file.close();
return;
}
tstream.readLine(); // skip line
// read version info
str = tstream.readLine();
list = str.split(" ");
version[0] = list.at(54).toInt();
version[1] = list.at(55).toInt();
version[2] = list.at(56).toInt();
version[3] = list.at(57).toInt();
// define data offset
if(version[0]==0) // French group cameras
n_lines_before_data=24;
if(version[0]==4){
if(version[1]==9) // from OpenSIFkai
n_lines_before_data = 27;
if(version[1]==11) // Imperial College camera
n_lines_before_data = 31;
if(version[1]==13 || version[1]==15) // from OpenSIFkai
n_lines_before_data = 31;
}
for(i=0; i<=n_lines_before_data-6; i++)
tstream.readLine(); // skip line
// read width & height info
str = tstream.readLine();
list = str.split(" ");
int left = list.at(1).toInt();
int top = list.at(2).toInt();
int right = list.at(3).toInt();
int bottom = list.at(4).toInt();
*width = right-left+1;
*height = top-bottom+1;
// go to begginning of the file
file.seek(0);
// skip headerer lines
qint8 i8 = 0;
for(i=0; i<n_lines_before_data; i++){
dstream >> i8;
while(i8 != 10) // end line simbol
dstream >> i8;
}
// read data
float tmp;
for(j=0; j<*height; j++) {
for(i=0; i<*width; i++){
dstream >> tmp;
Array[i][*height-1-j] = (int)tmp;
}
}
file.close();
}
void MainWindow::LoadTiff(QString filename, int **Array, int *width, int *height)
{
*width = 0;
*height = 0;
//check if tiff is supported (list all supported file formats)
//QList<QByteArray> list = QImageReader::supportedImageFormats();
//QMessageBox().information(this, "Supported formats", list.join(","));
QFile f(filename);
if(!f.open(QIODevice::ReadOnly)){
QMessageBox().warning(this, "easyFG", "Cannot open file");
return;
}
QByteArray ar(f.size(), ' ');
f.read(ar.data(), ar.size());
f.close();
QImage img;
img.loadFromData(ar);
if (img.isNull()){
QMessageBox().warning(this, "easyFG", "File load error");
return;
}
//QMessageBox().information(this, "Image format", QString::number(img.format()));
if(img.format()!=QImage::Format_Grayscale8 && img.format()!=QImage::Format_Grayscale16)
{
QMessageBox().warning(this, "easyFG", "Unsupported TIFF file format");
return;
}
// read data
*width = img.width();
*height = img.height();
uchar* line;
int i, j;
for(j=0; j<*height; j++)
{
line = img.scanLine(j);
for(i=0; i<*width; i++)
{
if(img.format()==QImage::Format_Grayscale8) // 8-bit greyscale
Array[i][j] = ((uint8_t*)line)[i];
else //16-bit greyscale
Array[i][j] = ((uint16_t*)line)[i];
}
}
}
// Pyrocam III .RAW file
void MainWindow::LoadRaw(QString filename, int **Array, int *width, int *height)
{
int i, j;
*width = 124;
*height = 124;
// Raw file
QFile file(filename);
file.open(QIODevice::ReadOnly);
// Stream for reading data
QDataStream dstream(&file);
dstream.setByteOrder(QDataStream::LittleEndian);
// go to begginning of the data
file.seek(16704);
// read data
int16_t tmp;
for(j=0; j<*height; j++)
{
for(i=0; i<*width; i++)
{
dstream >> tmp;
Array[i][j] = (int)tmp;
}
}
file.close();
}
// Pyrocam IV .bgData file
void MainWindow::LoadBgdata(QString filename, int **Array, int *width, int *height)
{
int i, j;
*width = 0;
*height = 0;
hid_t file;
int32_t *data;
file = H5Fopen(filename.toUtf8(), H5F_ACC_RDONLY, H5P_DEFAULT);
// read width and height
H5LTread_dataset_int(file, "/BG_DATA/1/RAWFRAME/WIDTH", width);
H5LTread_dataset_int(file, "/BG_DATA/1/RAWFRAME/HEIGHT", height);
data = (int32_t*)malloc(sizeof(int32_t) * (*width) * (*height));
// read dataset
H5LTread_dataset_int(file,"/BG_DATA/1/DATA",data);
for(j=0; j<*height; j++)
{
for(i=0; i<*width; i++)
Array[i][j] = data[i+(*width)*j] >> 16; // shift 16 bit to the right
}
// from Ophir website:
// Regarding the .bgData image file decription; the input camera native source may be 8, 10, 12, 14, or 16 bits per pixel.
// BeamGage employs a normalized (signed 32-bit) fixed point format for storing pixel values in HDF5 data files. The
// acquired and processed camera pixel data is converted to a 32-bit signed value and stored. The most significant bit of the
// camera's native data is shifted to the bit position just behind the sign bit (assuming bit positions 0 [lsb] -31 [msb] this would
// be position 30). The empty bits below the native format are then available for additional precision and will be utilized via
// frame averaging, background subtraction, or other image processing activities.
free(data);
/* close file */
H5Fclose(file);
}
void MainWindow::LoadData(QString path)
{
QFileInfo file(path);
if(!file.exists())
return;
int tmp;
datafile = path;
if(file.suffix().toLower()=="asc" || file.suffix().toLower()=="csv"){ // ASCII
LoadAscii(datafile, DataArray, &datawidth, &dataheight);
dataloaded = true;
}
if(file.suffix().toLower()=="sif"){ // Andor sif
LoadSif(datafile, DataArray, &datawidth, &dataheight);
dataloaded = true;
}
if(file.suffix().toLower()=="tiff" || file.suffix().toLower()=="tif"){ // TIFF
LoadTiff(datafile, DataArray, &datawidth, &dataheight);
dataloaded = true;
}
if(file.suffix().toLower()=="raw"){ // Pyrocam III
LoadRaw(datafile, DataArray, &datawidth, &dataheight);
dataloaded = true;
}
if(file.suffix().toLower()=="bgdata"){ // Pyrocam IV
LoadBgdata(datafile, DataArray, &datawidth, &dataheight);
dataloaded = true;
}
if(!dataloaded)
return;
datamin = 1e9;
datamax = -1e9;
//dataaverage = 0;
for(int i=0; i<datawidth; i++){
for(int j=0; j<dataheight; j++){
tmp = DataArray[i][j];
if(tmp<datamin)
datamin=tmp;
if(tmp>datamax)
datamax = tmp;
//dataaverage += DataArray[i][j];
}
}
//dataaverage /= datawidth*dataheight;
if(referenceComboBox->currentIndex() == 3) // "Show reference"
referenceComboBox->setCurrentIndex(0); // switch to "OFF"
if(refloaded && referenceComboBox->currentIndex()>0)
CalculateCorrectedArray();
UpdateCursors();
UpdateScale();
UpdateImage();
RedoAnalysis();
UpdateVisibility();
UpdateScene();
UpdateStatus();
}
void MainWindow::LoadRef(QString path)
{
QFileInfo file(path);
if(!file.exists())
return;
reffile = path;
if(file.suffix().toLower()=="asc"){ // ASCII file
LoadAscii(reffile, RefArray, &refwidth, &refheight);
refloaded = true;
}
if(file.suffix().toLower()=="sif"){ // Andor sif
LoadSif(reffile, RefArray, &refwidth, &refheight);
refloaded = true;
}
if(file.suffix().toLower()=="tiff" || file.suffix().toLower()=="tif"){ // TIFF
LoadTiff(reffile, RefArray, &refwidth, &refheight);
refloaded = true;
}
if(file.suffix().toLower()=="raw"){ // Pyrocam III
LoadRaw(reffile, RefArray, &refwidth, &refheight);
refloaded = true;
}
if(file.suffix().toLower()=="bgdata"){ // Pyrocam IV
LoadBgdata(reffile, RefArray, &refwidth, &refheight);
refloaded = true;
}
if(!refloaded)
return;
refaverage = 0;
for(int i=0; i<refwidth; i++)
for(int j=0; j<refheight; j++)
refaverage += RefArray[i][j];
refaverage /= refwidth*refheight;
if(dataloaded && referenceComboBox->currentIndex()>0){
CalculateCorrectedArray();
UpdateImage();
UpdateScale();
RedoAnalysis();
UpdateScene();
UpdateStatus();
}
UpdateVisibility();
}