Obtain a frame from a camera

This example will connect to the virtual pushbroom camera (using MiniCube.hdr and its references), obtain a single frame, and display the values of the upper left 4x4 pixels of the frame.

C++

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

  1#if defined(_WIN32) && defined(_MSC_VER)
  2#include <windows.h>
  3#endif
  4
  5#include <iostream>
  6#include <string>
  7#include <fstream>
  8#include <streambuf>
  9#include <algorithm>
 10#include <utility>
 11
 12#include <cstddef>
 13
 14#include <fluxEngine/fluxEngine>
 15
 16#include "paths.h"
 17#include "helpers.h"
 18
 19static std::string toString(fluxEngine::ParameterInfo::Type type)
 20{
 21    switch (type) {
 22    case fluxEngine::ParameterInfo::Type::Unknown: return "Unknown";
 23    case fluxEngine::ParameterInfo::Type::Boolean: return "Boolean";
 24    case fluxEngine::ParameterInfo::Type::Integer: return "Integer";
 25    case fluxEngine::ParameterInfo::Type::Float: return "Float";
 26    case fluxEngine::ParameterInfo::Type::Enumeration: return "Enumeration";
 27    case fluxEngine::ParameterInfo::Type::String: return "String";
 28    case fluxEngine::ParameterInfo::Type::File: return "File";
 29    case fluxEngine::ParameterInfo::Type::Command: return "Command";
 30    default: return "Unknown (Invalid type)";
 31    }
 32}
 33
 34int main()
 35{
 36    try {
 37        std::cout << "fluxEngine version: " << fluxEngine::versionString() << std::endl;
 38        fluxEngine::Handle handle(readFile(g_licenseFileName));
 39        handle.setDriverBaseDirectory(g_driverDirectory);
 40        handle.setDriverIsolationExecutable(g_driverIsolationExecutable);
 41        handle.createProcessingThreads(4);
 42
 43        // Load virtual camera
 44        fluxEngine::EnumerationResult enumeratedDevices = fluxEngine::enumerateDevices(handle, -1, std::chrono::seconds{1});
 45        fluxEngine::EnumeratedDevice* virtualCameraDevice = nullptr;
 46        for (auto const& device : enumeratedDevices.devices) {
 47            if (device->driver->name == "VirtualHyperCamera") {
 48                virtualCameraDevice = device.get();
 49                break;
 50            }
 51        }
 52
 53        if (!virtualCameraDevice)
 54            throw std::runtime_error("Could not find virtual camera driver");
 55
 56        fluxEngine::ConnectionSettings connectionSettings;
 57        connectionSettings.driverName = virtualCameraDevice->driver->name;
 58        connectionSettings.driverType = virtualCameraDevice->driver->type;
 59        connectionSettings.id = virtualCameraDevice->id;
 60        connectionSettings.timeout = std::chrono::seconds{60};
 61        connectionSettings.connectionParameters["Cube"] = encodeFileNameForConnectionParameter(g_cubeFileName);
 62        connectionSettings.connectionParameters["WhiteReferenceCube"] = encodeFileNameForConnectionParameter(g_whiteCubeFileName);
 63        connectionSettings.connectionParameters["DarkReferenceCube"] = encodeFileNameForConnectionParameter(g_darkCubeFileName);
 64
 65        std::cout << "Attempting to connect to device...\n" << std::flush;
 66        fluxEngine::DeviceGroup deviceGroup = fluxEngine::connectDeviceGroup(handle, connectionSettings);
 67        std::cout << "Connected.\n" << std::flush;
 68        fluxEngine::InstrumentDevice* camera = dynamic_cast<fluxEngine::InstrumentDevice*>(deviceGroup.primaryDevice());
 69        if (!camera) {
 70            deviceGroup.disconnect(std::chrono::seconds{5});
 71            throw std::runtime_error("The device is not an instrument device");
 72        }
 73
 74        fluxEngine::ParameterInfo parameterList = camera->parameterList(fluxEngine::Device::ParameterListType::Parameter);
 75        std::vector<std::string> const parameterNames = parameterList.parameterNames();
 76        std::cout << "Device parameters:\n";
 77        for (auto const& parameterName : parameterNames) {
 78            std::cout << "  - " << parameterName << " (" << toString(parameterList.parameterType(parameterName)) << ")\n";
 79            if (parameterList.parameterType(parameterName) == fluxEngine::ParameterInfo::Type::Enumeration) {
 80                std::vector<std::string> const enumerationEntryNames = parameterList.enumerationEntryNames(parameterName);
 81                for (auto const& entryName : enumerationEntryNames) {
 82                    int64_t value = parameterList.enumerationEntryValue(parameterName, entryName);
 83                    std::cout << "    - " << entryName << " = " << value << "\n";
 84                }
 85            }
 86        }
 87        if (!parameterNames.size())
 88            std::cout << "  - (none)\n";
 89        std::cout << std::flush;
 90
 91        camera->setupInternalBuffers(5);
 92
 93        std::cout << "Starting acquisition:\n" << std::flush;
 94        fluxEngine::InstrumentDevice::AcquisitionParameters acqParams;
 95        camera->startAcquisition(acqParams);
 96        std::cout << "Done.\n" << std::flush;
 97
 98        std::cout << "Obtaining buffer:\n" << std::flush;
 99        fluxEngine::BufferInfo buffer = camera->retrieveBuffer(std::chrono::seconds{10});
100        if (!buffer.ok)
101            throw std::runtime_error("Could not obtain a buffer from the camera within 10 seconds.");
102        std::cout << "Done.\n" << std::flush;
103
104        if (buffer.order != 2)
105            throw std::runtime_error("Expected a camera with a two-dimensional buffer.");
106
107        // Copy the data into our own memory area and
108        // potentially convert it to Float32.
109        std::size_t totalCount = std::size_t(buffer.dimensions[0] * buffer.dimensions[1]);
110        std::vector<float> values;
111        values.resize(totalCount);
112        std::array<int64_t, 5> strides;
113        strides[1] = 1;
114        strides[0] = buffer.dimensions[1];
115        buffer.copyRawData(values.data(), fluxEngine::DataType::Float32, strides);
116        camera->returnBuffer(buffer.id);
117
118        std::cout << "Stopping acquisition:\n" << std::flush;
119        camera->stopAcquisition();
120        std::cout << "Done.\n" << std::flush;
121
122        for (int y = 0; y < 5; ++y) {
123            for (int x = 0; x < 5; ++x) {
124                std::size_t index = std::size_t(y * strides[0] + x * strides[1]);
125                std::cout << "Pixel value @(" << x << ", " << y << ") = " << values[index] << "\n";
126            }
127        }
128        std::cout << std::flush;
129    } catch (std::exception& e) {
130        std::cerr << "Error: " << e.what() << std::endl;
131        return 1;
132    } catch (...) {
133        std::cerr << "Unknown error." << std::endl;
134        return 1;
135    }
136
137    return 0;
138}

