CPP API Manual

Introduction to the API

Is this the best API for you?

The Vimba C++ API has an elaborate class architecture. It is designed as a highly efficient and sophisticated API for advanced object-oriented programming including the STL (standard template library), shared pointers, and interface classes. If you prefer an API with less design patterns, we recommend the Vimba C API.

See also

To understand the API, read the SDK Manual first: It contains essential information.

Tip

For more information about design patterns, we recommend the book Design Patterns. Elements of Reusable Object-Oriented Software.

To get the best possible performance, you need knowledge about multithreading. We recommend the book C++ Concurrency in Action.

Compatibility

To ensure backward compatibility, the C++ API release build is compatible with Visual Studio 2015. If you use a higher version, we recommend you to rebuild the C++ API by compiling the source files with your Visual Studio version. You can also use other IDEs that implement the C++11 standard (or higher) if you compile the C++ API source files with these IDEs.

Note

The C++ API provides release and debug build DLL files. If you build your application in debug mode, use the debug DLL file VimbaCPPd.dll.

Shared pointers

Vimba C++ API makes intense use of shared pointers to ease object lifetime and memory allocation. Since some C++ runtime libraries don’t provide them, this Vimba API is equipped with an own implementation for Shared Pointers, which can be exchanged with your preferred shared pointer implementation (see Replacing the shared pointer library), for example, std::shared_ptr, boost::shared_ptr, or QSharedPointer from the Qt library.

C++ API diagram

The image below shows a simplified C++ API UML diagram. To ease understanding the concept, only the most important items are listed. For classes that you access through their pointers, the diagram shows these pointers instead of the corresponding class names.

Simplified UML diagram

Simplified UML diagram

API usage

For a quick start, we recommend using the examples.

See also

By default, the examples are located at:

  • C:/Users/Public/Documents/Allied Vision/Vimba_x.x (Windows)

  • Vimba install directory/VimbaCPP/Examples (Linux)

Entry point

The entry point to Vimba C++ API is the VimbaSystem singleton. The VimbaSystem class allows both to control the API’s behavior and to query for interfaces and cameras.

To obtain a reference to it, call the static function VimbaSystem::GetInstance. All Vimba C++ classes reside in the namespace AVT::VmbAPI, so employ the using declaration using AVT::VmbAPI.

API version

Even if new features are introduced to the C++ API, your software remains backward compatible. Use VimbaSystem::QueryVersion to check the version number of the C API. You can run this function without initializing the API.

API startup and shutdown

To start and shut down the C++ API, use these paired functions:

  • VimbaSystem::Startup initializes the API.

  • VimbaSystem::Shutdown shuts down the API and destroys all used objects in the API (when all observers have finished execution).

VimbaSystem::Startup and VimbaSystem::Shutdown must always be paired. Calling the pair several times within the same program is possible, but not recommended. Successive calls of VimbaSystem::Startup or VimbaSystem::Shutdown are ignored and the first VimbaSystem::Shutdown after a VimbaSystem::Startup closes the API.

Note

Always shut down the API when your application closes. Shutting down the API is necessary under all circumstances to unload the transport layers. If they still are loaded although the application is closed, they access invalid memory.

Note

VimbaSystem::Shutdown blocks until all callbacks have finished execution.

Shared Pointers usage

General aspects

A shared pointer is an object that wraps any regular pointer variable to control its lifetime. Besides wrapping the underlying raw pointer, it keeps track of the number of copies of itself. By doing so, it ensures that it will not release the wrapped raw pointer until its reference count (the number of copies) has dropped to zero. A shared pointer automatically deletes the wrapped pointer when the last shared pointer to it is destroyed. Though giving away the responsibility for deallocation, the programmer can still work on the very same objects.

Shared Pointers
{
// This declares an empty shared pointer that can wrap a pointer of
// type Camera
CameraPtr sp1;

// The reset member function tells the shared pointer to
// wrap the provided raw pointer
// sp1 now has a reference count of 1
sp1.reset( new Camera () );
  {
  // In this new scope we declare another shared pointer
  CameraPtr sp2;

  // By assigning sp1 to it the reference count of both (!) is set to 2
  sp2 = sp1;
  }
  // When sp2 goes out of scope the reference count drops back to 1
}
// Now that sp1 has gone out of scope its reference count has dropped
// to 0 and it has released the underlying raw pointer on destruction

Shared pointers (or smart pointers in general) were not part of the C++ standard library until C++11. For example, the first version of Microsoft’s C++ standard library implementation that supports shared pointers is included in Visual Studio 2010. Because of the mentioned advantages, Vimba C++ API makes heavy use of shared pointers while not relying on a specific implementation.

Replacing the shared pointer library

Although it is best practice to use the predefined shared pointer type, you can replace it with a different pointer type from libraries like Qt or Boost. In order to ease this exchange, the Vimba C++ source files include the header file UserSharedPointerDefines.h. This header file also lists the needed macros and typedefs.

