X
2580

How to pass a spectral library to the ENVISpectralAngleMapperTask

ENVI's SpectralAngleMapperClassificationTask can accept training statistics from regions of interest (ROIs), vectors and also from spectral libraries.  When using ROIs or Vectors with an image for classification, the pixels within the ROI or Vector are used to calculate statistics such as the mean per band for that class which can then be used in ENVI's classification tasks.  Additionally, if you plot the mean for an ROI or vector class, it will be a spectrum representing the mean of the training class.  These plotted means from ROIs and Vectors can also be saved as spectral libraries.

However, spectral libraries often are created from another source, such as a different image, a field radiometer, or materials measured in a lab.  If a spectral library comes from a source other than your input image and has additional (or fewer) spectral bands than your image, it is necessary to resample the spectral library to match the same wavelengths and bands as the input image for classification.  In this case, the resampled spectrum, with one (reflectance or radiance) value per band, is considered a 'mean' for a class just as if you calculated the mean of an ROI or vector extracted from the image to create a mean spectrum for a class. 

The following example will open a hyperspectral image and spectral library from the ENVI distribution, then resample the spectral library to match the wavelengths of the hyperspectral image using ENVIResampleSpectrumTask.  The results of the spectral library resampling is stored in a nBands x nClasses (spectral library) array which can be passed as the MEAN for the ENVISpectralAngleMapperClassificationTask.

;================================

pro SAMclassWithSpeclib
compile_opt idl2

e=envi()

; Open a spectral library
specLibFile = FILEPATH('veg_2grn.sli', ROOT_DIR=e.ROOT_DIR, $
  SUBDIR=['resource', 'speclib', 'veg_lib'])
specLib = ENVISpectralLibrary(specLibFile)
  
; Open a hyperspectral image
file = FILEPATH('AVIRISReflectanceSubset.dat', $
  ROOT_DIR=e.ROOT_DIR, $
  SUBDIRECTORY = ['data', 'hyperspectral'])
raster = e.OpenRaster(file)

  ; Get wavelength units of raster
  Task1 = ENVITask('RasterMetadataItem')
  Task1.INPUT_RASTER = raster
  Task1.KEY = 'Wavelength Units'
  Task1.Execute
   
  ; Get wavelengths of raster
  Task2 = ENVITask('RasterMetadataItem')
  Task2.INPUT_RASTER = raster
  Task2.KEY = 'Wavelength'
  Task2.Execute
    
  ;create an array to hold resampled spectra
  class_means = make_array(n_elements(Task2.VALUE.value), n_elements(speclib.spectra_name))

  ;loop through the spectral library resampling all spectra
  foreach iterator_1, speclib.spectra_name, iterator_1_index do begin

    ; Get the selected spectrum from spectral library
    Task3 = ENVITask('GetSpectrumFromLibrary')
    Task3.INPUT_SPECTRAL_LIBRARY = specLib
    Task3.SPECTRUM_NAME = speclib.spectra_name[iterator_1_index]
    Task3.Execute
        
    ; Get the resample spectrum task from the catalog of ENVITasks
    Task4 = ENVITask('ResampleSpectrum')
    
    ; Define inputs
    ; Spectrum from library to be resampled
    Task4.INPUT_SPECTRUM = Task3.SPECTRUM
    
    ; Wavelengths from spectral library
    Task4.INPUT_WAVELENGTHS = Task3.WAVELENGTHS
    
    ; Wavelength units from spectral library
    Task4.INPUT_WAVELENGTH_UNITS = Task3.WAVELENGTH_UNITS
    
    ; Wavelengths from raster
    Task4.RESAMPLE_WAVELENGTHS = Task2.VALUE.value
    
    ; Wavelength units from raster
    Task4.RESAMPLE_WAVELENGTH_UNITS = Task1.VALUE.value
    
    ; Run the resample spectrum task
    Task4.Execute
    
    ; add resampled spectra to array
    class_means[*, iterator_1_index] = task4.output_spectrum

endforeach

  ; Get the task from the catalog of ENVITasks
  Task = ENVITask('SpectralAngleMapperClassification')
   
  ; Define inputs
  Task.INPUT_RASTER = Raster
  Task.MEAN = class_means
  Task.Threshold_angle = [0.1]
   
  ; Define outputs
  Task.OUTPUT_RASTER_URI = e.GetTemporaryFilename()
   
  ; Run the task
  Task.Execute
  
  ; Get the collection of data objects currently available in the Data Manager
  DataColl = e.Data

  ; Add the output to the Data Manager
  DataColl.Add, Task.Output_Raster

  ; Display the result
  View1 = e.GetView()
  Layer1 = View1.CreateLayer(Task.Output_Raster)
  
end

;================================

Created by MM on 12/15/2017

Review by PS on 12/18/2017