CPP API Manual
Introduction to the API
The 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 using the 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
The C++ API release build is compatible with Visual Studio 2017. 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.
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.
API usage
Entry point
The entry point to the C++ API is the VmbSystem singleton. To obtain a
reference to it, call the static function VmbSystem::GetInstance
. All
C++ classes reside in the namespace VmbCPP, so employ the using
declaration using VmbCPP
.
API version
Even if new features are introduced to the C++ API, your software
remains backward compatible. Use VmbSystem::QueryVersion
to check
the version number of the 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:
VmbSystem::Startup()
initializes the API, the TLs, and Interfaces. With the optional parameterpathConfiguration
, you can select which transport layers are used.VmbSystem::Shutdown()
shuts down the API and destroys all used objects in the API (when all observers have finished execution).
VmbSystem::Startup
and VmbSystem::Shutdown
must always be paired.
Calling the pair several times within the same program is possible,
but not recommended.
Successive calls of VmbSystem::Startup
or VmbSystem::Shutdown
are
ignored and the first VmbSystem::Shutdown
after a VmbSystem::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
VmbSystem::Shutdown
blocks until all callbacks have finished execution.
Listing cameras
The function VmbSystem::GetCameras
enumerates all cameras recognized by the underlying transport layers.
With this command, you 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 the camera id and the camera model.
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 ICameraListObserver
with VmbSystem.
In this case, a call to VmbSystem::GetCameras
or
VmbSystem::GetCameraByID
returns immediately.
If no camera list observer is registered, a call to
VmbSystem::GetCameras
or
VmbSystem::GetCameraByID
takes some time because the responses to
the initiated discovery command must be waited for.
USB 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 VmbSystem::GetCameras
returns immediately.
Camera Link cameras
The specifications of Camera Link and GenCP do not support plug & play or
discovery events. To detect changes to the camera list, shutdown and startup
the API by calling VmbSystem::Shutdown
and VmbSystem::Startup
consecutively.
MIPI CSI 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.
std::string name;
CameraPtrVector cameras;
VmbSystem& system = VmbSystem::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;
}
}
}
}
Function |
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 |
The following table lists additional functions of the Camera class.
Camera class member functions |
Comment |
---|---|
GetInterface() |
Access the Interface and its features |
GetTransportLayer() |
Access the TL and its features |
GetLocalDevice() |
Access local device features |
GetStreams() |
Enumerate camera streams |
GetExtendedID() |
Get the Extended ID (if available) |
GetLocalDevice() |
Access local device features |
Extended ID
Tip
In most cases, the Extended ID is not needed.
If several TLs are available for one camera, the camera is listed several times.
To avoid potential conflicts, the SDK automatically creates an extended ID string for each camera.
The extended ID string is provided in the struct VmbCameraInfo_t: cameraIdStringExtended
.
Extended IDs use the following grammar:
extended_id : <tl_identifier-char-count> separator tl_identifier <interface_id-char-count>
separator interface_id <camera_id-char-count> separator camera_id separator : ':'`
Note
Extended IDs always overwrite other ids. A non-extended ID may be unusable after other cameras are discovered.
Placeholder |
Description |
---|---|
tl_identifier |
File path of the transport layer |
interface_id |
ID of the interface as reported by the transport layer |
camera_id |
Camera (non-extended) ID as reported by the interface |
<tl_identifier-char-count> |
Number of characters (TL ID) encoded as decimal integer |
<interface_id-char-count> |
Number of characters (interface ID) encoded as decimal integer |
<camera_id-char-count> |
Number of characters encoded as decimal integer |
Notifications of changed camera states
For being notified whenever a camera is detected, disconnected, or changes its open state, use
VmbSystem::RegisterCameraListObserver
(GigE and USB only). This call registers a
camera list observer (of type ICameraListObserver
) with the VmbSystem 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:
VmbSystem::Startup
VmbSystem::Shutdown
VmbSystem::GetCameras
VmbSystem::GetCameraByID
VmbSystem::RegisterCameraListObserver
VmbSystem::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 the function
VmbSystem::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).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).
CameraPtrVector cameras;
VmbSystem& system = VmbSystem::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.
CameraPtr camera;
VmbSystem& system = VmbSystem::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
.
// The "camera" object points to an opened camera
if( VmbErrorSuccess == camera->Close() )
{
std::cout << "Camera closed" << std::endl;
}
Accessing features
The function Camera::Open
provides access to the features of the Remote Device module.
To access features of the interface, you can retrieve the pointer to the Interface instance
via the member function Camera::GetInterface()
. For accessing the features of the
Transport Layer Camera::GetTransportLayer()
can be used.
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.
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 the class Feature
to access them as shown in the following
code snippets:
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:
FeaturePtr feature;
if( VmbErrorSuccess == camera->GetFeatureByName( "AcquisitionMode", feature ) )
{
if( VmbErrorSuccess == feature->SetValue( "Continuous" ) )
{
if( VmbErrorSuccess == camera->GetFeatureByName( "AcquisitionStart",
feature ) )
{
if( VmbErrorSuccess == feature->RunCommand() )
{
std::cout << "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 section 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.
Function |
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 |
GetFlags( VmbFeatureFlagsType& ) |
Static feature flags, containing information |
GetCategory( std::string& ) |
Category the feature belongs to, used for |
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 |
GetVisibility( VmbFeatureVisibilityType& ) |
The audience the feature is for |
GetToolTip( std::string& ) |
Short description of the feature, used |
GetDescription( std::string& ) |
Description of the feature, used |
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 |
Feature |
Type |
Access |
Description |
---|---|---|---|
AcquisitionMode |
Enumeration |
R/W |
Values: Continuous, |
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 |
Use VmbPayloadSizeGet() |
Note
Functions that must not be called within the feature observer:
VmbSystem::Startup
VmbSystem::Shutdown
VmbSystem::GetCameras
VmbSystem::GetCameraByID
VmbSystem::RegisterCameraListObserver
VmbSystem::UnregisterCameraListObserver
Feature::SetValue
Feature::RunCommand
Acquiring images
See also
The SDK Manual describes synchronous and asynchronous image acquisition.
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:
Asynchronous image acquisition
The following code snippet is a minimalistic example of asynchronous image acquisition. It uses the convenience functions
#include "VmbCPP/VmbCpp.h"
using namespace VmbCPP;
class FrameObserver : public IFrameObserver
{
public:
FrameObserver( CameraPtr pCamera );
void FrameReceived( const FramePtr pFrame );
};
// 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 );
}
int main()
{
VmbErrorType err; // Every Vimba X function returns an error code that
// should always be checked for VmbErrorSuccess (not done here for brevity)
VmbSystem& system = VmbSystem::GetInstance();
err = system.Startup();
// Listing available cameras and selecting the one to use
CameraPtrVector cameras;
err = system.GetCameras( cameras );
CameraPtr camera = cameras.at( 0 ); // For this example we just use the first listed camera
err = camera->Open( VmbAccessModeFull );
// Starting the acquisition
err = camera->StartContinuousImageAcquisition(5, IFrameObserverPtr( new FrameObserver( camera ) ) );
// The camera is now acquiring images and for every recorded frame the
// `FrameObserver::FrameReceived` function above is called.
// Stopping the acquisition and shutting down the API
err = camera->StopContinuousImageAcquisition();
err = system.Shutdown();
}
Image capture
To enable image capture, frame buffers must be allocated and the API must be
prepared for incoming frames. This is done in the convenience function
Camera::StartContinuousAcquisition
(Camera::StopContinuousAcquisition
stops acquisition). Note that these convenience functions perform all steps
shown in section Image Capture vs. Image Acquisition 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 acquisition 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.
Optionally, you can activate the alloc and announce functionality for more efficient buffer allocation. To do this, use the optional parameter /x.
Note
CSI-2 cameras only:
We recommend using alloc and announce. If you want to use the announce mode with the CSI TL,
without using the Convenience functions AcquireSingleImage()
, AcquireMultipleImages()
,
and StartContinuousImageAcquisition()
, make sure you pass the StreamBufferAlignment
within the Frame Constructor.
Asynchronous image capture step by step:
Open the camera as described in chapter Opening and closing a camera.
Query the necessary buffer size through the convenience function
VmbPayloadsizeGet()
.Allocate frames of this size.
Announce the frames.
Start the capture engine.
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 Acquiring images.
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.
Stop the capture engine and discard all pending callbacks with
Camera::EndCapture
.Call
Camera::FlushQueue
to cancel all frames on the queue. If the API has done the memory allocation, this memory is not released untilRevokeAllFrames
,RevokeFrame
,EndCapture
, orClose
functions have been called.Revoke the frames with
Camera::RevokeAllFrames
to clear the buffers.
To synchronously capture images (blocking your execution thread), follow these steps:
Open the camera as described in section Opening and closing a camera.
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 Acquiring images).
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:
VmbSystem::Startup
VmbSystem::Shutdown
VmbSystem::OpenCameraByID
Camera::Open
Camera::Close
Camera::AcquireSingleImage
Camera::AcquireMultipleImages
Camera::StartContinuousImageAcquisition
Camera::StopContinuousImageAcquisition
Camera::StartCapture
Camera::EndCapture
Camera::AnnounceFrame
Camera::RevokeFrame
Stream::Open
Stream::Close
Stream::AcquireSingleImage
Stream::AcquireMultipleImages
Stream::StartCapture
Stream::EndCapture
Stream::AnnounceFrame
Stream::RevokeFrame
Stream::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 wish to setup capture step by step as described in section Image capture, you have to start image acquisition on your camera:
Set the feature AcquisitionMode (for example, to Continuous).
Run the command AcquisitionStart.
To stop image acquisition, run command AcquisitionStop. The code snippet below shows a modification of the main function of the simple image streaming example above.
int main()
{
VmbErrorType err; // Every Vimba X function returns an error code that
// should always be checked for VmbErrorSuccess (not done here for brevity)
VmbSystem& system = VmbSystem::GetInstance();
err = system.Startup();
// Listing available cameras and selecting the one to use
CameraPtrVector cameras;
err = system.GetCameras( cameras );
CameraPtr camera = cameras.at( 0 ); // For this example we just use the first listed camera
err = camera->Open( VmbAccessModeFull );
FramePtrVector frames( 5 ); // A list of frames for streaming. We chose to queue 5 frames.
IFrameObserverPtr observer(
new FrameObserver( camera ) ); // Our implementation of a frame observer
FeaturePtr feature; // Variable to hold features that need to be used
VmbUint32_t payloadSize; // The payload size of one frame
err = camera->GetPayloadSize( payloadSize );
for( FramePtrVector::iterator iter = frames.begin(); frames.end() != iter; ++iter )
{
( *iter ).reset( new Frame( payloadSize ) );
err = ( *iter )->RegisterObserver( observer );
err = camera->AnnounceFrame( *iter );
}
err = camera->StartCapture();
for( FramePtrVector ::iterator iter = frames.begin(); frames.end() != iter; ++iter )
{
err = camera->QueueFrame( *iter );
}
err = camera->GetFeatureByName( "AcquisitionMode", feature );
err = feature->SetValue( "Continuous" );
err = camera->GetFeatureByName( "AcquisitionStart", feature );
err = feature->RunCommand();
// Program runtime ...
// When finished , tear down the acquisition chain , close camera and API
err = camera->GetFeatureByName( "AcquisitionStop", feature );
err = feature->RunCommand();
err = camera->EndCapture();
err = camera->FlushQueue();
err = camera->RevokeAllFrames();
err = camera->Close();
err = system.Shutdown();
}
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,
Using Events
Events serve a multitude of purposes and can have several origins such as VmbSystem, 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 chapter:
Camera list notifications
Tracking invalidations of features
Explicit camera event features
For camera list notifications, see the code snippet below:
// 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
}
}
};
int main()
{
VmbErrorType res;
VmbSystem& system = VmbSystem::GetInstance();
FeaturePtr pFeature;
// 2. Register the observer; automatic discovery for GigE is turned on
res = system.RegisterCameraListObserver( ICameraListObserverPtr( new CamObserver() ) );
}
// 1. define observer
class WidthObserver : public IFeatureObserver
{
// ...
public:
void FeatureChanged( const FeaturePtr& feature )
{
if( feature != nullptr )
{
VmbError_t err;
std::string strName( "" );
err = feature->GetDisplayName( strName );
std::cout << strName << " changed" << std::endl;
}
}
};
int main()
{
// Assuming an opened camera instance
VmbErrorType err;
FeaturePtr feature;
// 2. register the observer for the camera event
err = camera->GetFeatureByName( "Width", feature );
err = feature->RegisterObserver( IFeatureObserverPtr( new WidthObserver() ) );
// As an example , binning is changed , so the observer will be run
err = camera->GetFeatureByName( "BinningHorizontal", feature );
err = feature->SetValue( "8" );
}
// 1. define observer
class EventObserver : public IFeatureObserver
{
//...
public:
void FeatureChanged( const FeaturePtr& feature )
{
if( feature != nullptr )
{
VmbErrorType err;
std::string strName( "" );
err = feature->GetDisplayName( strName );
std::cout << "Event " << strName << " occurred" << std::endl;
}
};
};
int main()
{
// Assuming an opened camera instance
VmbErrorType err;
FeaturePtr feature;
// 2. register the observer for the camera event
err = camera->GetFeatureByName( "EventAcquisitionStart", feature );
err = feature->RegisterObserver( IFeatureObserverPtr( new EventObserver() ) );
// 3. select "AcquisitionStart" (or a different) event
err = camera->GetFeatureByName( "EventSelector", feature );
err = feature->SetValue( "AcquisitionStart" );
// 4. switch on the event notification (or switch it off with "Off")
err = camera->GetFeatureByName( "EventNotification", feature );
err = feature->SetValue( "On" );
}
Chunk
Note
To use the chunk feature, make sure your camera supports it.
Chunk data are image metadata such as the exposure time that are available in the Frame. To activate chunk, see the user documentation of your camera.
To access the chunk feature, call Frame::AccessChunkData()
from FrameObserver::FrameReceived()
.
Within this function, you can access chunk features via the FeatureContainerPtr
.
See also
See the ChunkAccess example.
See also
For user defined error codes, see the code snippet in section Chunk in the C API Manual.
Saving and loading settings
Additionally to the user sets stored inside the cameras, you can save the feature values of the GenTL modules as an XML file to your host PC.
#include <filesystem>
#include <VmbCPP/VmbCPP.h>
using namespace VmbCPP;
int main()
{
VmbSystem& system = VmbSystem::GetInstance();
CameraPtrVector cameras;
if( VmbErrorSuccess == system.Startup() )
{
if( VmbErrorSuccess == system.GetCameras( cameras ) )
{
if( cameras.size() > 0 )
{
CameraPtr camera = cameras.at( 0 );
if( VmbErrorSuccess == camera->Open( VmbAccessModeFull ) )
{
std::filesystem::path xmlFile( "camera_0_settings.xml" );
VmbFeaturePersistSettings_t settingsStruct;
settingsStruct.loggingLevel = 1;
settingsStruct.maxIterations = 5;
settingsStruct.persistType = VmbFeaturePersistNoLUT;
if( VmbErrorSuccess != camera->SaveSettings( xmlFile.c_str(), &settingsStruct ) )
{
std::cout << "Could not save camera settings to '" << xmlFile << "'"
<< std::endl;
}
camera->Close();
}
}
}
system.Shutdown();
}
}
Logging levels:
0: Info only
1: With errors
2: With warnings
3: Debug
4: Trace
Iterations: Several iterations may be needed to catch all feature dependencies (compare desired value with camera value and write it to camera).
To control which features are saved, see the C API Manual, chapter Saving and loading settings.
Triggering
Note
Before triggering, startup the API and open the camera(s).
External trigger
The following code snippet shows how to trigger your camera with an external device.
// 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
for( CameraPtrVector::iterator iter = cameras.begin(); cameras.end() != iter; ++iter )
{
VmbTransportLayerType inter;
FeaturePtr feature;
( *iter )->GetInterfaceType( inter );
switch( inter )
{
case VmbTransportLayerTypeGEV:
( *iter )->GetFeatureByName( "TriggerSelector", feature );
feature->SetValue( "FrameStart" );
( *iter )->GetFeatureByName( "TriggerSource", feature );
feature->SetValue( "Line1" );
( *iter )->GetFeatureByName( "TriggerMode", feature );
feature->SetValue( "On" );
break;
case VmbTransportLayerTypeU3V:
( *iter )->GetFeatureByName( "LineSelector", feature );
feature->SetValue( "Line0" );
( *iter )->GetFeatureByName( "LineMode", feature );
feature->SetValue( "Input" );
( *iter )->GetFeatureByName( "TriggerSource", feature );
feature->SetValue( "Line0" );
( *iter )->GetFeatureByName( "TriggerMode", feature );
feature->SetValue( "On" );
break;
}
}
Listing interfaces
You can list all found interfaces such as frame grabbers or NICs.
VmbSystem::GetInterfaces
enumerates all interfaces recognized by
the underlying transport layers.
std::string name; InterfacePtrVector interfaces; VmbSystem& system = VmbSystem::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.
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) |
Error codes
For error codes and other technical issues, see Troubleshooting.