Additionally, the table below lists macros covering the basic functionality that Vimba expects from any shared pointer. Since a shared pointer is a generic type, it requires a template parameter. That is what the various typedefs are for. For example, the CameraPtr is just an alias for AVT::VmbAPI::shared_ptr<AVT::VmbAPI::Camera>.

To replace the shared pointers, follow these steps:

  1. Add UserSharedPointerDefines.h by adding the define USER_SHARED_POINTER to your compiler settings.

  2. Add your shared pointer source files to the Vimba C++ API project.

  3. Define the macros and typedefs as described in the header UserSharedPointerDefines.h.

  4. Recompile Vimba C++ API.

Basic functions of a shared pointer class

Macro

Example

Purpose

SP_DECL( T )

std::shared_ptr

Declares a new shared pointer

SP_SET( sp, rawPtr )

sp.reset( rawPtr )

Tells an existing shared pointer to
wrap the given raw pointer

SP_RESET( sp )

sp.reset()

Tells an existing shared pointer to
decrease its reference count

SP_ISEQUAL( sp1, sp2 )

sp1 == sp2 )

Checks the addresses of the wrapped
raw pointers for equality

SP_ISNULL( sp )

( NULL == sp )

Checks the address of the wrapped
raw pointer for NULL

SP_ACCESS( sp )

sp.get()

Returns the wrapped raw pointer

SP_DYN_CAST( sp, T )

td::dynamic_pointer_cast(sp)

A dynamic cast of the pointer

Vimba now is ready to use the added shared pointer implementation without changing its behavior. Within your own application, you can employ your shared pointers as usual. Note that your application and Vimba must refer to the same shared pointer type.

Tip

If you want your application to substitute its shared pointer type along with Vimba, you can utilize the macros listed in the table above in your application as well.

Listing cameras

See also

For a quick start, see the ListCameras example.

The function VimbaSystem::GetCameras enumerates all cameras recognized by the underlying transport layers. With this command, the programmer can fetch the list of all connected camera objects. Before opening cameras, camera objects contain all static details of a physical camera that do not change throughout the object’s lifetime such as:

  • Camera ID

  • Camera model

  • Name or ID of the connected interface

The order in which the detected cameras are listed is determined by the order of camera discovery and therefore not deterministic. Moreover, the order may change depending on your system configuration and the accessories (for example, hubs or long cables).

GigE cameras

For GigE cameras, discovery has to be initiated by the host software. This is done automatically if you register a camera list observer of type ICameraListObserv with VimbaSystem.

In this case, a call to VimbaSystem::GetCameras or VimbaSystem::GetCameraByID returns immediately. If no camera list observer is registered, a call to VimbaSystem::GetCameras or VimbaSystem::GetCameraByID takes some time because the responses to the initiated discovery command must be waited for.

USB and 1394 cameras

Changes to the plugged cameras are detected automatically. Consequently, any changes to the camera list are announced via discovery events and the call to VimbaSystem::GetCameras returns immediately.

MIPI CSI-2 cameras

Cameras with MIPI CSI-2 interface are detected when the board is booted. To avoid damage to the hardware, do not plug in or out a camera while the board is powered.

Getting the camera list code snippet
std:: string name;
CameraPtrVector cameras;
VimbaSystem &system = VimbaSystem :: GetInstance ();
if ( VmbErrorSuccess == system.Startup () )
{
   if ( VmbErrorSuccess == system.GetCameras( cameras ) )
   {
      for ( CameraPtrVector :: iterator iter = cameras.begin ();
            cameras.end() != iter;
            ++iter )
      {
         if ( VmbErrorSuccess == (*iter)->GetName( name ) )
         {
          std::cout << name << std::endl;
         }
      }
   }
}
Basic functions of the Camera class

Function
returning VmbErrorType

Purpose

GetID( std::string& ) const

Unique ID

GetName( std::string& ) const

Name

GetModel( std::string& ) const

Model name

GetSerialNumber( std::string& ) const

Serial number

GetPermittedAccess( VmbAccessModeType& ) const

Mode to open the camera

GetInterfaceID( std::string& ) const

ID of the interface the camera is connected to

Note

VimbaSystem::Shutdown blocks until all callbacks have finished execution.

Notifications of changed camera states

For being notified whenever a camera is detected, disconnected, or changes its open state, use VimbaSystem::RegisterCameraListObserver (GigE and USB only). This call registers a camera list observer (of type ICameraListObserver) with the VimbaSystem that gets executed on the according event. The observer function to be registered has to be of type ICameraListObserver*.

Note

Functions that must not be called within your camera list observer:

  • VimbaSystem::Startup

  • VimbaSystem::Shutdown

  • VimbaSystem::GetCameras

  • VimbaSystem::GetCameraByID

  • VimbaSystem::RegisterCameraListObserver

  • VimbaSystem::UnregisterCameraListObserver

  • Feature::SetValue

  • Feature::RunCommand

Opening and closing a camera