This source file will compile to the executable ExampleObtainCameraBuffer.

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 ExampleObtainCameraBuffer\Program.cs.

  1using System;
  2
  3namespace ExampleObtainCameraBuffer
  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            var parameterList = camera.ParameterList(LuxFlux.fluxEngineNET.Device.ParameterListType.Parameter);
 50            var parameterNames = parameterList.ParameterNames;
 51            Console.WriteLine("Device parameters:");
 52            foreach (var parameterName in parameterNames)
 53            {
 54                var type = parameterList.ParameterType(parameterName);
 55                Console.WriteLine($"  - {parameterName} ({type})");
 56                if (type == LuxFlux.fluxEngineNET.ParameterList.Type.Enumeration)
 57                {
 58                    var enumerationEntryNames = parameterList.EnumerationEntryNames(parameterName);
 59                    foreach (var entryName in enumerationEntryNames)
 60                    {
 61                        Int64 value = parameterList.EnumerationEntryValue(parameterName, entryName);
 62                        Console.WriteLine($"    - {entryName} = {value}");
 63                    }
 64                }
 65            }
 66            if (parameterNames.Count == 0)
 67                Console.WriteLine("  - (none)");
 68
 69            camera.SetupInternalBuffers(5);
 70
 71            Console.WriteLine("Starting acquisition:");
 72            var acqParams = new LuxFlux.fluxEngineNET.InstrumentDevice.AcquisitionParameters();
 73            camera.StartAcquisition(acqParams);
 74            Console.WriteLine("Done.");
 75
 76            Console.WriteLine("Obtaining buffer:");
 77            var buffer = camera.RetrieveBuffer(TimeSpan.FromSeconds(10));
 78            if (buffer == null)
 79                throw new Exception("Could not obtain a buffer from the camera within 10 seconds.");
 80
 81            LuxFlux.fluxEngineNET.GenericTensor bufferData;
 82
 83            try
 84            {
 85                Console.WriteLine("Done.");
 86
 87                if (buffer.Order != 2)
 88                    throw new Exception("Expected a camera with a two-dimensional buffer.");
 89
 90                // Create a copy of the data in the buffer, and auto-convert it to Float32
 91                // (so we don't have to care what the original data was stored in)
 92                bufferData = new LuxFlux.fluxEngineNET.GenericTensor(LuxFlux.fluxEngineNET.DataType.Float32, buffer.Dimensions);
 93                buffer.CopyInto(bufferData);
 94            }
 95            finally
 96            {
 97                camera.ReturnBuffer(buffer);
 98            }
 99
