Basic usage

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

img = hsi.open("<path-to-file>")
print(img.shape)
img = img - 10
hsi.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_hs_image_t* img = hv_hsi_file_to_image(&file);

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

// Perform scalar subtraction
hv_hs_image_t* sub_img = hv_hs_image_sub_scalar_u8(img, 10);
hv_hs_image_free(&img);

// Write the result to a file
hv_hs_image_write(sub_img, "<path-to-output>");
hv_hs_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 hsi.open() function and the hsi.HSImage.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 hsi.write() function.

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

img = hsi.open("<path-to-file>")
array = img.to_numpy() # Get the full 3d cube
slice_2d = img.array_plane(200, hsi.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_hs_image_t* img = hv_hsi_file_to_image(&file);

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

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

Both of these also initiate the computation when called.

Finally, the hsi.HSImage.resolve() method runs the computation, but returns a new hsi.HSImage 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 hsi.HSImage provides conversions to/from NumPy. The memory layout of the file or image determines the layout of the ndarray that is returned or used as input (see Hyperspectral data for details on the layout of the 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 hsi.HSImage.to_numpy() method.

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

The interleave can be changed using hsi.HSImage.to_numpy_with_interleave():

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

You can also create a new hsi.HSImage object directly from a NumPy array:

img = hsi.HSImage.from_numpy(a, interleave=hsi.bsq)