-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Instrument
is the base class for connecting to appropriate hardware such as a PSI camera. It owns the transport layer and provides access to devices, but it does not handle camera specific functionality.
Camera
is the primary interface for the library. An instance of Camera
will handle the connection to a specific camera, provide access to features that are specific to that hardware and devices that can be accessed via that hardware.
Initialisation
A camera instance must be initialised to start the internal thread.
Camera camera;
// With no arguments it will attempt to connect to the first camera it can.
camera.Initialise();
// Alternatively you can specify a regex allowing you to target a particular camera.
// The USB serial descriptor can contain both the serial number and user assigned name
// for the camera, so to target any serial number but a specific name for example:
camera.Initialise(".*:myid");
// Additionally you can specify a callback function for handling connection events
camera.Initialise(".*:myid", [](bool connected) {
cout << "Camera has been" << (connected ? "connected" : "disconnected") << endl;
});
Grabbing images
Grabbing an image requires a capture mode, something to handle the data and a callback function for when grabbing is complete. The function returns immediately since grabbing is asynchronous.
camera.GrabImage(Camera::Mode::Normal, handler, [](bool status) {
if (status)
{
// Grabbing was successful so do something with the image
}
return true;
});
In the above example the handler
is a type of DataHandler
, please refer to the images section below for more details.
Returning true
from the callback function indicates that another frame is required (streaming mode) whereas returning false will allow the camera thread to pause until GrabImage()
is next called.
Miscellaneous
The camera can be queried and controlled in a number of ways:
// Indicates whether or not the underlying transport layer has connected to the hardware.
if (camera.Connected()) {}
// Returns true if the camera is busy attempting to grab an image.
if (camera.Grabbing()) {}
// If a flash is connected this will allow you to control the power.
camera.SetFlash(0);
// Some camera chips support multiple contexts whereby you can have multiple complex
// configurations that can be switched between instantly.
camera.SetContext(1);
The data returned from a camera is simply a buffer of bytes that must be converted into an image. This is performed by a DataHandler
, examples of which can be found in include/psinc/handlers. A DataHandler
class must implement the following which will be invoked by Camera
during an image grab, but before the callback function:
virtual bool Process(
bool monochrome, // true = monochrome imaging chip, false = bayer
bool hdr, // true if the data is HDR (2 bytes per pixel)
emg::Buffer<byte> &data, // the raw data from the imaging chip
int width, // the image width
int height, // the image height
byte bayerMode // indicates the starting position in the bayer grid
);
The library provides an ImageHandler<>
that will convert the data to an Image<byte>
or Image<uint16_t>
and acts as a reference for creating your own handler type.
Helper functions for dealing with Bayer filtering can be found in the Decoder.hpp file.
Imaging chips typically contain a multitude of configuration options contained in registers. A single register can be responsible for a number of features and so the library abstracts these to a map of features that can modify the underlying registers appropriately.
// Set feature to a required value.
camera.features["VREF_ADC Voltage Level"].Set(4);
// Retrieve the current value of a feature.
int value = camera.features["A: Window Width"].Get();
The available features for a supported imaging chip can be found in src/psinc/xml although common features are made available through...
Aliases
The Alias
structure refers to specific features for the connected image chip where available.
// Enable automatic gain control for context 0
camera.aliases[0].autoGain->Set(1);
// Set the exposure level for context 1
camera.aliases[1].exposure->Set(42);
// Get the current image width for context 0
int width = camera.aliases[0].width->Get();
Devices provide a common way of communicating with additional pieces of hardware connected to an instrument and some aspects of the instrument itself are exposed as devices. For example, reading the serial number of a camera can be performed as follows:
string serial = camera.devices["Serial"].Read();