Commit 59b0e5f5edf6b0497e1a0c37d46acca5c542343d
1 parent
2119be83
updated envi file to support adding elements (like wavelength units)
Showing
3 changed files
with
67 additions
and
37 deletions
Show diff stats
docs/nwt_format.pptx
No preview for this file type
python/envi.py
... | ... | @@ -9,7 +9,6 @@ import os |
9 | 9 | import numpy |
10 | 10 | import scipy |
11 | 11 | import matplotlib.pyplot as plt |
12 | -#import pyprind | |
13 | 12 | import sys |
14 | 13 | from math import floor |
15 | 14 | import progressbar |
... | ... | @@ -186,31 +185,62 @@ class envi_header: |
186 | 185 | |
187 | 186 | #save an ENVI header |
188 | 187 | def save(self, fname): |
189 | - f = open(fname, "w") | |
190 | - f.write("ENVI\n") | |
191 | - f.write("description = {" + self.description + "}" + "\n") | |
192 | - f.write("samples = " + str(self.samples) + "\n") | |
193 | - f.write("lines = " + str(self.lines) + "\n") | |
194 | - f.write("bands = " + str(self.bands) + "\n") | |
195 | - f.write("header offset = " + str(self.header_offset) + "\n") | |
196 | - f.write("file type = ENVI Standard" + "\n") | |
197 | - f.write("data type = " + str(self.get_envi_type(self.type)) + "\n") | |
198 | - f.write("interleave = " + self.interleave + "\n") | |
199 | - f.write("sensor type = " + self.sensor_type + "\n") | |
200 | - f.write("byte order = " + str(self.byte_order) + "\n") | |
201 | - f.write("x start = " + str(self.x_start) + "\n") | |
202 | - f.write("y start = " + str(self.y_start) + "\n") | |
203 | - f.write("wavelength units = " + self.wavelength_units + "\n") | |
204 | - f.write("z plot titles = {" + self.z_plot_titles + "}" + "\n") | |
188 | + f = open(fname, "w") | |
189 | + f.write("ENVI\n") | |
190 | + f.write("description = {" + self.description + "}" + "\n") | |
191 | + f.write("samples = " + str(self.samples) + "\n") | |
192 | + f.write("lines = " + str(self.lines) + "\n") | |
193 | + f.write("bands = " + str(self.bands) + "\n") | |
194 | + f.write("header offset = " + str(self.header_offset) + "\n") | |
195 | + f.write("file type = ENVI Standard" + "\n") | |
196 | + f.write("data type = " + str(self.get_envi_type(self.type)) + "\n") | |
197 | + f.write("interleave = " + self.interleave + "\n") | |
198 | + f.write("sensor type = " + self.sensor_type + "\n") | |
199 | + f.write("byte order = " + str(self.byte_order) + "\n") | |
200 | + f.write("x start = " + str(self.x_start) + "\n") | |
201 | + f.write("y start = " + str(self.y_start) + "\n") | |
202 | + f.write("wavelength units = " + self.wavelength_units + "\n") | |
203 | + f.write("z plot titles = {" + self.z_plot_titles + "}" + "\n") | |
204 | + | |
205 | + # save the wavelength values | |
206 | + if self.wavelength != []: | |
207 | + if len(self.wavelength) == self.bands: | |
208 | + f.write("wavelength = {") | |
209 | + f.write(",".join(map(str, self.wavelength))) | |
210 | + f.write("}\n") | |
211 | + else: | |
212 | + raise Exception("ENVI HEADER ERROR: Number of wavelengths does not match number of bands") | |
205 | 213 | |
206 | - f.close() | |
214 | + f.close() | |
207 | 215 | |
208 | 216 | #sets the properties of the header to match those of the input array |
209 | - def set(self, A): | |
210 | - self.type = A.dtype | |
211 | - self.samples = A.shape[2] | |
212 | - self.lines = A.shape[1] | |
213 | - self.bands = A.shape[0] | |
217 | + def setprops(self, A, interleave="BSQ", wavelength=[]): | |
218 | + # determine the data type automatically | |
219 | + self.type = A.dtype | |
220 | + | |
221 | + # determine the ordering based on the specified interleave | |
222 | + if interleave == "BSQ": | |
223 | + self.samples = A.shape[2] | |
224 | + self.lines = A.shape[1] | |
225 | + self.bands = A.shape[0] | |
226 | + elif interleave == "BIP": | |
227 | + self.samples = A.shape[1] | |
228 | + self.lines = A.shape[2] | |
229 | + self.bands = A.shape[0] | |
230 | + elif interleave == "BIL": | |
231 | + self.samples = A.shape[0] | |
232 | + self.lines = A.shape[2] | |
233 | + self.bands = A.shape[1] | |
234 | + else: | |
235 | + raise Exception("invalid interleave format (requires 'BSQ', 'BIP', or 'BIL') - interleave is set to {}".interleave) | |
236 | + | |
237 | + # if wavelength units are given, make sure that they match the number of bands | |
238 | + if wavelength != []: | |
239 | + if len(wavelength) != self.bands: | |
240 | + raise Exception("invalid number of wavelengths specified") | |
241 | + else: | |
242 | + self.wavelength = wavelength | |
243 | + | |
214 | 244 | |
215 | 245 | |
216 | 246 | class envi: |
... | ... | @@ -413,8 +443,8 @@ class envi: |
413 | 443 | #read a batch of data based on the mask |
414 | 444 | def loadbatch(self, npixels): |
415 | 445 | i = numpy.flatnonzero(self.mask) #get the indices of valid pixels |
416 | - if len(i) == self.idx: #if all of the pixels have been read, return an empyt array | |
417 | - return [] | |
446 | + if len(i) == self.idx: #if all of the pixels have been read, return an empyt array | |
447 | + return [] | |
418 | 448 | npixels = min(npixels, len(i) - self.idx) #if there aren't enough pixels, change the batch size |
419 | 449 | B = self.header.bands |
420 | 450 | |
... | ... | @@ -439,14 +469,14 @@ class envi: |
439 | 469 | |
440 | 470 | #returns an image of the pixels that have been read using batch loading |
441 | 471 | def batchmask(self): |
442 | - #allocate a new mask | |
443 | - outmask = numpy.zeros(self.mask.shape, dtype=numpy.bool) | |
472 | + #allocate a new mask | |
473 | + outmask = numpy.zeros(self.mask.shape, dtype=numpy.bool) | |
444 | 474 | |
445 | - #zero out any unclassified pixels | |
446 | - idx = self.getidx() | |
447 | - i = numpy.nonzero(self.mask) | |
448 | - outmask[i[0][0:idx], i[1][0:idx]] = self.mask[i[0][0:idx], i[1][0:idx]] | |
449 | - return outmask | |
475 | + #zero out any unclassified pixels | |
476 | + idx = self.getidx() | |
477 | + i = numpy.nonzero(self.mask) | |
478 | + outmask[i[0][0:idx], i[1][0:idx]] = self.mask[i[0][0:idx], i[1][0:idx]] | |
479 | + return outmask | |
450 | 480 | |
451 | 481 | def close(self): |
452 | 482 | self.file.close() |
... | ... | @@ -455,11 +485,11 @@ class envi: |
455 | 485 | self.file.close() |
456 | 486 | |
457 | 487 | #saves an array as an ENVI file |
458 | -def save_envi(A, fname): | |
488 | +def save_envi(A, fname, interleave="BSQ", wavelength=[]): | |
459 | 489 | |
460 | 490 | #create and save a header file |
461 | 491 | header = envi_header(); |
462 | - header.set(A) | |
492 | + header.setprops(A, interleave, wavelength) | |
463 | 493 | header.save(fname + ".hdr") |
464 | 494 | |
465 | 495 | #save the raw data | ... | ... |
python/muve-align.py
... | ... | @@ -96,8 +96,8 @@ def align(A, B, max_power=5): |
96 | 96 | #warp_matrix[0, 2] = 0 |
97 | 97 | # return warp_matrix |
98 | 98 | |
99 | -fmask = "Z:/jack/TinkParaffinLung0.005S/*.png" | |
100 | -out_dir = "Z:/jack/TinkParaffinLung0.005S/aligned" | |
99 | +fmask = "D:/Dropbox/todo/lab-presentations/jack/TinkParaffinLung0.005S/*.png" | |
100 | +out_dir = "D:/Dropbox/todo/lab-presentations/jack/TinkParaffinLung0.005S/aligned" | |
101 | 101 | |
102 | 102 | if not os.path.isdir(out_dir): |
103 | 103 | os.mkdir(out_dir) |
... | ... | @@ -155,4 +155,4 @@ ax.set_xlabel("Press 'z' and 'x' to change slices and arrow keys to align") |
155 | 155 | plt.show() |
156 | 156 | |
157 | 157 | I = apply_alignment(S, warps) |
158 | -imagestack.save(I, out_dir + "/aligned_", ".bmp") | |
159 | 158 | \ No newline at end of file |
159 | +imagestack.save(I, out_dir + "/aligned_", "bmp") | |
160 | 160 | \ No newline at end of file | ... | ... |