diff --git a/matlab/brewermap.m b/matlab/brewermap.m new file mode 100644 index 0000000..0a2c521 --- /dev/null +++ b/matlab/brewermap.m @@ -0,0 +1,28 @@ +function result = stimBrewerColormap(R) + +%returns a Brewer colormap with the specified resolution R + +ctrlPts = zeros(11, 3); + +ctrlPts(1, :) = [0.192157, 0.211765, 0.584314]; +ctrlPts(2, :) = [0.270588, 0.458824, 0.705882]; +ctrlPts(3, :) = [0.454902, 0.678431, 0.819608]; +ctrlPts(4, :) = [0.670588, 0.85098, 0.913725]; +ctrlPts(5, :) = [0.878431, 0.952941, 0.972549]; +ctrlPts(6, :) = [1, 1, 0.74902]; +ctrlPts(7, :) = [0.996078, 0.878431, 0.564706]; +ctrlPts(8, :) = [0.992157, 0.682353, 0.380392]; +ctrlPts(9, :) = [0.956863, 0.427451, 0.262745]; +ctrlPts(10, :) = [0.843137, 0.188235, 0.152941]; +ctrlPts(11, :) = [0.647059, 0, 0.14902]; + +X = 1:11; + +r = 1:11/R:11; + +R = interp1(X, ctrlPts(:, 1), r); +G = interp1(X, ctrlPts(:, 2), r); +B = interp1(X, ctrlPts(:, 3), r); + +result = [R' G' B']; + diff --git a/matlab/enviClose.m b/matlab/enviClose.m new file mode 100644 index 0000000..3ee3283 --- /dev/null +++ b/matlab/enviClose.m @@ -0,0 +1,3 @@ +function rtsEnviClose(enviFID) + +fclose(enviFID.fid); \ No newline at end of file diff --git a/matlab/enviID.m b/matlab/enviID.m new file mode 100644 index 0000000..b8e67f5 --- /dev/null +++ b/matlab/enviID.m @@ -0,0 +1,8 @@ +classdef enviID < handle + properties + fid + header + mask + fpos + end +end \ No newline at end of file diff --git a/matlab/enviLoadHeader.m b/matlab/enviLoadHeader.m new file mode 100644 index 0000000..f0cb5ae --- /dev/null +++ b/matlab/enviLoadHeader.m @@ -0,0 +1,78 @@ +function s = enviLoadHeader(filename) +%create a cell array of fields +s = struct; + +fid = fopen(filename, 'r', 'n', 'US-ASCII'); + +%read the first field and make sure it is "ENVI" +fname = GetFieldName(fid); +if strcmp(fname, 'ENVI') == 0 + disp('Not an ENVI header file'); + return; +end + +while feof(fid) == 0 + fname = GetFieldName(fid); + if feof(fid) == 1 + return; + end + [value, valid] = ReadField(fid, fname); + if valid == 1 + s = setfield(s, fname, value); + end +end +fclose(fid); + +function t = GetFieldName(fid) +string_struct = textscan(fid, '%s', 1, 'Delimiter', '='); +if feof(fid) == 1 + t = []; + return; +end +t = string_struct{1}{1}; +t = strtrim(t); +t(t==' ') = '_'; + +function [v, valid] = ReadField(fid, field_name) +valid = 1; +stringFields = {'file_type', 'interleave', 'sensor_type', 'wavelength_units'}; +intFields = {'samples', 'lines', 'bands', 'header_offset', 'data_type', 'byte_order'}; + +%if the field is "description", read between the brackets +if strcmp(field_name, 'description') == 1 + textscan(fid, '%[{]', 1); + string_struct = textscan(fid, '%[^}]', 1, 'Whitespace', ''); + textscan(fid, '%[}]', 1); + v = string_struct{1}{1}; + v = strtrim(v); + return; +end +if max(strcmp(field_name, intFields)) ~= 0 + v = fscanf(fid, '%d'); + return; +end +if max(strcmp(field_name, stringFields)) ~= 0 + string_struct = textscan(fid, '%s', 1, 'Whitespace', '\n'); + v = string_struct{1}{1}; + v = strtrim(v); + return; +end + +%read and return the wavelength values +if strcmp(field_name, 'wavelength') == 1 + v = []; + textscan(fid, '%[{]', 1); + c = ' '; + while c ~= '}' + new = fscanf(fid, '%f'); + v = [v new]; + c = fscanf(fid, '%c', 1); + end + return; +end + +%if it doesn't match anything, just read until the end of the line +%string_struct = textscan(fid, '%s', 1, 'Whitespace', '\n'); +string_struct = textscan(fid, '%s', 1, 'Delimiter', '\n'); +v = ''; +valid = 0; diff --git a/matlab/enviOpen.m b/matlab/enviOpen.m new file mode 100644 index 0000000..e159aec --- /dev/null +++ b/matlab/enviOpen.m @@ -0,0 +1,35 @@ +function EID = rtsEnviOpen(filename, headername, mask) + +%opens an ENVI file and returns an ID structure +% filename = name of ENVI file +% headername = name of ENVI header +% FID = structure containing file information +% mask = binary image specifying valid spectra + +%assign the mask variable +if(nargin < 3) + mask = 1; +end + +%open the file and save the file ID +fid = fopen(filename, 'r'); + +%open the ENVI header file +header = enviLoadHeader(headername); + +%this is currently only valid for BIP files +if(~strcmp(header.interleave, 'bip')) + disp('Error: This function only works for BIP interleave files. Load in ENVI and convert.'); +end +if(header.data_type ~= 4) + disp('Error: This function only works for floating-point files.'); +end + +EID = enviID; +EID.fid = fid; +EID.header = header; +EID.mask = mask; +EID.fpos = 0; + +%EID = struct('fid', fid, 'header', header, 'mask', mask, 'fpos', 0); + diff --git a/matlab/enviRead.m b/matlab/enviRead.m new file mode 100644 index 0000000..d46db6c --- /dev/null +++ b/matlab/enviRead.m @@ -0,0 +1,68 @@ +function S = rtsEnviRead(fid, batchSize) + +%This function reads a batch of spectra from the given ENVI file ID +% fid = ENVI file ID created using rtsEnviOpen +% batchSize = number of spectra to read + +%if there is no mask, just load each spectrum in order +if(fid.mask == 1) + + %compute the new batch size in case we are near the eof + nSpectra = fid.header.samples * fid.header.lines; + remainingSpectra = nSpectra - fid.fpos; + + if(batchSize > remainingSpectra) + batchSize = remainingSpectra; + end + + S = fread(fid.fid, [fid.header.bands batchSize], '*float32'); + + %increment the fid counter + fid.fpos = fid.fpos + batchSize; + +%otherwise only load valid spectra +else + + %compute the new batch size in case we are near the eof + if(fid.fpos == 0) + remainingSpectra = nnz(fid.mask); + else + nSpectra = nnz(fid.mask); + maskRead = fid.mask(1:fid.fpos+1); + remainingSpectra = nSpectra - nnz(maskRead); + end + + if(batchSize > remainingSpectra) + batchSize = remainingSpectra; + end + + %allocate space for the spectra + S = zeros(fid.header.bands, batchSize); + + %for each spectrum in the batch + for s = 1:batchSize + + %while the current spectrum is invalid + skip = 0; + while (~fid.mask(fid.fpos + 1)) + %read the invalid spectrum + %invalid = fread(fid.fid, [fid.header.bands 1], '*float32'); + skip = skip + 1; + + %increment the file position + fid.fpos = fid.fpos + 1; + end + fseek(fid.fid, skip * fid.header.bands * 4, 'cof'); + + test = fread(fid.fid, [fid.header.bands 1], '*float32'); + if size(test) ~= size(S(:, s)) + size(test) + size(S(:, s)) + end + S(:, s) = test; + fid.fpos = fid.fpos + 1; + + end + +end + -- libgit2 0.21.4