100            Console.WriteLine("Stopping acquisition:");
101            camera.StopAcquisition();
102            Console.WriteLine("Done.");
103
104            for (int y = 0; y < 5; ++y)
105            {
106                for (int x = 0; x < 5; ++x)
107                {
108                    Console.WriteLine($"Pixel value @({x}, {y}) = {bufferData.Value<float>(y, x)}");
109                }
110            }
111
112            Console.WriteLine("Disconnecting from device...");
113            deviceGroup.Disconnect(TimeSpan.FromSeconds(5));
114            Console.WriteLine("Done.");
115            handle.Dispose();
116        }
117    }
118}

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_obtain_camera_buffer.py:

 1#!/usr/bin/env python3
 2
 3import fluxEngine
 4import os
 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
39deviceSettings = camera.parameterList(fluxEngine.Device.ParameterListType.Parameter)
40print('Device parameters:')
41parameterList = deviceSettings.parameters()
42if len(parameterList):
43    for parameter in parameterList:
44        print('  - {} ({})'.format(parameter.name, parameter.type))
45        if parameter.type == fluxEngine.ParameterInfo.Type.Enumeration:
46            for entry in parameter.enumerationEntries():
47                print('    - {} = {}'.format(entry.name, entry.value))
48else:
49    print('  - (none)')
50
51camera.setupInternalBuffers(5)
52
53print('Starting acquisition:')
54acqParams = fluxEngine.InstrumentDevice.AcquisitionParameters()
55camera.startAcquisition(acqParams)
56print('Done.')
57
58print('Obtaining buffer:')
59buffer = camera.retrieveBuffer(10000)
60if buffer is None:
61    raise Exception('Could not obtain a buffer from the camera within 10 seconds.')
62print('Done.')
63
64values = buffer.getData()
65camera.returnBuffer(buffer)
66
67print('Stopping acquisition:')
68camera.stopAcquisition()
69print('Done.')
70
71print('The upper left corner of pixel values:')
72print(values[:5,:5])

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.
Device parameters:
- Interval (Integer)
Starting acquisition:
Done.
Obtaining buffer:
Done.
Stopping acquisition:
Done.
Pixel value @(0, 0) = 6153
Pixel value @(1, 0) = 5114
Pixel value @(2, 0) = 6143
Pixel value @(3, 0) = 7069
Pixel value @(4, 0) = 7856
Pixel value @(0, 1) = 6143
Pixel value @(1, 1) = 5099
Pixel value @(2, 1) = 6119
Pixel value @(3, 1) = 6966
Pixel value @(4, 1) = 7805
Pixel value @(0, 2) = 6186
Pixel value @(1, 2) = 5142
Pixel value @(2, 2) = 6212
Pixel value @(3, 2) = 7114
Pixel value @(4, 2) = 7862
Pixel value @(0, 3) = 6152
Pixel value @(1, 3) = 5171
Pixel value @(2, 3) = 6159
Pixel value @(3, 3) = 7142
Pixel value @(4, 3) = 7882
Pixel value @(0, 4) = 6227
Pixel value @(1, 4) = 5164
Pixel value @(2, 4) = 6192
Pixel value @(3, 4) = 7118
Pixel value @(4, 4) = 7893