Commit 88c3e6360038b1fab492c1c15a69d5fcc793df77
1 parent
421219ba
Ziqi added big.h
Showing
1 changed file
with
271 additions
and
0 deletions
Show diff stats
1 | +#include "../envi/envi.h" | |
2 | +#include "../envi/binary.h" | |
3 | +#include <cstring> | |
4 | +#include <utility> | |
5 | + | |
6 | +namespace rts{ | |
7 | + | |
8 | +template <typename T> | |
9 | + | |
10 | +class bip: public binary<T> { | |
11 | + | |
12 | +protected: | |
13 | + | |
14 | + envi header; | |
15 | + | |
16 | +public: | |
17 | + | |
18 | + using binary<T>::open; | |
19 | + using binary<T>::file; | |
20 | + using binary<T>::getSlice; | |
21 | + | |
22 | + //open a file, given the file and its header's names | |
23 | + bool open(std::string filename, std::string headername){ | |
24 | + | |
25 | + if (header.load(headername)==false){ | |
26 | + std::cout<<"ERROR: unable to load header file: "<<headername<<std::endl; | |
27 | + return false; | |
28 | + } | |
29 | + | |
30 | + open(filename, vec<unsigned int>(header.samples, header.lines, header.bands), header.header_offset); | |
31 | + return true; | |
32 | + | |
33 | + } | |
34 | + | |
35 | + //save one band of the file into the memory, and return the pointer | |
36 | + bool band_index( T * p, unsigned int page){ | |
37 | + | |
38 | + if (page >= header.bands){ //make sure the bank number is right | |
39 | + std::cout<<"ERROR: page out of range"<<std::endl; | |
40 | + return false; | |
41 | + } | |
42 | + | |
43 | + getSlice(p, 0, page); | |
44 | + return true; | |
45 | + } | |
46 | + | |
47 | + bool getBand( T * p, double wavelength){ | |
48 | + | |
49 | + unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band | |
50 | + | |
51 | + unsigned page=0; //bands around the wavelength | |
52 | + T * p1; | |
53 | + T * p2; | |
54 | + | |
55 | + //get the bands numbers around the wavelength | |
56 | + | |
57 | + //if wavelength is smaller than the first one in header file | |
58 | + if ( header.wavelength[page] > wavelength ){ | |
59 | + band_index(p, page); | |
60 | + return true; | |
61 | + } | |
62 | + | |
63 | + while( header.wavelength[page] < wavelength ) | |
64 | + { | |
65 | + page++; | |
66 | + //if wavelength is larger than the last wavelength in header file | |
67 | + if (page == header.bands) { | |
68 | + band_index(p, header.bands-1); | |
69 | + return true; | |
70 | + } | |
71 | + } | |
72 | + if ( wavelength < header.wavelength[page] ) | |
73 | + { | |
74 | + p1=(T*)malloc( XY * sizeof(T)); //memory allocation | |
75 | + p2=(T*)malloc( XY * sizeof(T)); | |
76 | + band_index(p1, page - 1); | |
77 | + band_index(p2, page ); | |
78 | + for(unsigned i=0; i < XY; i++){ | |
79 | + double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); | |
80 | + p[i] = (p2[i] - p1[i]) * r + p1[i]; | |
81 | + } | |
82 | + } | |
83 | + else //if the wavelength is equal to a wavelength in header file | |
84 | + { | |
85 | + band_index(p, page); | |
86 | + } | |
87 | + | |
88 | + free(p1); | |
89 | + free(p2); | |
90 | + return true; | |
91 | + } | |
92 | + | |
93 | + //save one pixel of the BIP file into the memory, and return the pointer | |
94 | + bool getSpectrum(T * p, unsigned x, unsigned y){ | |
95 | + | |
96 | + unsigned int i; | |
97 | + | |
98 | + if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right | |
99 | + std::cout<<"ERROR: sample or line out of range"<<std::endl; | |
100 | + return false; | |
101 | + } | |
102 | + | |
103 | + file.seekg((x + y * header.samples) * header.bands * sizeof(T), std::ios::beg); //point to the certain sample and line | |
104 | + | |
105 | + file.read((char *)p, sizeof(T) * header.bands); | |
106 | + | |
107 | + return true; | |
108 | + } | |
109 | + // not finished yet | |
110 | + //(BIP) baseline correction | |
111 | + bool baseline(std::string outname, std::vector<double> wls ) | |
112 | + { | |
113 | + unsigned N = wls.size(); //get the number of baseline points | |
114 | + | |
115 | + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file | |
116 | + std::string headername = outname + ".hdr"; //the header file name | |
117 | + | |
118 | + //simplify image resolution | |
119 | + unsigned int B = header.bands; //calculate the number of bands | |
120 | + unsigned int L = B * sizeof(T); | |
121 | + | |
122 | + T* c; //pointer to the current spectrum | |
123 | + c = (T*)malloc(L); | |
124 | + | |
125 | + } | |
126 | + | |
127 | + | |
128 | + /* | |
129 | + //(BSQ)baseline correction and save it into file | |
130 | + | |
131 | + bool baseline(std::string outname, std::vector<double> wls ) | |
132 | + { | |
133 | + unsigned N = wls.size(); //get the number of baseline points | |
134 | + | |
135 | + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file | |
136 | + std::string headername = outname + ".hdr"; //the header file name | |
137 | + | |
138 | + //simplify image resolution | |
139 | + unsigned int B = header.bands; //calculate the number of bands | |
140 | + unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band | |
141 | + unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band | |
142 | + | |
143 | + double ai, bi; //stores the two baseline points wavelength surrounding the current band | |
144 | + double ci; //stores the current band's wavelength | |
145 | +// unsigned aii, bii; //stores the two baseline points number surrounding the current band | |
146 | + unsigned control=0; | |
147 | + | |
148 | + T * a; //pointers to the high and low band images | |
149 | + T * b; | |
150 | + T * c; //pointer to the current image | |
151 | + | |
152 | + a = (T*)malloc( S ); //memory allocation | |
153 | + b = (T*)malloc( S ); | |
154 | + c = (T*)malloc( S ); | |
155 | + | |
156 | + if (a == NULL || b == NULL || c == NULL){ | |
157 | + std::cout<<"ERROR: error allocating memory"; | |
158 | + exit(1); | |
159 | + } | |
160 | + | |
161 | + | |
162 | + //initialize lownum, highnum, low, high | |
163 | + ai=header.wavelength[0]; | |
164 | + | |
165 | + //if no baseline point is specified at band 0, | |
166 | + //set the baseline point at band 0 to 0 | |
167 | + if(wls[0] != header.wavelength[0]){ | |
168 | + bi = wls[control]; | |
169 | + memset(a, (char)0, S); | |
170 | + } | |
171 | + //else get the low band | |
172 | + else{ | |
173 | + control += 1; | |
174 | + getBand(a, ai); | |
175 | + bi = wls[control]; | |
176 | + } | |
177 | + //get the high band | |
178 | + getBand(b, bi); | |
179 | + | |
180 | + //correct every band | |
181 | + for(unsigned cii = 0; cii < B; cii++){ | |
182 | + | |
183 | + //update baseline points, if necessary | |
184 | + if( header.wavelength[cii] >= bi && cii != B - 1) { | |
185 | + //if the high band is now on the last BL point? | |
186 | + if (control != N-1) { | |
187 | + | |
188 | + control++; //increment the index | |
189 | + | |
190 | + std::swap(a, b); //swap the baseline band pointers | |
191 | + | |
192 | + ai = bi; | |
193 | + bi = wls[control]; | |
194 | + getBand(b, bi); | |
195 | + | |
196 | + } | |
197 | + //if the last BL point on the last band of the file? | |
198 | + else if ( wls[control] < header.wavelength[B - 1]) { | |
199 | + | |
200 | + std::swap(a, b); //swap the baseline band pointers | |
201 | + | |
202 | + memset(b, (char)0, S); //clear the high band | |
203 | + | |
204 | + ai = bi; | |
205 | + bi = header.wavelength[B - 1]; | |
206 | + } | |
207 | + } | |
208 | + | |
209 | + //get the current band | |
210 | + band_index(c, cii); | |
211 | + ci = header.wavelength[cii]; | |
212 | + | |
213 | + //perform the baseline correction | |
214 | + for(unsigned i=0; i < XY; i++){ | |
215 | + double r = (double) (ci - ai) / (double) (bi - ai); | |
216 | + c[i] =(float) ( c[i] - (b[i] - a[i]) * r - a[i] ); | |
217 | + } | |
218 | + | |
219 | + target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination | |
220 | + | |
221 | + } | |
222 | + | |
223 | + header.save(headername); //save the new header file | |
224 | + | |
225 | + free(a); | |
226 | + free(b); | |
227 | + free(c); | |
228 | + target.close(); | |
229 | + return true; | |
230 | + } | |
231 | +*/ | |
232 | + // normalize the BSQ file | |
233 | + bool normalize(std::string outname, double band) | |
234 | + { | |
235 | + unsigned int B = header.bands; //calculate the number of bands | |
236 | + unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band | |
237 | + unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band | |
238 | + | |
239 | + std::ofstream target(outname.c_str(), std::ios::binary); //open the target binary file | |
240 | + std::string headername = outname + ".hdr"; //the header file name | |
241 | + | |
242 | + T * b; //pointers to the certain wavelength band | |
243 | + T * c; //pointer to the current image | |
244 | + | |
245 | + b = (T*)malloc( S ); //memory allocation | |
246 | + c = (T*)malloc( S ); | |
247 | + | |
248 | + getBand(b, band); //get the certain band into memory | |
249 | + | |
250 | + for(unsigned j = 0; j < B; j++) | |
251 | + { | |
252 | + band_index(c, j); //get the current band into memory | |
253 | + for(unsigned i = 0; i < XY; i++) | |
254 | + { | |
255 | + c[i] = c[i] / b[i]; | |
256 | + } | |
257 | + target.write(reinterpret_cast<const char*>(c), S); //write normalized data into destination | |
258 | + std::cout<<j<<std::endl; | |
259 | + } | |
260 | + | |
261 | + header.save(headername); //save the new header file | |
262 | + | |
263 | + free(b); | |
264 | + free(c); | |
265 | + target.close(); | |
266 | + return true; | |
267 | + } | |
268 | + | |
269 | + | |
270 | + }; | |
271 | +} | |
0 | 272 | \ No newline at end of file | ... | ... |