A camera must be opened to control it and to capture images. Call Camera::Open with the camera list entry of your choice, or use function VimbaSystem::OpenCameraByID with the ID of the camera. In both cases, also provide the desired access mode for the camera.

The API provides several access modes:

  • VmbAccessModeFull: read and write access. Use this mode to configure the camera features and to acquire images (Goldeye CL cameras: configuration only).

  • VmbAccessModeConfig: enables configuring the IP address of your GigE camera. Not available for 5 GigE cameras - please use ForceIP.

  • VmbAccessModeRead: read-only access. Setting features is not possible. However, for GigE cameras that are already in use by another application, the acquired images can be transferred to the API(Multicast).

Open a camera code snippet
CameraPtrVector cameras;
VimbaSystem &system = VimbaSystem :: GetInstance ();

if ( VmbErrorSuccess == system.Startup () )
{
  if ( VmbErrorSuccess == system.GetCameras( cameras ) )
  {
    for ( CameraPtrVector :: iterator iter = cameras.begin ();
          cameras.end() != iter;
          ++iter )
    {
      if ( VmbErrorSuccess == (*iter)->Open( VmbAccessModeFull ) )
      {
        std::cout << "Camera opened" << std::endl;
      }
    }
  }
}

The following code snippet shows how to open a GigE camera by its IP address. Opening the camera by its serial number or MAC address is also possible.

Open Camera by IP code snippet
CameraPtr camera;
VimbaSystem &system = VimbaSystem :: GetInstance ();
if ( VmbErrorSuccess == system.Startup () )
{
  if ( VmbErrorSuccess == system.OpenCameraByID( "192.168.0.42",
                                                 VmbAccessModeFull ,
                                                 camera ) )
  {
    std::cout << "Camera opened" << std::endl;
  }
}

The following code snippet shows how to close a camera using Camera::Close.

Closing a camera code snippet
// The "camera" object points to an opened camera
if ( VmbErrorSuccess == camera.Close () )
{
  std::cout << "Camera closed" << std::endl;
}

Acessing features

See also

To quickly learn how to list features, see the ListFeatures example.

Feature types

The C++ API provides several feature types, which all have their specific properties and functionalities. The API provides its own set of access functions for every feature data type. The table below lists the Vimba API functions of the Feature class used to access feature values.

Note

VimbaSystem::Shutdown blocks until all callbacks have finished execution.

Functions for reading and writing a feature

Type

Set

Get

Range/Increment

Enum

SetValue( string )

GetValue( string& )

GetValues( StringVector& )

SetValue( int )

GetValue( int& )

GetValues( IntVector& )

GetEntry( EnumEntry& )

GetEntries( EntryVector& )

Int

SetValue( int )

GetValue( int& )

GetRange( int&, int& )

GetIncrement( int& )

Float

SetValue( double )

GetValue( double& )

GetRange( double&, double& )

GetIncrement( double& )

String

SetValue( string )

GetValue( string& )

Bool

SetValue( bool )

GetValue( bool& )

Command

RunCommand( )

IsCommandDone( bool& )

Raw

SetValue( uchar )

GetValue( UcharVector& )

With the member function GetValue, a feature’s value can be queried.
With the member function SetValue, a feature’s value can be set.

Integer and double features support GetRange. These functions return the minimum and maximum value that a feature can have. Integer features also support the GetIncrement function to query the step size of feature changes. Valid values for integer features are min <= val <= min + [(max-min)/increment] * increment (the maximum value might not be valid).

Enumeration features support GetValues that returns a vector of valid enumerations as strings or integers. These values can be used to set the feature according to the result of IsValueAvailable. If a non-empty vector is supplied, the original content is overwritten and the size of the vector is adjusted to fit all elements. An enumeration feature can also be used in a similar way as an integer feature.

Since not all the features are available all the time, the current accessibility of features may be queried via IsReadable() and IsWritable(), and the availability of Enum values can be queried with IsValueAvailable( string ) or IsValueAvailable( int ) .

With Camera::GetFeatures, you can list all features available for a camera. This list remains static while the camera is opened. The Feature class of the entries in this list also provides information about the features that always stay the same for this camera. Use the member functions of class Feature to access them as shown in the following code snippets:

Reading a camera feature code snippet
FeaturePtr feature;
VmbInt64_t width;

