e8eb202f
David Mayerich
added a new ENVI ...
|
1
2
3
4
|
#ifndef STIM_BSQ_H
#define STIM_BSQ_H
#include "../envi/envi_header.h"
|
3fc1d461
heziqi
Ziqi added saveBa...
|
5
|
#include "../envi/binary.h"
|
e8eb202f
David Mayerich
added a new ENVI ...
|
6
|
#include "../envi/bil.h"
|
fc712213
David Mayerich
code simplifications
|
7
8
|
#include <cstring>
#include <utility>
|
e8eb202f
David Mayerich
added a new ENVI ...
|
9
|
#include <vector>
|
3fc1d461
heziqi
Ziqi added saveBa...
|
10
11
12
13
14
15
16
17
18
|
namespace rts{
template <typename T>
class bsq: public binary<T> {
protected:
|
e8eb202f
David Mayerich
added a new ENVI ...
|
19
20
21
|
//envi_header header;
std::vector<double> w; //band wavelengths
|
6708cc25
heziqi
Ziqi added envi c...
|
22
|
unsigned int offset;
|
3fc1d461
heziqi
Ziqi added saveBa...
|
23
|
|
3fc1d461
heziqi
Ziqi added saveBa...
|
24
25
|
public:
|
fc712213
David Mayerich
code simplifications
|
26
27
28
|
using binary<T>::open;
using binary<T>::file;
using binary<T>::getSlice;
|
e8eb202f
David Mayerich
added a new ENVI ...
|
29
|
using binary<T>::R;
|
fc712213
David Mayerich
code simplifications
|
30
|
|
e933c14e
David Mayerich
cleaned up the code
|
31
|
//open a file, given the file name and dimensions
|
e8eb202f
David Mayerich
added a new ENVI ...
|
32
|
bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int B, unsigned int header_offset, std::vector<double> wavelengths){
|
3fc1d461
heziqi
Ziqi added saveBa...
|
33
|
|
e8eb202f
David Mayerich
added a new ENVI ...
|
34
35
|
//copy the wavelengths to the BSQ file structure
w = wavelengths;
|
6708cc25
heziqi
Ziqi added envi c...
|
36
37
|
//copy the wavelengths to the structure
offset = header_offset;
|
e8eb202f
David Mayerich
added a new ENVI ...
|
38
39
40
41
|
return open(filename, vec<unsigned int>(X, Y, B), header_offset);
return false;
|
3fc1d461
heziqi
Ziqi added saveBa...
|
42
43
44
|
}
|
e933c14e
David Mayerich
cleaned up the code
|
45
|
//retrieve one band (specified by the band index)
|
0e48cc9c
heziqi
Ziqi added getBan...
|
46
|
bool band_index( T * p, unsigned int page){
|
3fc1d461
heziqi
Ziqi added saveBa...
|
47
|
|
e8eb202f
David Mayerich
added a new ENVI ...
|
48
|
if (page >= R[2]){ //make sure the bank number is right
|
3fc1d461
heziqi
Ziqi added saveBa...
|
49
50
51
52
|
std::cout<<"ERROR: page out of range"<<std::endl;
return false;
}
|
31394e2a
heziqi
Ziqi added method...
|
53
|
getSlice(p, 2, page);
|
3fc1d461
heziqi
Ziqi added saveBa...
|
54
55
56
|
return true;
}
|
e933c14e
David Mayerich
cleaned up the code
|
57
58
|
//retrieve one band (specified by the wavelength)
bool band( T * p, double wavelength){
|
0e48cc9c
heziqi
Ziqi added getBan...
|
59
|
|
e8eb202f
David Mayerich
added a new ENVI ...
|
60
|
unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
|
0e48cc9c
heziqi
Ziqi added getBan...
|
61
62
63
64
65
66
67
68
|
unsigned page=0; //bands around the wavelength
T * p1;
T * p2;
//get the bands numbers around the wavelength
//if wavelength is smaller than the first one in header file
|
e8eb202f
David Mayerich
added a new ENVI ...
|
69
|
if ( w[page] > wavelength ){
|
0e48cc9c
heziqi
Ziqi added getBan...
|
70
71
72
73
|
band_index(p, page);
return true;
}
|
e8eb202f
David Mayerich
added a new ENVI ...
|
74
|
while( w[page] < wavelength )
|
0e48cc9c
heziqi
Ziqi added getBan...
|
75
76
77
|
{
page++;
//if wavelength is larger than the last wavelength in header file
|
e8eb202f
David Mayerich
added a new ENVI ...
|
78
79
|
if (page == R[2]) {
getSlice(p, 2, R[2]-1);
|
0e48cc9c
heziqi
Ziqi added getBan...
|
80
81
82
|
return true;
}
}
|
e8eb202f
David Mayerich
added a new ENVI ...
|
83
|
if ( wavelength < w[page] )
|
0e48cc9c
heziqi
Ziqi added getBan...
|
84
85
86
87
88
89
|
{
p1=(T*)malloc( XY * sizeof(T)); //memory allocation
p2=(T*)malloc( XY * sizeof(T));
band_index(p1, page - 1);
band_index(p2, page );
for(unsigned i=0; i < XY; i++){
|
e8eb202f
David Mayerich
added a new ENVI ...
|
90
|
double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
|
0e48cc9c
heziqi
Ziqi added getBan...
|
91
92
93
94
95
96
97
98
|
p[i] = (p2[i] - p1[i]) * r + p1[i];
}
}
else //if the wavelength is equal to a wavelength in header file
{
getSlice(p, 2, page);
}
|
0e48cc9c
heziqi
Ziqi added getBan...
|
99
100
101
|
return true;
}
|
3fc1d461
heziqi
Ziqi added saveBa...
|
102
|
//save one pixel of the file into the memory, and return the pointer
|
e933c14e
David Mayerich
cleaned up the code
|
103
|
bool spectrum(T * p, unsigned x, unsigned y){
|
3fc1d461
heziqi
Ziqi added saveBa...
|
104
105
106
|
unsigned int i;
|
e8eb202f
David Mayerich
added a new ENVI ...
|
107
|
if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right
|
3fc1d461
heziqi
Ziqi added saveBa...
|
108
109
110
111
|
std::cout<<"ERROR: sample or line out of range"<<std::endl;
return false;
}
|
e8eb202f
David Mayerich
added a new ENVI ...
|
112
113
|
file.seekg((x + y * R[0]) * sizeof(T), std::ios::beg); //point to the certain sample and line
for (i = 0; i < R[3]; i++)
|
3fc1d461
heziqi
Ziqi added saveBa...
|
114
115
|
{
file.read((char *)(p + i), sizeof(T));
|
e8eb202f
David Mayerich
added a new ENVI ...
|
116
|
file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band
|
3fc1d461
heziqi
Ziqi added saveBa...
|
117
118
|
}
|
3fc1d461
heziqi
Ziqi added saveBa...
|
119
120
|
return true;
}
|
f0d5a769
heziqi
Ziqi changed the ...
|
121
122
123
124
125
126
|
//baseline correction and save it into file
bool baseline(std::string outname, std::vector<double> wls )
{
unsigned N = wls.size(); //get the number of baseline points
|
31394e2a
heziqi
Ziqi added method...
|
127
|
|
f0d5a769
heziqi
Ziqi changed the ...
|
128
|
std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
|
0c748c81
heziqi
Ziqi added save h...
|
129
|
std::string headername = outname + ".hdr"; //the header file name
|
f0d5a769
heziqi
Ziqi changed the ...
|
130
131
|
//simplify image resolution
|
e8eb202f
David Mayerich
added a new ENVI ...
|
132
133
|
unsigned int B = R[2]; //calculate the number of bands
unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
|
f0d5a769
heziqi
Ziqi changed the ...
|
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
double ai, bi; //stores the two baseline points wavelength surrounding the current band
double ci; //stores the current band's wavelength
// unsigned aii, bii; //stores the two baseline points number surrounding the current band
unsigned control=0;
T * a; //pointers to the high and low band images
T * b;
T * c; //pointer to the current image
a = (T*)malloc( S ); //memory allocation
b = (T*)malloc( S );
c = (T*)malloc( S );
if (a == NULL || b == NULL || c == NULL){
std::cout<<"ERROR: error allocating memory";
exit(1);
}
//initialize lownum, highnum, low, high
|
e8eb202f
David Mayerich
added a new ENVI ...
|
156
|
ai=w[0];
|
f0d5a769
heziqi
Ziqi changed the ...
|
157
158
159
|
//if no baseline point is specified at band 0,
//set the baseline point at band 0 to 0
|
e8eb202f
David Mayerich
added a new ENVI ...
|
160
|
if(wls[0] != w[0]){
|
f0d5a769
heziqi
Ziqi changed the ...
|
161
162
163
164
165
166
|
bi = wls[control];
memset(a, (char)0, S);
}
//else get the low band
else{
control += 1;
|
e933c14e
David Mayerich
cleaned up the code
|
167
|
band(a, ai);
|
f0d5a769
heziqi
Ziqi changed the ...
|
168
169
170
|
bi = wls[control];
}
//get the high band
|
e933c14e
David Mayerich
cleaned up the code
|
171
|
band(b, bi);
|
f0d5a769
heziqi
Ziqi changed the ...
|
172
173
174
175
176
|
//correct every band
for(unsigned cii = 0; cii < B; cii++){
//update baseline points, if necessary
|
e8eb202f
David Mayerich
added a new ENVI ...
|
177
|
if( w[cii] >= bi && cii != B - 1) {
|
f0d5a769
heziqi
Ziqi changed the ...
|
178
179
180
181
182
183
184
185
186
|
//if the high band is now on the last BL point?
if (control != N-1) {
control++; //increment the index
std::swap(a, b); //swap the baseline band pointers
ai = bi;
bi = wls[control];
|
e933c14e
David Mayerich
cleaned up the code
|
187
|
band(b, bi);
|
f0d5a769
heziqi
Ziqi changed the ...
|
188
189
190
|
}
//if the last BL point on the last band of the file?
|
e8eb202f
David Mayerich
added a new ENVI ...
|
191
|
else if ( wls[control] < w[B - 1]) {
|
f0d5a769
heziqi
Ziqi changed the ...
|
192
193
194
195
196
197
|
std::swap(a, b); //swap the baseline band pointers
memset(b, (char)0, S); //clear the high band
ai = bi;
|
e8eb202f
David Mayerich
added a new ENVI ...
|
198
|
bi = w[B - 1];
|
f0d5a769
heziqi
Ziqi changed the ...
|
199
200
201
202
203
|
}
}
//get the current band
band_index(c, cii);
|
e8eb202f
David Mayerich
added a new ENVI ...
|
204
|
ci = w[cii];
|
f0d5a769
heziqi
Ziqi changed the ...
|
205
206
207
208
|
//perform the baseline correction
for(unsigned i=0; i < XY; i++){
double r = (double) (ci - ai) / (double) (bi - ai);
|
92e4cf05
heziqi
include file fixed
|
209
|
c[i] =(T) ( c[i] - (b[i] - a[i]) * r - a[i] );
|
f0d5a769
heziqi
Ziqi changed the ...
|
210
211
212
213
214
|
}
target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination
}
|
0c748c81
heziqi
Ziqi added save h...
|
215
|
|
e8eb202f
David Mayerich
added a new ENVI ...
|
216
|
//header.save(headername); //save the new header file
|
f0d5a769
heziqi
Ziqi changed the ...
|
217
218
219
220
221
222
223
|
free(a);
free(b);
free(c);
target.close();
return true;
}
|
089d9c81
heziqi
Ziqi added normal...
|
224
225
|
// normalize the BSQ file
|
e933c14e
David Mayerich
cleaned up the code
|
226
|
bool normalize(std::string outname, double w)
|
089d9c81
heziqi
Ziqi added normal...
|
227
|
{
|
e8eb202f
David Mayerich
added a new ENVI ...
|
228
229
|
unsigned int B = R[2]; //calculate the number of bands
unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
|
089d9c81
heziqi
Ziqi added normal...
|
230
231
232
233
234
235
236
237
238
239
240
|
unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file
std::string headername = outname + ".hdr"; //the header file name
T * b; //pointers to the certain wavelength band
T * c; //pointer to the current image
b = (T*)malloc( S ); //memory allocation
c = (T*)malloc( S );
|
e933c14e
David Mayerich
cleaned up the code
|
241
|
band(b, w); //get the certain band into memory
|
089d9c81
heziqi
Ziqi added normal...
|
242
243
244
245
246
247
248
249
250
251
252
|
for(unsigned j = 0; j < B; j++)
{
band_index(c, j); //get the current band into memory
for(unsigned i = 0; i < XY; i++)
{
c[i] = c[i] / b[i];
}
target.write(reinterpret_cast<const char*>(c), S); //write normalized data into destination
}
|
e8eb202f
David Mayerich
added a new ENVI ...
|
253
|
//header.save(headername); //save the new header file
|
089d9c81
heziqi
Ziqi added normal...
|
254
255
256
257
258
259
|
free(b);
free(c);
target.close();
return true;
}
|
f0d5a769
heziqi
Ziqi changed the ...
|
260
|
|
421219ba
heziqi
Ziqi added bip.h ...
|
261
262
263
|
//convert BSQ file to BIP file and save it
bool bip(std::string outname)
{
|
f6169dea
heziqi
Ziqi completed bi...
|
264
265
266
267
268
269
|
std::string temp = outname + "_temp";
std::string headtemp = temp + ".hdr";
//first creat a temporary bil file and convert bsq file to bil file
bil(temp);
rts::bil<T> n;
|
e933c14e
David Mayerich
cleaned up the code
|
270
|
if(n.open(temp, R[0], R[1], R[2], offset, w)==false){ //open infile
|
f6169dea
heziqi
Ziqi completed bi...
|
271
272
|
std::cout<<"ERROR: unable to open input file"<<std::endl;
exit(1);
|
421219ba
heziqi
Ziqi added bip.h ...
|
273
|
}
|
f6169dea
heziqi
Ziqi completed bi...
|
274
275
276
277
278
|
//then convert bil file to bip file
n.bip(outname);
n.close();
remove(temp.c_str());
remove(headtemp.c_str());
|
421219ba
heziqi
Ziqi added bip.h ...
|
279
280
|
return true;
}
|
c25e7d0d
heziqi
speed of bip.base...
|
281
282
283
284
285
|
//convert BSQ file to BIL file and save it
bool bil(std::string outname)
{
//simplify image resolution
|
6708cc25
heziqi
Ziqi added envi c...
|
286
|
unsigned int L = R[0] * R[2] * sizeof(T); //calculate the number of bytes of a ZX slice
|
e8eb202f
David Mayerich
added a new ENVI ...
|
287
|
unsigned int jump = (R[1] - 1) * R[0] * sizeof(T);
|
c25e7d0d
heziqi
speed of bip.base...
|
288
289
290
291
292
293
294
|
std::ofstream target(outname.c_str(), std::ios::binary);
std::string headername = outname + ".hdr";
T * p; //pointer to the current spectrum
p = (T*)malloc(L);
|
e8eb202f
David Mayerich
added a new ENVI ...
|
295
|
for ( unsigned i = 0; i < R[1]; i++)
|
c25e7d0d
heziqi
speed of bip.base...
|
296
|
{
|
e8eb202f
David Mayerich
added a new ENVI ...
|
297
298
|
file.seekg(R[0] * i * sizeof(T), std::ios::beg);
for ( unsigned j = 0; j < R[2]; j++ )
|
c25e7d0d
heziqi
speed of bip.base...
|
299
|
{
|
e8eb202f
David Mayerich
added a new ENVI ...
|
300
|
file.read((char *)(p + j * R[0]), sizeof(T) * R[0]);
|
c25e7d0d
heziqi
speed of bip.base...
|
301
302
303
304
|
file.seekg(jump, std::ios::cur); //go to the next band
}
target.write(reinterpret_cast<const char*>(p), L); //write XZ slice data into target file
}
|
e8eb202f
David Mayerich
added a new ENVI ...
|
305
306
|
//header.interleave = rts::envi_header::BIL; //change the type of file in header file
//header.save(headername);
|
c25e7d0d
heziqi
speed of bip.base...
|
307
308
309
310
311
|
free(p);
target.close();
return true;
}
|
421219ba
heziqi
Ziqi added bip.h ...
|
312
|
|
f6169dea
heziqi
Ziqi completed bi...
|
313
314
315
316
317
|
//close the file
bool close(){
file.close();
return true;
}
|
31394e2a
heziqi
Ziqi added method...
|
318
|
|
3fc1d461
heziqi
Ziqi added saveBa...
|
319
320
|
};
}
|
31394e2a
heziqi
Ziqi added method...
|
321
|
|
e8eb202f
David Mayerich
added a new ENVI ...
|
322
323
|
#endif
|
fc712213
David Mayerich
code simplifications
|
324
|
|