Skip to content

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.

// QuickSpin — direct property access
pCam->ExposureTime.SetValue(5000.0f);
pCam->Gain.SetValue(0.0f);
pCam->TriggerMode.SetValue(TriggerMode_On);
pCam->TriggerSource.SetValue(TriggerSource_Line0);
// QuickSpin — direct property access
cam.ExposureTime.Value = 5000.0;
cam.Gain.Value = 0.0;
cam.TriggerMode.Value = TriggerModeEnums.On;
cam.TriggerSource.Value = TriggerSourceEnums.Line0;
# QuickSpin — direct property access
cam.ExposureTime.SetValue(5000.0)
cam.Gain.SetValue(0.0)
cam.TriggerMode.SetValue(PySpin.TriggerMode_On)
cam.TriggerSource.SetValue(PySpin.TriggerSource_Line0)

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 Sequencer example 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 UserSetFeatureSelector node 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