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