5. Tutorial: spec_mod

5.1. Sample data

Sample imagery captured from a Resonon Pika II VIS-NIR line scanning imager and ancillary sample files can be downloaded from this link.

Before trying this tutorial on your own machine, please download the sample files and place into a local directory of your choosing (and do not change the file names). Indicate the location of your sample files by modifying data_dir:

[1]:
data_dir = r'F:\\nigo0024\Documents\hs_process_demo'

5.2. Confirm your environment

Before trying the tutorials, be sure hs_process and its dependencies are properly installed. If you installed in a virtual environment, first check we are indeed using the Python instance that was installed with the virtual environment:

[2]:
import sys

print('Python install location: {0}'.format(sys.executable))
Python install location: C:\Users\nigo0024\AppData\Local\Continuum\anaconda3\envs\spec\python.exe

The spec folder that contains python.exe tells me that the activated Python instance is indeed in the spec environment, just as I intend. If you created a virtual environment, but your python.exe is not in the envs\spec directory, you either did not properly create your virtual environment or you are not pointing to the correct Python installation in your IDE (e.g., Spyder, Jupyter notebook, etc.).


5.3. spec_mod.load_spyfile

Loads a SpyFile (Spectral Python object) for data access and/or manipulation by the hstools class. [API]

Load and initialize the hsio and spec_mod modules

[3]:
import os
from hs_process import hsio
from hs_process import spec_mod

fname_in = os.path.join(data_dir, 'Wells_rep2_20180628_16h56m_pika_gige_7-Radiance Conversion-Georectify Airborne Datacube-Convert Radiance Cube to Reflectance from Measured Reference Spectrum.bip.hdr')
io = hsio(fname_in)
my_spec_mod = spec_mod(io.spyfile)

Load datacube using spec_mod.load_spyfile

[4]:
my_spec_mod.load_spyfile(io.spyfile)
my_spec_mod.spyfile
[4]:
        Data Source:   'F:\\nigo0024\Documents\hs_process_demo\Wells_rep2_20180628_16h56m_pika_gige_7-Radiance Conversion-Georectify Airborne Datacube-Convert Radiance Cube to Reflectance from Measured Reference Spectrum.bip'
        # Rows:            617
        # Samples:        1300
        # Bands:           240
        Interleave:        BIP
        Quantization:  32 bits
        Data format:   float32

5.4. spec_mod.spectral_clip

Removes/clips designated wavelength bands from the hyperspectral datacube. [API]

Load and initialize the hsio and spec_mod modules

[5]:
from hs_process import hsio
from hs_process import spec_mod

fname_hdr = os.path.join(data_dir, 'Wells_rep2_20180628_16h56m_pika_gige_7-Radiance Conversion-Georectify Airborne Datacube-Convert Radiance Cube to Reflectance from Measured Reference Spectrum.bip.hdr')
io1 = hsio()
io1.read_cube(fname_hdr)
my_spec_mod = spec_mod(io1.spyfile)

Using spec_mod.spectral_clip, clip all spectral bands below 420 nm and above 880 nm, as well as the bands near the oxygen absorption (i.e., 760-776 nm) and water absorption (i.e., 813-827 nm) regions.

[6]:
array_clip, metadata = my_spec_mod.spectral_clip(wl_bands=[[0, 420], [760, 776], [813, 827], [880, 1000]])

Save the clipped datacube

[7]:
fname_hdr_clip = os.path.join(data_dir, 'spec_mod', 'Wells_rep2_20180628_16h56m_pika_gige_7-clip.bip.hdr')
if not os.path.isdir(os.path.dirname(fname_hdr_clip)):  # create a new folder named "spec_mod" if it does not exist
    os.mkdir(os.path.dirname(fname_hdr_clip))

io1.write_cube(fname_hdr_clip, array_clip, metadata)
Saving F:\nigo0024\Documents\hs_process_demo\spec_mod\Wells_rep2_20180628_16h56m_pika_gige_7-clip.bip

Initialize a second instance of hsio and read in the clipped cube to compare the clipped cube to the unclipped cube

[8]:
io2 = hsio()  # initialize a second instance to compare cubes
io2.read_cube(fname_hdr_clip)
io1.spyfile
[8]:
        Data Source:   'F:\\nigo0024\Documents\hs_process_demo\Wells_rep2_20180628_16h56m_pika_gige_7-Radiance Conversion-Georectify Airborne Datacube-Convert Radiance Cube to Reflectance from Measured Reference Spectrum.bip'
        # Rows:            617
        # Samples:        1300
        # Bands:           240
        Interleave:        BIP
        Quantization:  32 bits
        Data format:   float32

The unclipped cube (above) has 240 spectral bands, while the clipped cube (below) has 210.

[9]:
io2.spyfile
[9]:
        Data Source:   'F:\\nigo0024\Documents\hs_process_demo\spec_mod\Wells_rep2_20180628_16h56m_pika_gige_7-clip.bip'
        # Rows:            617
        # Samples:        1300
        # Bands:           210
        Interleave:        BIP
        Quantization:  32 bits
        Data format:   float32

5.5. spec_mod.spectral_smooth

Performs Savitzky-Golay smoothing on the spectral domain. [API]

Load and initialize the hsio and spec_mod modules

[10]:
from hs_process import hsio
from hs_process import spec_mod

fname_hdr = os.path.join(data_dir, 'Wells_rep2_20180628_16h56m_pika_gige_7-Radiance Conversion-Georectify Airborne Datacube-Convert Radiance Cube to Reflectance from Measured Reference Spectrum.bip.hdr')
io = hsio()
io.read_cube(fname_hdr)
my_spec_mod = spec_mod(io.spyfile)

Use spec_mod.spectral_smooth to perform a Savitzky-Golay smoothing operation across the hyperspectral spectral signature.

[11]:
array_smooth, metadata = my_spec_mod.spectral_smooth(window_size=11, order=2)

Save the smoothed datacube using hsio.write_cube

[12]:
fname_hdr_smooth = os.path.join(data_dir, 'spec_mod', 'Wells_rep2_20180628_16h56m_pika_gige_7-smooth.bip.hdr')
io.write_cube(fname_hdr_smooth, array_smooth, metadata)
Saving F:\nigo0024\Documents\hs_process_demo\spec_mod\Wells_rep2_20180628_16h56m_pika_gige_7-smooth.bip

Open smoothed datacube in Spectronon software to visualize the result of the smoothing for a specific pixel. Before smoothing (the spectral curve of the pixel at the 800th column/sample and 200th row/line is plotted): |spectral\_smooth\_before|

And after smoothing (the spectral curve of the pixel at the 800th column/sample and 200th row/line is plotted): |spectral\_smooth\_after|