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
.
.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}
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.')
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.