Generate a Preview for a PushBroom

This example will connect to the virtual pushbroom camera (using MiniCube.hdr and its references), create a instrument preview processing context for the PushBroom and run it for 10 frames. It will display the first 6 pixels of each of these lines.

Note

The behavior of this example changed slightly in version 4.11 with the virtual camera; in previous versions it would depend on the camera driver whether the wavelengths were averaged, but starting in version 4.11 the spectral bands are always averaged for previews, regardless of the specific camera driver.

C++

The source code of the example can be found in the file example_pushbroom_preview.cpp:

  1#if defined(_WIN32) && defined(_MSC_VER)
  2#include <windows.h>
  3#endif
  4
  5#include <iostream>
  6#include <iomanip>
  7#include <string>
  8#include <fstream>
  9#include <streambuf>
 10#include <algorithm>
 11#include <utility>
 12
 13#include <cstddef>
 14
 15#include <fluxEngine/fluxEngine>
 16
 17#include "paths.h"
 18#include "helpers.h"
 19
 20int main()
 21{
 22    try {
 23        std::cout << "fluxEngine version: " << fluxEngine::versionString() << std::endl;
 24        fluxEngine::Handle handle(readFile(g_licenseFileName));
 25        handle.setDriverBaseDirectory(g_driverDirectory);
 26        handle.setDriverIsolationExecutable(g_driverIsolationExecutable);
 27        handle.createProcessingThreads(4);
 28
 29        // Create a processing context
 30        fluxEngine::EnumerationResult enumeratedDevices = fluxEngine::enumerateDevices(handle, -1, std::chrono::seconds{1});
 31        fluxEngine::EnumeratedDevice* virtualCameraDevice = nullptr;
 32        for (auto const& device : enumeratedDevices.devices) {
 33            if (device->driver->name == "VirtualHyperCamera") {
 34                virtualCameraDevice = device.get();
 35                break;
 36            }
 37        }
 38
 39        if (!virtualCameraDevice)
 40            throw std::runtime_error("Could not find virtual camera driver");
 41
 42        fluxEngine::ConnectionSettings connectionSettings;
 43        connectionSettings.driverName = virtualCameraDevice->driver->name;
 44        connectionSettings.driverType = virtualCameraDevice->driver->type;
 45        connectionSettings.id = virtualCameraDevice->id;
 46        connectionSettings.timeout = std::chrono::seconds{60};
 47        connectionSettings.connectionParameters["Cube"] = encodeFileNameForConnectionParameter(g_cubeFileName);
 48        connectionSettings.connectionParameters["WhiteReferenceCube"] = encodeFileNameForConnectionParameter(g_whiteCubeFileName);
 49        connectionSettings.connectionParameters["DarkReferenceCube"] = encodeFileNameForConnectionParameter(g_darkCubeFileName);
 50
 51        std::cout << "Attempting to connect to device...\n" << std::flush;
 52        fluxEngine::DeviceGroup deviceGroup = fluxEngine::connectDeviceGroup(handle, connectionSettings);
 53        std::cout << "Connected.\n" << std::flush;
 54        fluxEngine::InstrumentDevice* camera = dynamic_cast<fluxEngine::InstrumentDevice*>(deviceGroup.primaryDevice());
 55        if (!camera) {
 56            deviceGroup.disconnect(std::chrono::seconds{5});
 57            throw std::runtime_error("The device is not an instrument device");
 58        }
 59
 60        camera->setupInternalBuffers(5);
 61
 62        // Create preview context
 63        fluxEngine::ProcessingContext ctx = fluxEngine::ProcessingContext::createInstrumentPreviewContext(camera);
 64
 65        std::cout << "Starting acquisition:\n" << std::flush;
 66        fluxEngine::InstrumentDevice::AcquisitionParameters acqParams;
 67        camera->startAcquisition(acqParams);
 68        std::cout << "Done.\n" << std::flush;
 69
 70        std::cout << "Generating preview \"image\" for the first 10 lines:\n" << std::flush;
 71        int count = 0;
 72        while (count < 10) {
 73            fluxEngine::BufferInfo buffer = camera->retrieveBuffer(std::chrono::milliseconds{100});
 74            if (!buffer.ok)
 75                continue;
 76
 77            ctx.setSourceData(buffer);
 78            ctx.processNext();
 79
 80            fluxEngine::TensorData data{ctx.outputSinkData(0)};
 81            // Output the first 6 pixels of the preview for each line
 82            if (data.dataType() == fluxEngine::DataType::Float64) {
 83                for (int x = 0; x < 6; ++x) {
 84                    if (x > 0)
 85                        std::cout << ' ';
 86                    std::cout << std::setw(20) << data.at<double>(0, x, 0) << std::setw(0);
 87                }
 88                std::cout << '\n' << std::flush;
 89            } else if (data.dataType() == fluxEngine::DataType::Float32) {
 90                for (int x = 0; x < 6; ++x) {
 91                    if (x > 0)
 92                        std::cout << ' ';
 93                    std::cout << std::setw(20) << data.at<float>(0, x, 0) << std::setw(0);
 94                }
 95                std::cout << '\n' << std::flush;
 96            }
 97
 98            camera->returnBuffer(buffer.id);
 99            ++count;
100        }
101
102        std::cout << "Stopping acquisition:\n" << std::flush;
103        camera->stopAcquisition();
104        std::cout << "Done.\n" << std::flush;
105    } catch (std::exception& e) {
106        std::cerr << "Error: " << e.what() << std::endl;
107        return 1;
108    } catch (...) {
109        std::cerr << "Unknown error." << std::endl;
110        return 1;
111    }
112
113    return 0;
114}

