Programmer's Guide¶
This guide covers key architectural concepts and camera features that apply across the Spinnaker SDK APIs (C++, C, C#, Python). For language-specific code examples, see the Getting Started section and the API Reference.
Architecture¶
The Spinnaker API is built around the GenICam standard, which provides a generic programming interface for cameras and interfaces across manufacturers. Spinnaker is an extension of GenAPI and provides two major components:
- Image Acquisition
- The acquisition engine is responsible for setting up image buffers and grabbing images from the camera stream.
- Image Configuration
- The configuration engine controls the camera via GenICam nodes. This component includes the QuickSpin API, which is a wrapper that makes GenAPI easy to use for common properties.
Object Hierarchy¶
System (singleton)
└── Interface (USB or GigE adapter)
└── Camera
├── GenICam NodeMap ← camera control (requires Init())
├── Transport Layer NodeMap ← device info (available before Init())
└── Stream NodeMap ← buffer/stream configuration
The System singleton is the entry point. It enumerates interfaces and cameras.
The Camera object provides access to three node maps:
| Node Map | Access | Use For |
|---|---|---|
GetNodeMap() |
After Init() |
All camera settings (exposure, gain, trigger, format, etc.) |
GetTLDeviceNodeMap() |
Before Init() |
Serial number, model name, device type — useful for selecting among multiple cameras |
GetTLStreamNodeMap() |
After Init() |
Buffer mode, number of buffers, stream statistics |
GenICam Nodes¶
Camera features are accessed through the GenICam node map as typed node objects. Always check a node's availability before reading or writing it.
Node Types¶
| Type | Class | Value Access |
|---|---|---|
| Integer | CIntegerPtr |
GetValue() / SetValue() |
| Float | CFloatPtr |
GetValue() / SetValue() |
| Boolean | CBooleanPtr |
GetValue() / SetValue() |
| String | CStringPtr |
GetValue() / SetValue() |
| Enumeration | CEnumerationPtr |
GetCurrentEntry() / SetIntValue() |
| Command | CCommandPtr |
Execute() |
Checking Availability¶
// Always check before reading or writing
CIntegerPtr ptrWidth = nodeMap.GetNode("Width");
if (IsReadable(ptrWidth))
{
int64_t width = ptrWidth->GetValue();
}
if (IsWritable(ptrWidth))
{
ptrWidth->SetValue(640);
}
Setting an Enumeration¶
CEnumerationPtr ptrAcqMode = nodeMap.GetNode("AcquisitionMode");
if (IsWritable(ptrAcqMode))
{
CEnumEntryPtr ptrContinuous = ptrAcqMode->GetEntryByName("Continuous");
if (IsReadable(ptrContinuous))
{
ptrAcqMode->SetIntValue(ptrContinuous->GetValue());
}
}
QuickSpin API¶
QuickSpin is a layer on top of the GenICam API that provides direct property access using typed, named members on the camera object. It is available in C++, C#, and Python (but not in the C API).
QuickSpin internally accesses the same GenICam node map, so it still requires
Init() to be called before use.
When to use QuickSpin vs GenICam directly:
| Use QuickSpin for | Use GenICam directly for |
|---|---|
| Standard parameters (exposure, gain, width, format) | Advanced or camera-specific nodes |
| Rapid prototyping | Checking node availability/writability before access |
| Clean, readable code | Maximum flexibility and feature completeness |
Camera XML¶
The camera's XML file contains feature naming, register mapping, and dependencies between features. GenICam-compliant software caches this XML for quicker access to the camera's definition. Spinnaker caches the XML file in a binary format for better performance.
On Windows, cached XML files are stored at: C:\ProgramData\Spinnaker\XML
Image Pointer¶
ImagePtr is a smart pointer that manages the lifetime of an image object. Multiple
pointers can reference the same image object. The pointer must be assigned before
use — do not call methods on an uninitialised pointer.
// Correct: retrieve from acquisition then assign
ImagePtr pResultImage;
pResultImage = pCam->GetNextImage(1000);
// Correct: copy — both pointers reference the same image
ImagePtr duplicateImagePtr = pResultImage;
// INCORRECT: calling Create on an uninitialised pointer
ImagePtr illegalImage;
illegalImage->Create(...); // undefined behaviour
// Correct: create a new standalone image
ImagePtr goodImage;
goodImage = Image::Create(...);
Always call pImage->Release() when done with an image retrieved via
GetNextImage() to return the buffer to the pool. Failing to do so exhausts
the camera's buffer queue.
// Always check for incomplete frames before processing
if (!pResultImage->IsIncomplete())
{
// Process image...
}
// Always release back to the buffer pool
pResultImage->Release();
Sequencer¶
The Sequencer allows programmatic control of acquisition parameters across a sequence of images. You can define both what settings are used (exposure, gain, etc.) and when the camera transitions from one setting to the next. This functions as a state machine: states correspond to sequencer set feature settings, and transitions are triggered by specific events.
To configure the sequencer:
- Visually: Use SpinView's Sequencer tab.
- Programmatically: Use the
Sequencerexample installed with the SDK (src/Sequencer/Sequencer.cpp).
Logic Block¶
A Logic Block is a collection of combinatorial logic and latches that allows you to create custom signals inside the camera. Each Logic Block consists of two lookup tables (LUTs):
- Value LUT — drives the D input of a flip-flop
- Enable LUT — drives the enable input of the flip-flop
Both LUTs have 3 inputs and 8 configuration bits for their truth table, giving full control over the output signal logic.
Logic Blocks are useful for combining trigger signals, implementing delays, or creating custom event logic without external hardware.
User Set¶
User Set is on-camera non-volatile memory that stores camera properties such as exposure, gain, and other configurable settings. Multiple user sets can be saved and loaded, allowing quick switching between camera configurations.
To check which features a user set can store, either:
- Query the
UserSetFeatureSelectornode programmatically, or - Use the SpinView User Set tab.
Saving and loading a user set:
// Save current settings to User Set 1
CEnumerationPtr ptrUserSetSelector = nodeMap.GetNode("UserSetSelector");
ptrUserSetSelector->SetIntValue(
ptrUserSetSelector->GetEntryByName("UserSet1")->GetValue());
CCommandPtr ptrUserSetSave = nodeMap.GetNode("UserSetSave");
ptrUserSetSave->Execute();
// Load User Set 1 as the default power-on configuration
CEnumerationPtr ptrUserSetDefault = nodeMap.GetNode("UserSetDefault");
ptrUserSetDefault->SetIntValue(
ptrUserSetDefault->GetEntryByName("UserSet1")->GetValue());
Further Reading¶
For feature-specific details including triggering, exposure, gain, gamma, white balance, events, logging, and chunk data, see the corresponding examples in the SDK source:
| Topic | Example File |
|---|---|
| Trigger | src/Trigger/Trigger.cpp |
| Exposure | src/Exposure/Exposure.cpp |
| Events | src/NodeMapCallback/NodeMapCallback.cpp |
| Chunk Data | src/ChunkData/ChunkData.cpp |
| Logging | src/Logging/Logging.cpp |
| Sequencer | src/Sequencer/Sequencer.cpp |
| Image Format | src/ImageFormatControl/ImageFormatControl.cpp |
| Save to Video | src/SaveToVideo/SaveToVideo.cpp |