if ( VmbErrorSuccess == camera ->GetFeatureByName( "Width", feature )
{
  if ( VmbErrorSuccess == feature ->GetValue( width ) )
  {
    std::out << width << std::endl;
  }
}

Writing features to a camera and running a command feature:

Writing features and running command features
 FeaturePtr feature;

if ( VmbErrorSuccess == camera ->GetFeatureByName( "AcquisitionMode", feature )
{
  if ( VmbErrorSuccess == feature ->SetValue( "Continuous" ) )
  {
    if ( VmbErrorSuccess == camera ->GetFeatureByName( "AcquisitionStart",
                                                       feature ) )
    {
      if ( VmbErrorSuccess == feature ->RunCommand () )
      {
           std::out << "Acquisition started" << std::endl;
      }
    }
  }
}

The following table introduces the basic features of all cameras. A feature has a name, a type, and access flags such as read-permitted and write-permitted. To get notified when a feature’s value changes, use Feature::RegisterObserver (see Using Events). The observer to be registered has to implement the interface IFeatureObserver. This interface declares the member function FeatureChanged. In the implementation of this function, you can react on updated feature values as it will get called by the API on the according event.

Functions for accessing static properties of a feature

Function
returning VmbErrorType

Purpose

GetName( std::string& )

Name of the feature

GetDisplayName( std::string& )

Name to display in GUI

GetDataType( VmbFeatureDataType& )

Data type of the feature. Gives information
about the available functions for the feature.

GetFlags( VmbFeatureFlagsType& )

Static feature flags, containing information
about the actions available for a feature:
Read an Write, Volatile (changes with every
Read possible). ModifyWrite features are ajdusted to
valid values.

GetCategory( std::string& )

Category the feature belongs to, used for
structuring the features

GetPollingTime( VmbUint32_t& )

The suggested time to poll the feature

GetUnit( std::string& )

The unit of the feature, if available

GetRepresentation( std::string& )

The scale to represent the feature, used
as a hint for feature control

GetVisibility( VmbFeatureVisibilityType& )

The audience the feature is for

GetToolTip( std::string& )

Short description of the feature, used
for bubble help

GetDescription( std::string& )

Description of the feature, used
as extended explanation

GetSFNCNamespace( std::string& )

The SFNC namespace of the feature

GetAffectedFeatures( FeaturePtrVector& )

Features that change if the feature is changed

GetSelectedFeatures( FeaturePtrVector& )

Features that are selected by the feature

Functions for accessing static properties of a feature

Feature

Type

Access

Description

AcquisitionMode

Enumeration

R/W

Values: Continuous,
SingleFrame, MultiFrame.

AcquisitionStart

Command

Start acquiring images.

AcquisitionStop

Command

Stop acquiring images.

PixelFormat

Enumeration

R/W

Image format (Mono8 etc.)

Width

Uint32

R/W

Image width, in pixels.

Height

Uint32

R/W

Image height, in pixels.

PayloadSize

Uint32

R

Number of bytes in the camera payload, incl. image.

Note

VimbaSystem::Shutdown blocks until all callbacks have finished execution.

Note

Functions that must not be called within the feature observer:

  • VimbaSystem::Startup

  • VimbaSystem::Shutdown

  • VimbaSystem::GetCameras

  • VimbaSystem::GetCameraByID

  • VimbaSystem::RegisterCameraListObserver

  • VimbaSystem::UnregisterCameraListObserver

  • Feature::SetValue

  • Feature::RunCommand

Acquiring images

See also

The SDK Manual describes synchronous and asynchronous image acquisition.

See also

For a quick start, see the SynchronousGrab example.

Image Capture vs. Image Acquisition

Image capture and image acquisition are two independent operations:

  • The API captures images

  • The camera acquires images.

To obtain an image from your camera, setup the API to capture images before starting the acquisition on the camera:

Typical asynchronous application with the C++ API

Typical asynchronous application with the C++ API

Note

The C++ API provides convenience functions, which are optimized for ease of use. We recommend using the convenience functions for projects where quick and easy programming is more important than best performance of your vision application.

Asynchronous image acquisition

The following code snippet is a minimalistic example of asynchrounous image acquisition.

Simple image streaming code snippet
#include "Vimba.h"
namespace AVT {
namespace VmbAPI {

// Constructor for the FrameObserver class
FrameObserver :: FrameObserver(CameraPtr pCamera) : IFrameObserver(pCamera ){}

// Frame callback notifies about incoming frames
void FrameObserver :: FrameReceived(const FramePtr pFrame)
{
   // Send notification to working thread
   // Do not apply image processing within this callback (performance)
   // When the frame has been processed , requeue it
   m_pCamera ->QueueFrame(pFrame );
}

void Vimba :: RunExample(void)
{
   VmbInt64_t nPLS; // Payload size value
   FeaturePtr pFeature; // Generic feature pointer
   VimbaSystem &sys = VimbaSystem :: GetInstance (); // Create and get Vimba singleton
   CameraPtrVector cameras; // Holds camera handles
   CameraPtr camera;
   FramePtrVector frames (15); // Frame array

   // Start the API, get and open cameras
   sys.Startup ();
   sys.GetCameras(cameras );
   camera = cameras [0];
   camera ->Open(VmbAccessModeFull );

   // Get the image size for the required buffer
   // Allocate memory for frame buffer
   // Register frame observer/callback for each frame
   // Announce frame to the API
   camera ->GetFeatureByName("PayloadSize", pFeature );
   pFeature ->GetValue(nPLS);
   for(FramePtrVector :: iterator iter=frames.begin (); frames.end ()!= iter; ++iter)
   {
      (*iter). reset(new Frame(nPLS ));
      (*iter)->RegisterObserver(IFrameObserverPtr(new FrameObserver(camera )));
      camera ->AnnounceFrame (*iter);
   }

   // Start the capture engine (API)
   camera ->StartCapture ();
   for(FramePtrVector :: iterator iter=frames.begin (); frames.end ()!= iter; ++iter)
   {
      // Put frame into the frame queue
      camera ->QueueFrame (*iter);
   }

       // Start the acquisition engine (camera)
       camera ->GetFeatureByName("AcquisitionStart", pFeature );
   pFeature ->RunCommand ();

   // Program runtime , e.g., Sleep (2000);

   // Stop the acquisition engine (camera)
   camera ->GetFeatureByName("AcquisitionStop", pFeature );
   pFeature ->RunCommand ();

   // Stop the capture engine (API)
   // Flush the frame queue
   // Revoke all frames from the API
   camera ->EndCapture ();
   camera ->FlushQueue ();
   camera ->RevokeAllFrames ();
   for(FramePtrVector :: iterator iter=frames.begin (); frames.end ()!= iter; ++iter)
   {
      // Unregister the frame observer/callback
      (*iter)->UnregisterObserver ();
   }
   camera ->Close ();
   sys.Shutdown (); // Always pair sys.Startup and sys.Shutdown
}
}} // namespace AVT::VmbAPI

Image capture

To enable image capture, frame buffers must be allocated and the API must be prepared for incoming frames. This is done in convenience function Camera::StartContinuousAcquisition (Camera::StopContinuousAcquisition stops acquisition). Note that these convenience functions perform all steps listed in figure Typical asynchronous application with the C++ API for each single image. Therefore, they do not provide best performance if your vision application requires frequently starting and stopping image acquisition. In this case, it is unnecessary to prepare image acquisisition and to clean up for each image. Instead, you can prepare image acquisition once, toggle between the start and stop functions, and clean up after your images are captured.

Asynchronous image capture step by step:

  1. Open the camera as described in section Opening and closing a camera.

  2. Query the necessary buffer size through the feature PayloadSize. Allocate frames of this size.

  3. Announce the frames.

  4. Start the capture engine.

  5. Queue the frame you have just created with Camera::QueueFrame, so that the buffer can be filled when the acquisition has started.

The API is now ready. Start and stop image acquisition on the camera as described in section Image Acquisition.

  1. Register a frame observer that gets executed when capturing is complete. The frame observer has to be of type IFrameObserver. Within the frame observer, queue the frame again after you have processed it.

  2. Stop the capture engine with Camera::EndCapture.

  3. Call Camera::FlushQueue to cancel all frames on the queue. If the API has done the memory allocation, this memory is not released until RevokeAllFrames, RevokeFrame, EndCapture, or Close functions have been called.

  4. Revoke the frames with Camera::RevokeAllFrames to clear the buffers.

Synchronous image capture (blocking your execution thread) step by step:

  1. Open the camera as described in section Opening and closing a camera.

  2. How you proceed depends on the number of frames and the performance you need:

    • Single frame: You can use the convenience function Camera::AcquireSingleImage to receive one image frame.

    • Multiple frames: You can use the convenience function Camera::AcquireMultipleImages to receive several image frames (determined by the size of your vector of FramePtrs).

Note

If your application requires a low CPU load or exact triggering, we recommend a different approach: Set the feature AcquisitionMode to MultiFrame or Continuous and run the command AcquisitionStart (see section Image Acquisition).

To assure correct continuous image capture, use at least two or three frames. The appropriate number of frames to be queued in your application depends on the frames per second the camera delivers and on the speed with which you are able to re-queue frames (also taking into consideration the operating system load). The image frames are filled in the same order in which they were queued.

Note

Always check that Frame::GetReceiveStatus returns VmbFrameStatusComplete when a frame is returned to ensure the data is valid.

Note

Functions that must not be called within the frame observer:

  • VimbaSystem::Startup

  • VimbaSystem::Shutdown

  • VimbaSystem::OpenCameraByID

  • Camera::Open

  • Camera::Close

  • Camera::AcquireSingleImage

  • Camera::AcquireMultipleImages

  • Camera::StartContinuousImageAcquisition

  • Camera::StopContinuousImageAcquisition

  • Camera::StartCapture

  • Camera::EndCapture

  • Camera::AnnounceFrame

  • Camera::RevokeFrame

  • Camera::RevokeAllFrames

Image Acquisition

If you have decided to use one of the convenience functions Camera::AcquireSingleImage, Camera::AcquireMultipleImages, or Camera::StartContinuousImageAcquisition, no further actions are necessary.

Only if you have setup capture step by step as described in section Image capture, you have to start image acquisition on your camera:

  1. Set the feature AcquisitionMode (for example, to Continuous).

  2. Run the command AcquisitionStart.

To stop image acquisition, run command AcquisitionStop. The code snippet below shows a simplified streaming example without error handling.

Image streaming code snippet
VmbErrorType err;           // Every Vimba function returns an error code that
                            // should always be checked for VmbErrorSuccess
VimbaSystem &sys;           // A reference to the VimbaSystem singleton
CameraPtrVector cameras;    // A list of known cameras
FramePtrVector frames( 3 ); // A list of frames for streaming. We chose
                            // to queue 3 frames.
IFrameObserverPtr pObserver( new MyFrameObserver () ); // Our implementation
                                                       // of a frame observer
FeaturePtr pFeature;        // Any camera feature
VmbInt64_t nPLS;            // The payload size of one frame

sys = VimbaSystem :: GetInstance ();
err = sys.Startup ():
err = sys.GetCameras( cameras );
err = cameras [0]->Open( VmbAccessModeFull );
err = cameras [0]-> GetFeatureByName( "PayloadSize", pFeature ); (A)
err = pFeature ->GetValue( nPLS ) (A)

for ( FramePtrVector :: iterator iter = frames.begin ();
      frames.end() != iter;
      ++iter )
{
    ( *iter ). reset( new Frame( nPLS ) ); (B)
    err = ( *iter )->RegisterObserver( pObserver ) ); (C)
    err = cameras [0]-> AnnounceFrame( *iter ); (1)
}

err = cameras [0]-> StartCapture (); (2)

for ( FramePtrVector :: iterator iter = frames.begin ();
      frames.end() != iter;
      ++iter )
{
      err = cameras [0]-> QueueFrame( *iter ); (3)
}

err = GetFeatureByName( "AcquisitionStart", pFeature ); (4)
err = pFeature ->RunCommand (); (4)

// Program runtime ...
// When finished , tear down the acquisition chain , close camera and API

err = GetFeatureByName( "AcquisitionStop", pFeature );
err = pFeature ->RunCommand ();
err = cameras [0]-> EndCapture ();
err = cameras [0]-> FlushQueue ();
err = cameras [0]-> RevokeAllFrames ();
err = cameras [0]->Close ();
err = sys.Shutdown ();
Notifications about a new frame code snippet
// 1. define observer that reacts on new frames
class FrameObserver : public IFrameObserver
{
...
public:
  // In your contructor call the constructor of the base class
  // and pass a camera object
  FrameObserver( CameraPtr pCamera ) : IFrameObserver( pCamera )
  {
    // Put your initialization code here
  }

  void FrameReceived( const FramePtr pFrame )
  {
    VmbFrameStatusType eReceiveStatus;

    if( VmbErrorSuccess == pFrame ->GetReceiveStatus( eReceiveStatus ) )
    {
      if ( VmbFrameStatusComplete == eReiveStatus )
      {
        // Put your code here to react on a successfully received frame
      }
      else
      {
        // Put your code here to react on an unsuccessfully received frame
      }
    }

  // When you are finished copying the frame , re -queue it
  m_pCamera ->QueueFrame( pFrame );
  }
};

{
  VmbErrorType res;
  FramePtr pFrame;
  CameraPtr pCamera;

  // 2. Register the observer before queuing the frame
  res = pFrame.RegisterObserver( IFrameObserverPtr( new FrameObserver( pCamera ) ) );
}

Transforming images

To transform images received via the API into common image formats, use the Image Transform Library.

See also

For a quick start, see the AsynchrounousGrab example, which contains an image transformation.

Using Events

Events serve a multitude of purposes and can have several origins: The Vimba System, an Interface, and cameras.

In the C++ API, notifications are issued as a result to a feature invalidation of either its value or its state. Consequently, to get notified about any feature change, register an observer of the desired type (ICameraListObserver, IInterfaceListObserver, or IFeatureObserver) with the appropriate RegisterXXXObserver method (RegisterCameraListObserver, RegisterInterfaceListObserver, or RegisterObserver), which gets called if there is a change to that feature.

Three examples are listed in this section:

  • Camera list notifications

  • Tracking invalidations of features

  • Explicit camera event features

For camera list notifications (GigE, USB, and 1394 only), see the code snippet below:

Getting notified about camera list changes
// 1. define observer that reacts on camera list changes
class CamObserver : public ICameraListObserver
{
...
public:
   void CameraListChanged( CameraPtr pCam , UpdateTriggerType reason )
   {
    // Next to the camera pointer a reason why the observer's function was triggered
    // is passed in. Possible values are:
    // UpdateTriggerPluggedIn (0), a new camera was discovered
    // UpdateTriggerPluggedOut (1), a known camera disappeared from the bus
    // UpdateTriggerOpenStateChanged (3), a known camera was opened or closed
    // by another application
    if ( UpdateTriggerPluggedIn == reason || UpdateTriggerPluggedOut == reason )
    {
      // Put your code here to react on the changed camera list
      // E.g., by sending a Windows event message or
      // triggering a Qt or boost signal to update your view
    }
    else
    {
     // React on a changed open state
    }
  }
};

{
 VmbErrorType res;
 VimbaSystem &sys = VimbaSystem :: GetInstance ();
 FeaturePtr pFeature;

// 2. Register the observer; automatic discovery for GigE is turned on
res = sys.RegisterCameraListObserver( ICameraListObserverPtr( new CamObserver () ) );
}
Getting notified about feature changes
// 1. define observer
class WidthObserver : public IFeatureObserver
{
...
public:
  void FeatureChanged ( const FeaturePtr &feature )
   {
     if ( feature != NULL )
     {
       VmbError_t res;
       std:: string strName("");
       res = feature ->GetDisplayName(strName );
       std::cout << strName << " changed" << std::endl;
     }
   }
};

{
...
// 2. register the observer for that event
res = GetFeatureByName( "Width", pFeature );

res = pFeature ->RegisterObserver( IFeatureObserverPtr( new WidthObserver () ));
// as an example , binning is changed , so the observer will be run
res = GetFeatureByName( "BinningHorizontal", pFeature );
pFeature ->SetValue (8);
}

GigE cameras additionally provide the Camera events feature. Camera events (for changed camera states) are also handled with the same mechanism of feature invalidation.

Getting notified about camera events
// 1. define observer
class EventObserver : public IFeatureObserver
{
...
public:
  void FeatureChanged ( const FeaturePtr &feature )
  {
    if ( feature != NULL )
    {
      VmbError_t res;
      std:: string strName("");

      res = feature ->GetDisplayName(strName );
      std::cout "Event " << strName << " occurred" << std::endl;
    }
  };

{
  ...
  // 2. register the observer for the camera event
  res = GetFeatureByName( "EventAcquisitionStart", pFeature );
  res = pFeature ->RegisterObserver( IFeatureObserverPtr( new EventObserver () ));

  // 3. select "AcquisitionStart" (or a different) event
  res = GetFeatureByName( "EventSelector", pFeature );
  res = pFeature ->SetValue( "AcquisitionStart" );

  // 4. switch on the event notification (or switch it off with "Off")
  res = GetFeatureByName( "EventNotification", pFeature );
  res = pFeature ->SetValue( "On" );
}

Saving and loading settings

See also

For a quick start, see the LoadSaveSettings example.

Additionally to the user sets stored inside the cameras, you can save the feature values as an XML file to your host PC. For example, you can configure your camera with Vimba Viewer, save the settings as a file, and load them with the API. To do this, use the functions LoadCameraSettings and SaveCameraSettings.

To control which features are saved, use either the function LoadSaveSettingsSetup or the struct below.

Note

Saving and loading all features including look-up tables may take several minutes.

You can manually edit the XML file if you want only certain features to be restored.

Struct VmbFeaturePersistSettings_t

Struct Entry

Purpose

VmbFeaturePersist_t persistType

Controls which features are saved. Valid values:
VmbFeaturePersistAll (all features)
VmbFeaturePersistStreamable (streamable features
only, excluding look-up tables
VmbFeaturePersistNoLUT (default, all features
except look-up tables

VmbCameraPersistFlags_t

Optional flags, see above

Vmbuint32_t maxIterations

Number of iterations. LoadCameraSettings iterates
through all given features of the XML file and tries
to set each value to the camera. Because of complex
feature dependencies, writing a feature value may
impact another feature that has already been set by
LoadCameraSettings. To ensure all values are written
as desired, the feature list can be looped several
times, given by this parameter.
Default value: 5, valid values: 1…10

Triggering

Note

Before triggering, startup the API and open the camera(s).

Tip

To easily configure the camera’s trigger settings, use Vimba Viewer and save/load the settings.

External trigger

The following code snippet shows how to trigger your camera with an external device.

External trigger code snippet
// Startup the API, get cameras and open cameras as usual
// Trigger cameras according to their interface
// Configure trigger input line and selector , switch trigger on
( *iter )->GetInterfaceType( pinterface );
switch( pinterface )
{
case VmbInterfaceEthernet:
( *iter )->GetFeatureByName( "TriggerSelector", pFeature );
pFeature ->SetValue( "FrameStart" );
( *iter )->GetFeatureByName( "TriggerSource", pFeature );
pFeature ->SetValue( "Line1" );
( *iter )->GetFeatureByName( "TriggerMode", pFeature );
pFeature ->SetValue( "On" );
break;

// USB: VmbInterfaceUsb
// CSI -2: VmbInterfaceCSI2

case VmbInterfaceUsb:
( *iter )->GetFeatureByName( "LineSelector", pFeature );
pFeature ->SetValue( "Line0" );
( *iter )->GetFeatureByName( "LineMode", pFeature );
pFeature ->SetValue( "Input" );
( *iter )->GetFeatureByName( "TriggerSource", pFeature );
pFeature ->SetValue( "Line0" );
( *iter )->GetFeatureByName( "TriggerMode", pFeature );
pFeature ->SetValue( "On" );
break;
}

Trigger over Ethernet – Action Commands

See also

For a quick start, see the ActionCommands example.

See also

Find more details in the application note: Trigger over Ethernet (ToE) - Action Commands

Triggering via the AcquisitionStart command is supported by all cameras. However, it is less precise than triggering with an external device connected to the camera’s I/O port. Some GigE cameras additionally support Action Commands. With Action Commands, you can broadcast a trigger signal simultaneously to multiple GigE cameras via GigE cable. Action Commands must be set first to the camera(s) and then to the TL, which sends the Action Commands to the camera(s). As trigger source, select Action0 or Action1.

ActionControl parameters

The following ActionControl parameters must be configured on the camera(s) and on the TL.

  • ActionDeviceKey must be equal on the camera and on the host PC. Before a camera accepts an Action Command, it verifies if the received key is identical with its configured key. Note that ActionDeviceKey must be set each time the camera is opened. Range (camera and host PC): 0 to 4294967295

  • ActionGroupKey means that each camera can be assigned to exactly one group for Action0 and a different group for Action1. All grouped cameras perform an action at the same time. If this key is identical on the sender and the receiving camera, the camera performs the assigned action. Range (camera and host PC): 0 to 4294967295

  • ActionGroupMask serves as filter that specifies which cameras within a group react on an Action Command. It can be used to create sub-groups. Range (camera): 0 to 4294967295 Range (host PC): 1 to 4294967295

Executing the feature ActionCommands sends the ActionControl parameters to the cameras and triggers the assigned action, for example, image acquisition. Before an Action Command is executed, each camera validates the received ActionControl parameter values against its configured values. If they are not equal, the camera ignores the command.

Action Commands code snippet
// Additionally to this code snippet:
// Configure the trigger settings and add image streaming

int deviceKey = 11, groupKey = 22, groupMask = 33;
FeaturePtr feature;

// Startup Vimba
VimbaSystem& system = VimbaSystem :: GetInstance ();
system.Startup ();

// Get cameras
CameraPtrVector cameras;
system.GetCameras( cameras );

for( int i=0; i<cameras.size (); ++i )
{
   // Open camera
   CameraPtr camera = cameras.at(i);
   camera ->Open ();

   // Set Action Command to camera
   camera ->GetFeatureByName( "ActionDeviceKey", feature );
   feature ->SetValue( deviceKey );

   camera ->GetFeatureByName( "ActionGroupKey", feature );
   feature ->SetValue( groupKey );

   camera ->GetFeatureByName( "ActionGroupMask", feature );
   feature ->SetValue( groupMask );
}

// Set Action Command to camera
camera ->GetFeatureByName( "ActionDeviceKey", feature );
feature ->SetValue( deviceKey );
camera ->GetFeatureByName( "ActionGroupKey", feature );
feature ->SetValue( groupKey );
camera ->GetFeatureByName( "ActionGroupMask", feature );
feature ->SetValue( groupMask );

// Set Action Command to Vimba API
system ->GetFeatureByName( "ActionDeviceKey", feature );
feature ->SetValue( deviceKey );
system ->GetFeatureByName( "ActionGroupKey", feature );
feature ->SetValue( groupKey );
system ->GetFeatureByName( "ActionGroupMask", feature );
feature ->SetValue( groupMask );

// Send Action Command
system ->GetFeatureByName( "ActionCommand", feature )
feature ->RunCommand ();

for( int i=0; i<cameras.size (); ++i )
{
   // Close camera
   CameraPtr camera = cameras.at(i);
   camera ->Close ();
}

// Shutdown Vimba
system.Shutdown ();

Listing interfaces

You can list all found interfaces such as frame grabbers or NICs. VimbaSystem::GetInterfaces enumerates all interfaces recognized by the underlying transport layers.

Get interfaces code snippet
std:: string name;
InterfacePtrVector interfaces;
VimbaSystem &system = VimbaSystem :: GetInstance ();

if ( VmbErrorSuccess == system.Startup () )
{
  if ( VmbErrorSuccess == system.GetInterfaces( interfaces ) )
  {
    for ( InterfacePtrVector :: iterator iter = interfaces.begin ();
          interfaces.end() != iter;
          ++iter )
    {
      if ( VmbErrorSuccess == (*iter)->GetName( name ) )
      {
        std::cout << name << std::endl;
      }
    }
  }
}

The Interface class provides the member functions to obtain information about an interface listed in the following table.

Basic functions of the Interface class

Function (returning VmbErrorType)

Purpose

GetID( std::string& ) const

The unique ID

GetName( std::string& ) const The name

The name

GetType( VmbInterfaceType& ) const

The camera interface type

GetSerialNumber( std::string& ) const

The serial number (not in use)

GetPermittedAccess( VmbAccessModeType& ) const

The mode to open the interface

Error codes

For error codes and other technical issues, see Troubleshooting.