This source file will compile to the executable ExamplePushBroomPreview.

The following classes and methods are among those used in this example:

.NET

The source code of the example can be found in the file ExamplePushBroomPreview\Program.cs.

  1using System;
  2
  3namespace ExamplePushBroomPreview
  4{
  5    class Program
  6    {
  7        static void Main(string[] args)
  8        {
  9            Console.WriteLine("fluxEngine version: " + LuxFlux.fluxEngineNET.Version.String);
 10            var handle = new LuxFlux.fluxEngineNET.Handle(ExampleHelpers.IO.ReadLicenseFile());
 11            handle.SetDriverBaseDirectory(ExampleHelpers.Paths.DriverDirectory);
 12            handle.CreateProcessingThreads(4);
 13
 14            // Load virtual camera
 15            var enumeratedDevices = LuxFlux.fluxEngineNET.DeviceEnumeration.EnumerateDevices(handle, null, TimeSpan.FromSeconds(1));
 16            LuxFlux.fluxEngineNET.EnumeratedDevice virtualCameraDevice = null;
 17            foreach (var device in enumeratedDevices.Devices)
 18            {
 19                if (device.Driver.Name == "VirtualHyperCamera")
 20                {
 21                    virtualCameraDevice = device;
 22                    break;
 23                }
 24            }
 25
 26            if (virtualCameraDevice == null)
 27                throw new Exception("Could not find virtual camera driver");
 28
 29            var connectionSettings = new LuxFlux.fluxEngineNET.ConnectionSettings();
 30            connectionSettings.DriverName = virtualCameraDevice.Driver.Name;
 31            connectionSettings.DriverType = virtualCameraDevice.Driver.Type;
 32            connectionSettings.Id = virtualCameraDevice.Id;
 33            connectionSettings.Timeout = TimeSpan.FromSeconds(60);
 34            connectionSettings.ConnectionParameters = new System.Collections.Generic.Dictionary<string, string>();
 35            connectionSettings.ConnectionParameters["Cube"] = ExampleHelpers.Paths.ExampleDataFileName("MiniCube.hdr");
 36            connectionSettings.ConnectionParameters["WhiteReferenceCube"] = ExampleHelpers.Paths.ExampleDataFileName("MiniCube_White.hdr");
 37            connectionSettings.ConnectionParameters["DarkReferenceCube"] = ExampleHelpers.Paths.ExampleDataFileName("MiniCube_Dark.hdr");
 38
 39            Console.WriteLine("Attempting to connect to device...");
 40            var deviceGroup = LuxFlux.fluxEngineNET.DeviceGroup.Connect(handle, connectionSettings);
 41            Console.WriteLine("Connected.");
 42            if (!(deviceGroup.PrimaryDevice is LuxFlux.fluxEngineNET.InstrumentDevice))
 43            {
 44                deviceGroup.Disconnect(TimeSpan.FromSeconds(5));
 45                throw new Exception("The device is not an instrument device.");
 46            }
 47            var camera = (LuxFlux.fluxEngineNET.InstrumentDevice)deviceGroup.PrimaryDevice;
 48
 49            camera.SetupInternalBuffers(5);
 50
 51            // Create preview context
 52            var ctx = LuxFlux.fluxEngineNET.ProcessingContext.CreateForInstrumentPreview(camera);
 53
 54            Console.WriteLine("Starting acquisition:");
 55            var acqParams = new LuxFlux.fluxEngineNET.InstrumentDevice.AcquisitionParameters();
 56            camera.StartAcquisition(acqParams);
 57            Console.WriteLine("Done.");
 58
 59            Console.WriteLine("Generating preview \"image\" for the first 10 lines:");
 60            int count = 0;
 61            while (count < 10)
 62            {
 63                var buffer = camera.RetrieveBuffer(TimeSpan.FromMilliseconds(100));
 64                if (buffer == null)
 65                    continue;
 66
 67                try
 68                {
 69                    ctx.SetSourceData(buffer);
 70                    ctx.ProcessNext();
 71
 72                    var data = ctx.OutputSinkData(0).AsTensorCopy();
 73                    // Output the first 6 pixels of the preview for each line
 74                    if (data.DataType == LuxFlux.fluxEngineNET.DataType.Float64)
 75                    {
 76                        for (int x = 0; x < 6; ++x)
 77                        {
 78                            if (x > 0)
 79                                Console.Write(" ");
 80                            Console.Write(string.Format("{0,20}", data.Value<double>(0, x, 0)));
 81                        }
 82                        Console.WriteLine("");
 83                    }
 84                    else if (data.DataType == LuxFlux.fluxEngineNET.DataType.Float32)
 85                    {
 86                        for (int x = 0; x < 6; ++x)
 87                        {
 88                            if (x > 0)
 89                                Console.Write(" ");
 90                            Console.Write(string.Format("{0,20}", data.Value<float>(0, x, 0)));
 91                        }
 92                        Console.WriteLine("");
 93                    }
 94
 95                }
 96                finally
 97                {
 98                    camera.ReturnBuffer(buffer);
 99                }
100
101                ++count;
102            }
103
104            Console.WriteLine("Stopping acquisition:");
105            camera.StopAcquisition();
106            Console.WriteLine("Done.");
107
108            Console.WriteLine("Disconnecting from device...");
109            deviceGroup.Disconnect(TimeSpan.FromSeconds(5));
110            Console.WriteLine("Done.");
111            handle.Dispose();
112        }
113    }
114}

