Commit dcdf12762ce9d96cef57811135b790edd8c99697
Merge branch 'master' of https://github.com/dmayerich/stim
Ziqi added the bip.h file.
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 | \ No newline at end of file | 272 | \ No newline at end of file |