Basic usage

The Hypervision SDK is designed to make working with hyperspectral data as simple as possible. Let’s look at an example:

img = hs.open("<path-to-file>")
print(img.shape)
img = img - 10
hs.write(img, "<path-to-output>")
// Open a file and convert it to an image object
hv_hsi_file_t* file;
int err = hv_hsi_file_open("<path-to-file>", &file);
hv_image_t* img = hv_hsi_file_to_image(&file);

// Read and print the image shape
hv_shape_t* shape;
hv_image_shape(img, &shape);
char* shape_str = hv_shape_debug_fmt(shape);
printf("%s", shape_str);
free(shape_str)

// Perform scalar subtraction
hv_image_t* sub_img = hv_image_sub_scalar_u8(img, 10);
hv_image_free(&img);

// Write the result to a file
hv_image_write(sub_img, "<path-to-output>");
hv_image_free(&sub_img);

The example opens a hyperspectral image file, prints its shape, creates an operation which performs scalar subtraction on the image, and writes the result to a new file. The Python version clearly reflects these four steps. The C version is more complex but can still be divided into these four steps.

Importantly, the hs.open() function and the hs.Image.sub() method don’t perform their operation immediately when called. Instead, they are only applied when output is requested, which, in the example, happens in the hs.write() function.

To get data out of a computation to use in further processing, the hs.Image.to_numpy() and hs.Image.array_plane() methods are particularly useful:

img = hs.open("<path-to-file>")
array = img.to_numpy() # Get the full 3d cube
slice_2d = img.array_plane(200, hs.bands) # Get a grayscale image of a single wavelength band.
// Open a file and convert it to an image object
hv_hsi_file_t* file;
int err = hv_hsi_file_open("<path-to-file>", &file);
hv_image_t* img = hv_hsi_file_to_image(&file);

// Get the full 3d cube
hv_array_t* array;
err = hv_image_full(img, &array);

// Get a grayscale image of a single wavelength band.
hv_array_t* slice_2d;
err = hv_image_array_plane(img, 200, HV_AXIS_BANDS, &slice_2d);

Both of these also initiate the computation when called.

Finally, the hs.Image.resolve() method runs the computation, but returns a new hs.Image with the result contained in a three-dimensional array. This operation is useful for caching intermediate results.

Important

The methods that are used to construct computation pipelines return immediately, because no computation is performed. As a consequence, the operations that run the computations are both blocking and can take a while to run. It is therefore important to think about how you construct pipelines and when you should cache the result.

Interacting with NumPy

The hs.Image provides conversions to/from NumPy. The memory layout of the file or image determines the layout of the numpy.ndarray that is returned or used as input (see Hyperspectral data for details on the memory layout of HSI files).

Conversions to NumPy can be done directly using the hs.Image.to_numpy() method.

a = hs.open("path/to/file.hdr").to_numpy()

The interleave can be changed using hs.Image.to_numpy_with_interleave():

a = hs.open("path/to/file.hdr").to_numpy_with_interleave(hs.bil)

You can also create a new hs.Image object directly from a NumPy array:

img = hs.Image.from_numpy(a, interleave=hs.bsq)