The following classes and methods are among those used in this example:

Python

The source code of the example can be found in the file example_pushbroom_preview.py:

 1#!/usr/bin/env python3
 2
 3import fluxEngine
 4import os, sys
 5
 6import fluxEngine_example_paths as paths
 7data_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data')
 8
 9print('fluxEngine version {}'.format(fluxEngine.versionString()))
10with open(paths.licenseFileName, 'rb') as f:
11    handle = fluxEngine.Handle(f.read())
12handle.setDriverBaseDirectory(paths.driverDirectory)
13handle.createProcessingThreads(4)
14
15enumeratedDevices = fluxEngine.enumerateDevices(handle, -1, 5000)
16virtualCameraDevice = None
17for device in enumeratedDevices.devices:
18    if device.driver.name == 'VirtualHyperCamera':
19        virtualCameraDevice = device
20
21if not virtualCameraDevice:
22    raise Exception('Could not find virtual camera driver')
23
24connectionSettings = fluxEngine.ConnectionSettings(virtualCameraDevice.driver.name, virtualCameraDevice.driver.type, virtualCameraDevice.id)
25connectionSettings.timeout = 60000
26connectionSettings.connectionParameters['Cube'] = os.path.join(data_dir, 'MiniCube.hdr')
27connectionSettings.connectionParameters['WhiteReferenceCube'] = os.path.join(data_dir, 'MiniCube_White.hdr')
28connectionSettings.connectionParameters['DarkReferenceCube'] = os.path.join(data_dir, 'MiniCube_Dark.hdr')
29
30print("Attempting to connect to device...")
31deviceGroup = fluxEngine.DeviceGroup(handle, connectionSettings)
32print("Connected.")
33
34camera = deviceGroup.primaryDevice()
35if not isinstance(camera, fluxEngine.InstrumentDevice):
36    deviceGroup.disconnect(5000)
37    raise Exception('The device is not an instrument device')
38
39camera.setupInternalBuffers(5)
40
41acqParams = fluxEngine.InstrumentDevice.AcquisitionParameters()
42
43# Create preview contect
44context = fluxEngine.ProcessingContext(None, fluxEngine.ProcessingContext.InstrumentPreview,
45                                       device=camera)
46
47print('Starting acquisition:')
48acqParams.referenceName = None
49camera.startAcquisition(acqParams)
50print('Done.')
51
52print('Generating preview "image" for the first 10 lines:')
53count = 0
54while count < 10:
55    buffer = camera.retrieveBuffer(100)
56    if not buffer:
57        continue
58
59    context.setSourceData(buffer)
60    context.processNext()
61    data = context.outputSinkData(0)
62    print(data[0, :6, 0])
63    camera.returnBuffer(buffer)
64    count += 1
65print('Done.')
66
67print('Stopping acquisition:')
68camera.stopAcquisition()
69print('Done.')

The following classes and methods are among those used in this example:

Expected Output

The output should look like the following:

fluxEngine version: [...]
Attempting to connect to device...
Connected.
Starting acquisition:
Done.
Generating preview "image" for the first 10 lines:
             7217.22              7160.26              7168.58              7146.76              7159.23              7192.86
             7348.53              7317.49              7322.11              7314.67              7316.54              7305.82
             7441.55              7431.62              7447.21               7439.7               7431.3              7396.99
             7485.26              7476.21               7511.7              7488.82              7479.78              7450.21
             7516.45              7492.98              7555.88              7512.07              7508.67              7492.33
             7539.83              7494.71              7578.19              7520.96              7533.36              7524.27
             7553.11               7498.3              7589.73               7525.6               7552.7              7546.77
              7570.4              7507.74              7596.02              7532.91              7581.62              7576.05
             7597.72              7538.99              7609.41              7555.27              7619.44              7610.17
             7635.46              7582.75              7630.93              7591.69              7655.63              7643.03
Stopping acquisition:
Done.