# This file was extracted from the HV SDK Docusaurus examples. # It is intended as a downloadable, runnable companion to the documentation. # Set HSI_EXAMPLE_BASE_DIR and related env vars to use your own data. # Source page: /hsi/hv_sdk/examples/basics#snv # region: setup import os from pathlib import Path import matplotlib.pyplot as plt import numpy as np import qtec_hv_sdk as hs from qtec_hv_sdk.preprocessing import make_reference from qtec_hv_sdk.preprocessing import reflectance_calibration from qtec_hv_sdk.preprocessing import snv BASE_DIR = Path(os.environ.get("HSI_EXAMPLE_BASE_DIR", "/path/to/HSI_data/nuts")) if not BASE_DIR.exists(): raise SystemExit( "Run: 'export HSI_EXAMPLE_BASE_DIR=/path/to/HSI_data/' to setup the " "folder containing the example datacubes." ) CUBE = os.environ.get("HSI_EXAMPLE_CUBE", "mix1.pam") DARK_REF = os.environ.get("HSI_EXAMPLE_DARK_REF", "dark_ref.pam") WHITE_REF = os.environ.get("HSI_EXAMPLE_WHITE_REF", "white_ref.pam") WAVELENGTH_MIN_NM = 430.0 WAVELENGTH_MAX_NM = 1700.0 def make_references(): dark = hs.open(str(BASE_DIR / DARK_REF)) white = hs.open(str(BASE_DIR / WHITE_REF)) return make_reference(dark), make_reference(white) def add_camera_wavelengths(img): # Example PAM cubes may not include wavelengths; attach them so downstream # wavelength-based code can use img.meta.spectral.wavelengths. if img.meta.spectral.wavelengths is not None: return img meta = img.meta meta.spectral = hs.SpectralMeta( wavelengths=hs.WavelengthMeta( np.linspace(WAVELENGTH_MIN_NM, WAVELENGTH_MAX_NM, img.meta.shape.bands), hs.WavelengthUnit.Nanometer, ) ) return img.with_meta(meta) def open_reflectance_cube(cube_name=CUBE): dark_ref, white_ref = make_references() img = add_camera_wavelengths(hs.open(str(BASE_DIR / cube_name))) return reflectance_calibration(img, white_ref, dark_ref, clip=True) def wavelengths_for_image(img): wavelengths = img.meta.spectral.wavelengths if wavelengths is None: raise ValueError("This image does not contain wavelength metadata.") if wavelengths.unit != hs.WavelengthUnit.Nanometer: raise ValueError(f"Expected wavelengths in nm, got {wavelengths.unit}.") return np.array(wavelengths.band_data) # end region # region: example reflectance = open_reflectance_cube() snv_reflectance = snv(reflectance) line = reflectance.array_plane(300, hs.lines).T snv_line = snv_reflectance.array_plane(300, hs.lines).T print(f"Raw line shape: {line.shape}") print(f"SNV line shape: {snv_line.shape}") samples = [530, 962] wavelengths = wavelengths_for_image(reflectance) fig, axes = plt.subplots(1, 2, figsize=(12, 4), sharex=True) for sample in samples: axes[0].plot(wavelengths, line[sample], label=f"sample {sample}") axes[1].plot(wavelengths, snv_line[sample], label=f"sample {sample}") axes[0].set_title("Reflectance spectra") axes[0].set_ylabel("Reflectance") axes[1].set_title("SNV spectra") axes[1].set_ylabel("SNV") for ax in axes: ax.set_xlabel("Wavelength [nm]") ax.grid(True, alpha=0.3) ax.legend() fig.tight_layout() plt.show() # end region