The pylon Programmer's Guide is a quick guide on how to program using the Basler pylon C++ API. It can be used together with the pylon sample code for getting started. Additionally, the API reference provides documentation about the Basler pylon C++ interface. The documentation of the interfaces is also available in the header files of pylon. When using Microsoft Visual Studio right-click on the desired method or class and select 'Go To Declaration' from the context menu to go to the related documentation.
For information when programming for Basler blaze cameras, refer to the pylon Supplementary Package for blaze (available for download on the Basler website). This includes a C++ API and a .NET API as well as sample code.
Common Settings for Building Applications with pylon (Windows)#
This section shows the most common Microsoft Visual Studio build settings for building an application using pylon. Consult the Advanced Topics section for more information, e.g. when a different configuration is required.
Add the following include directories for Release and Debug project configurations (Configuration Properties -> C/C++ -> General -> Additional Include Directories):
$(PYLON_DEV_DIR)\include;
Add the following library directories for Release and Debug project configurations (Configuration Properties -> Linker -> General -> Additional Library Directories) for 32-Bit:
$(PYLON_DEV_DIR)\lib\Win32;
For 64-Bit configurations add
$(PYLON_DEV_DIR)\lib\x64;
Enable runtime type info for Release and Debug project configurations (Configuration Properties -> C/C++ -> Language -> Enable Runtime Type Info).
yes
Enable C++ exceptions for Release and Debug project configurations (Configuration Properties -> C/C++ -> Code Generation -> Enable C++ Exceptions).
yes
Common Settings for Building Applications with pylon (Linux)#
This section shows the most common Linux build settings for building an application using pylon and the GNU tool chain. Consult the Advanced Topics section for more information.
To collect all the required parameters to build a pylon-based application, we created the pylon-config utility. It works like pkg-config and you can call pylon-config \--help to get a list of supported parameters.
In a typical GNU Make-based project you can add the following lines to your Makefile:
If needed, you can now overwrite the default installation path using the environment variable <PYLON_ROOT>. E.g.:
PYLON_ROOT=/path/to/your/pylon/installmake
Common Settings for Building Applications with pylon (macOS)#
This section shows the most common macOS build settings for building an application using pylon and Apple Xcode. Consult the Advanced Topics section for more information, e.g. when a different configuration is required.
First add the pylon framework to your project, right-click on your project and choose Add files to "\<Projectname\>".... Browse to the install location of the pylon framework, typically /Library/Frameworks and choose pylon.framework, click Add button.
Add the following user-defined variable for Release and Debug configurations to your build target (Build Settings -> User-Defined -> PYLON_LIBRARY_DIR):
/Library
Add the following Framework Search Paths for Release and Debug configurations to your build target (Build Settings -> Search Paths -> Framework Search Paths):
$(PYLON_LIBRARY_DIR)/Frameworks
Add the following Header Search Paths for Release and Debug configurations to your build target (Build Settings -> Search Paths -> Header Search Paths):
The pylon SDK Package includes the pylon-config.cmake and pylonc-config.cmake modules that are used to determine the installation location of pylon. These modules export the pylon::pylon CMake target for the C++ interface and the pylonC::PylonC CMake target for the C interface respectively. Pass one of these targets as argument to target_link_libraries, and CMake will take care of setting the include path, library path, etc. The modules are located in the pylon installation folder and will be found automatically by CMake.
A basic CMakeLists.txt CMake file could look like this:
In case pylon-config.cmake is not found automatically, make sure the path to the pylon runtime binaries (i.e., C:\Program Files\Basler\pylon\Runtime\x64) is set in the Windows PATH environment variable. Make sure PYLON_DEV_DIR is set correctly (i.e., to C:\Program Files\Basler\pylon\Development) or set the environment variable CMAKE_PREFIX_PATH manually to the pylon CMake folder (i.e., C:\Program Files\Basler\pylon\Development\CMake).
Use the CMake command
set(CMAKE_FIND_DEBUG_MODEON)
as a helper in your CMakeLists.txt file before the find_package statement to list all folders where CMake searches for the pylon-config.cmake or pylonc-config.cmake file.
If there is no CMake >= 3.14 installed, download a CMake Windows installer from https://cmake.org/download. Launch the .msi installer and follow the instructions.
When debugging a pylon application using GigE cameras you may encounter heartbeat timeouts. The application must send special network packets to the camera in defined intervals. If the camera doesn't receive these heartbeats it will consider the connection as broken and won't accept any commands from the application. This requires setting the heartbeat timeout of a camera to a higher value when debugging. The Advanced Topics section shows how to do this.
Initialization/Uninitialization of the pylon Runtime Library#
The pylon runtime system must be initialized before use. A pylon-based application must call the PylonInitialize() method before using any other functions of the pylon runtime system. Before an application exits, it must call the PylonTerminate() method to free resources allocated by the pylon runtime system.
#include<pylon/PylonIncludes.h>usingnamespacePylon;intmain(intargc,char*argv[]){Pylon::PylonAutoInitTermautoInitTerm;// PylonInitialize() will be called now// Use pylon// ..}// autoInitTerm's destructor calls PylonTerminate() now
The Advanced Topics section contains additional information for MFC users.
In the case of errors, the methods of pylon classes may throw C++ exceptions. The pylon C++ API throws exceptions of type GenericException or that are subclasses of GenericException. You should guard pylon calls with exception handlers catching GenericException. Example:
try{camera.Width.SetValue(640);}catch(constGenericException&e){cerr<<"Failed to set the AOI width. Reason: "<<e.GetDescription()<<endl;}
The first found camera device is created, e.g. for a vision system that uses only one camera. The Advanced Topics section shows how to handle multiple camera devices and how to find specific camera devices.
Instant Camera classes make it possible to grab images with a few lines of code reducing the programming effort to a minimum. An Instant Camera class uses a pylon Device internally. The pylon Device needs to be created and attached to the Instant Camera object for operation.
Example:
// Create an instant camera object with the camera device found first.CInstantCameracamera(CTlFactory::GetInstance().CreateFirstDevice());// Print the model name of the camera.cout<<"Using device "<<camera.GetDeviceInfo().GetModelName()<<endl;// Start the grabbing of c_countOfImagesToGrab images.// The camera device is parameterized with a default configuration which// sets up free-running continuous acquisition.camera.StartGrabbing(c_countOfImagesToGrab);// This smart pointer will receive the grab result data.CGrabResultPtrptrGrabResult;// Camera.StopGrabbing() is called automatically by the RetrieveResult() method// when c_countOfImagesToGrab images have been retrieved.while(camera.IsGrabbing()){// Wait for an image and then retrieve it. A timeout of 5000 ms is used.camera.RetrieveResult(5000,ptrGrabResult,TimeoutHandling_ThrowException);// Image grabbed successfully?if(ptrGrabResult->GrabSucceeded()){// Access the image data.cout<<"SizeX: "<<ptrGrabResult->GetWidth()<<endl;cout<<"SizeY: "<<ptrGrabResult->GetHeight()<<endl;constuint8_t*pImageBuffer=(uint8_t*)ptrGrabResult->GetBuffer();cout<<"Gray value of first pixel: "<<(uint32_t)pImageBuffer[0]<<endl<<endl;}else{cout<<"Error: "<<std::hex<<ptrGrabResult->GetErrorCode()<<std::dec<<" "<<ptrGrabResult->GetErrorDescription()<<endl;}}
The above code snippet can be found in the code sample Grab Sample.
The Instant Camera classes establish convenient access to a camera device while being highly customizable. The following list shows the main features of an Instant Camera class:
It serves as single access point for accessing camera functionality.
It can be used "out of the shelf" without setting any parameters. The camera uses a default configuration for the device. The default configuration can be overridden.
It handles pylon Device lifetime.
It opens and closes a pylon Device automatically.
It handles the creation, reuse and destruction of buffers.
It provides a grab loop thread if required.
It detects camera device removal.
It supports advanced camera features like chunk mode and event reporting (camera events).
Is extensible using derivation.
Is extensible by registering additional event handler objects.
The CBaslerUniversalInstantCamera class is a specialization of the CInstantCamera class, extending it by a parameter class. The parameter class provides a member for each camera parameter. The additional parameter class provides IDE auto completion (e.g., IntelliSense in Visual Studio) and is helpful when developing an application. It adds a small but neglectable runtime overhead.
The Instant Camera classes allow to register event handler objects for customizing the behavior of the camera object, for processing grab results, and for handling camera events. The following list shows the available event handler types.
Configuration event handler - can be used for customizing the behavior of the camera; must be derived from the Pylon::CConfigurationEventHandler base class.
Image event handler - can be used for processing the grab results; must be derived from the Pylon::CImageEventHandler base class.
Camera event handler - must be used for processing camera events; must be derived from the Pylon::CCameraEventHandler base class.
A custom event handler class can override one or more virtual methods of the base class. For instance whenever Pylon::CConfigurationEventHandler::OnOpened is called by an Instant Camera object it is the right time to set up camera parameters. The following code snippet shows an example of a configuration event handler setting the image area of interest (Image AOI) and the pixel format.
classCPixelFormatAndAoiConfiguration:publicPylon::CConfigurationEventHandler{public:voidOnOpened(Pylon::CInstantCamera&camera){try{// Allow all the names in the namespace GenApi to be used without qualification.usingnamespacePylon;// Get the camera control object.GenApi::INodeMap&nodemap=camera.GetNodeMap();// Get the parameters for setting the image area of interest (Image AOI).CIntegerParameterwidth(nodemap,"Width");CIntegerParameterheight(nodemap,"Height");CIntegerParameteroffsetX(nodemap,"OffsetX");CIntegerParameteroffsetY(nodemap,"OffsetY");// Maximize the Image AOI.offsetX.TrySetToMinimum();// Set to minimum if writable.offsetY.TrySetToMinimum();// Set to minimum if writable.width.SetToMaximum();height.SetToMaximum();// Set the pixel data format.CEnumParameter(nodemap,"PixelFormat").SetValue("Mono8");}catch(constPylon::GenericException&e){throwRUNTIME_EXCEPTION("Could not apply configuration. const GenericException caught in OnOpened method msg=%hs",e.what());}}};
One or more event handler objects can be registered at the Instant Camera object. The following code snippet shows an example of how the above event handler is registered and appended to the configuration event handler list.
// Register an additional configuration handler to set the image format and adjust the AOI.// By setting the registration mode to RegistrationMode_Append, the configuration handler is added instead of replacing// the already registered configuration handler.camera.RegisterConfiguration(newCPixelFormatAndAoiConfiguration,RegistrationMode_Append,Cleanup_Delete);
Configuration event handler classes are also just called "configurations" because they encapsulate certain camera configurations. The pylon C++ API comes with the following configuration classes:
These classes are provided as header files. This makes it possible to see what parameters of the camera are changed. The code can be copied and modified for creating own configuration classes. Pylon::CSoftwareTriggerConfiguration for instance can be used as basis for creating a hardware trigger configuration with few modifications. Pylon::CAcquireContinuousConfiguration is already registered when creating an Instant Camera class, providing a default setup that will work for most cameras.
The following example shows how to apply the software trigger configuration:
// Register the standard configuration event handler for enabling software triggering.// The software trigger configuration handler replaces the default configuration// as all currently registered configuration handlers are removed by setting the registration mode to RegistrationMode_ReplaceAll.camera.RegisterConfiguration(newCSoftwareTriggerConfiguration,RegistrationMode_ReplaceAll,Cleanup_Delete);
Handling Multiple Cameras Using Instant Camera Arrays#
The Instant Camera Array classes help managing multiple cameras in a system. An Instant Camera Array represents an array of Instant Camera objects. It provides almost the same interface as an Instant Camera for grabbing. The main purpose of the CInstantCameraArray is to simplify waiting for images and camera events of multiple cameras in one thread. This is done by providing a single RetrieveResult method for all cameras in the array. The following classes are available:
For camera configuration and for accessing other parameters, the pylon API uses the technologies defined by the GenICam standard. The GenICam specification (http://www.GenICam.org) defines a format for camera parameter description files. These files describe the configuration interface of GenICam compliant cameras. The description files are written in XML (eXtensible Markup Language) and describe camera registers, their interdependencies, and all other information needed to access high-level features such as Gain, Exposure Time, or Image Format by means of low level register read and write operations.
The elements of a camera description file are represented as software objects called Nodes. For example, a node can represent a single camera register, a camera parameter such as Gain, a set of available parameter values, etc. Each node implements the GenApi::INode interface.
The nodes have different types. For example, there are nodes representing integer values and other nodes representing strings. For each type of parameter, there is an interface in GenApi. pylon provides additional interfaces and parameter classes to simplify access to the GenApi interfaces. These interfaces and parameter classes are described in the ParameterTypes section. The AccessModes section introduces the concept of a parameter access mode. An access mode property is used to determine whether a parameter is available, readable, or writable.
The complete set of nodes is stored in a data structure called node map.
Note
Not only camera devices are parameterized using GenICam node maps. Also, most pylon objects provide node maps to provide access to their parameters. Therefore, a common way for accessing parameters is established.
Before reading or writing parameters of a camera, the drivers involved must be initialized and a connection to the physical camera device must be established. This is done by calling the Open() method. The camera can be closed using the Close() method.
pylon provides programming interface classes that are created from parameter description files using the code generators. These classes are exported by the Universal Instant Camera class. This provides a member for each available parameter. The Pylon::CBaslerUniversalInstantCamera class extends the GenApi interfaces to simplify parameterization. This is the easiest way to access parameters.
Example:
// Maximize the image area of interest (Image AOI).camera.OffsetX.TrySetToMinimum();camera.OffsetY.TrySetToMinimum();camera.Width.SetToMaximum();camera.Height.SetToMaximum();// Set the pixel data format.camera.PixelFormat.SetValue(PixelFormat_Mono8);
The complete set of nodes is stored in a data structure called node map. At runtime, a node map is instantiated from an XML description. The parameters or nodes must be accessed using a node map object together with pylon parameter classes based on Pylon::CParameter.
Example (setting the same parameters as in the above example):
// Allow all the names in the namespace GenApi to be used without qualification.usingnamespacePylon;// Get the camera control object.GenApi::INodeMap&nodemap=camera.GetNodeMap();// Get the parameters for setting the image area of interest (Image AOI).CIntegerParameterwidth(nodemap,"Width");CIntegerParameterheight(nodemap,"Height");CIntegerParameteroffsetX(nodemap,"OffsetX");CIntegerParameteroffsetY(nodemap,"OffsetY");// Maximize the Image AOI.offsetX.TrySetToMinimum();// Set to minimum if writable.offsetY.TrySetToMinimum();// Set to minimum if writable.width.SetToMaximum();height.SetToMaximum();// Set the pixel data format.CEnumParameter(nodemap,"PixelFormat").SetValue("Mono8");
The GenApi::IInteger interface (optionally extended by Pylon::IIntegerEx and Pylon::CIntegerParameter) is used to access integer parameters. An integer parameter represents a feature that can be set by an integer number, such as a camera's image width or height in pixels. The current value of an integer parameter is augmented by a minimum and a maximum value, defining a range of allowed values for the parameter, and by an increment that acts as a 'step width' for changes to the parameter's value. The set of all allowed values for an integer parameter can hence be expressed as x:={minimum}+N*{increment}, with N=0,1,2…, x<={maximum}. The current value, minimum, maximum, and increment can all be accessed as 64 bit values. The following example prints all valid values for the Width parameter:
Floating point parameters are represented by GenApi::IFloat, Pylon::IFloatEx, and Pylon::CFloatParameter objects. A float parameter represents a feature that can be set by a floating-point value, such as a camera's exposure time expressed in seconds. The floating point parameter is similar to the integer parameter with two exceptions: all values are of the 'double' type (double precision floating point numbers as defined by the IEEE 754 standard) and there is no increment value. Hence, a float parameter is allowed to take any value from the interval {minimum} <= x <={maximum}.
A Boolean parameter represents a binary-valued feature which can be enabled or disabled. It is represented by the GenApi::IBoolean interface and Pylon::IBooleanEx and Pylon::CBooleanParameter objects. Example: Any 'switch' to enable or disable a feature, such as a camera's external trigger input. Set and get operations are similar to the ones used by the GenApi::IInteger interface.
Each parameter has an access mode that describes whether a feature is implemented, available, readable, and writable. For a given camera, a feature may not be implemented at all. For example, a monochrome camera will not include a white balance feature. Depending on the camera's state, a feature may temporarily not be available. For example, a parameter related to external triggering may not be available when the camera is in free run mode. Available features can be read-only, write-only, or readable and writable.
The current state of a parameter can be queried by calling the parameter's GetAccessMode() method, which returns a GenApi::EAccessMode enumeration value described in the following table:
EAccessMode
Implemented
Available
Readable
Writable
NI
No
No
No
No
NA
Yes
No
No
No
WO
Yes
Yes
No
Yes
RO
Yes
Yes
Yes
No
RW
Yes
Yes
Yes
Yes
Typically, it is sufficient to check if a parameter is readable or writable. For this purpose, all pylon parameter interfaces and classes implement the methods IsReadable() and IsWritable().
Handling Differences Between Different Cameras Models#
Most features, e.g., Gain, are named according to the GenICam Standard Feature Naming Convention (SFNC). The SFNC defines a common set of features, their behavior, and the related parameter names. All Basler USB 3.0 and CoaXPress as well as most GigE, e.g., ace 2 GigE, cameras are based on the SFNC version 2.0 or later. Older Basler GigE camera models, however, are based on previous SFNC versions. Accordingly, the behavior of these cameras and some parameter names will be different. The following sections show how to handle this.
The pylon parameter interfaces and classes provide methods that are prefixed with "Try", e.g., IEnumerationEx::TrySetValue(int64_t). For these methods, the action is executed if the parameter is writable. Sometimes, the value must also be settable.
Example showing how turn GainAuto off if the camera provides GainAuto:
Methods that are suffixed with "OrDefault", e.g., GetValueOrDefault(), can be used to read a parameter value if it is readable or otherwise return a default value.
Example:
//code that runs for cameras with and without chunk support.if(camera.ChunkModeActive.GetValueOrDefault(false)){//do something if chunk mode is active}
If your code has to work with multiple camera device types that are compatible with different SFNC versions, you can use GetSfncVersion() to handle differences in parameter name and behavior.
// Check to see which Standard Feature Naming Convention (SFNC) is used by the camera device.if(camera.GetSfncVersion()>=Sfnc_2_0_0){// Access the Gain float type node. This node is available for USB camera devices.// USB camera devices are compliant to SFNC version 2.0.CFloatParametergain(nodemap,"Gain");if(gain.TrySetValuePercentOfRange(50.0)){cout<<"Gain (50%) : "<<gain.GetValue()<<" (Min: "<<gain.GetMin()<<"; Max: "<<gain.GetMax()<<")"<<endl;}}else{// Access the GainRaw integer type node. This node is available for GigE camera devices.CIntegerParametergainRaw(nodemap,"GainRaw");if(gainRaw.TrySetValuePercentOfRange(50.0)){cout<<"Gain (50%) : "<<gainRaw.GetValue()<<" (Min: "<<gainRaw.GetMin()<<"; Max: "<<gainRaw.GetMax()<<"; Inc: "<<gainRaw.GetInc()<<")"<<endl;}}
This section shows how to grab images using the Instant Camera class. Before grabbing images the camera parameters must be set up using one or more of the following approaches:
The camera is set up using code in the program flow after Open() is called.
The camera is preconfigured, e.g. using the pylon Viewer. The settings are stored in a user set in the camera and become active when the camera powers up, provided the user set was selected as the "startup set".
Using the latter three approaches may require to remove the default configuration after the Instant Camera object has been created. The following example shows how to do this. The configuration must be removed before calling the Open() method.
// Create a camera objectCInstantCameracamera;// Remove the default configurationcamera.RegisterConfiguration((CConfigurationEventHandler*)NULL,RegistrationMode_ReplaceAll,Cleanup_None);
In this document we distinguish between image acquisition, image data transfer, and image grabbing.
We denote the processes inside the camera as image acquisition. When a camera starts image acquisition, the sensor is exposed. When exposure is complete, the image data is read out from the sensor.
The acquired image data is transferred from the camera's memory to the computer using an interface such as USB or Gigabit Ethernet.
The process of writing the image data into the computer's main memory is referred to as "grabbing" an image.
The data of a grabbed image is held by a Grab Result Data object. The Grab Result Data object can't be directly accessed. It is always held by a grab result smart pointer, e.g. the basic grab result smart pointer CGrabResultPtr. The combination of smart pointer and Grab Result Data object is also referred to as grab result. The smart pointer controls the reuse and the lifetime of the Grab Result Data object and the associated image buffer. When all smart pointers referencing a Grab Result Data object go out of scope, the grab result's image buffer is reused for grabbing. Due to the smart pointer concept, a Grab Result Data object and the associated image buffer can live longer than the camera object used for grabbing the image data. The CBaslerUniversalInstantCamera class has a specific Grab Result Data object and a specific grab result smart pointer. The specific grab result smart pointer can be converted to or from the basic grab result smart pointer CGrabResultPtr by copying or assigning.
Note
The grabbing will stop with a buffer underrun when the grab results are never released, e.g. when put into a container.
The grab result smart pointer classes provide a cast operator that allows passing a grab result smart pointer directly to functions or methods that take a constPylon::IImage&` as parameter, e.g. image saving functions.
Attention
The returned reference to Pylon::IImage is only valid as long the grab result smart pointer it came from is not destroyed.
New buffers are automatically allocated for each grab session starting with StartGrabbing(). The buffer of a grabbed image is held by the Grab Result Data object. While the grabbing is in progress a buffer is reused when the Grab Result Data object is released by the grab result smart pointer. If the Grab Result Data object is released when the grabbing has stopped then the buffer is freed.
The number of used image data buffers can be set using the MaxNumBuffer parameter. The default amount of buffers used for grabbing is 10. The buffer size required for grabbing is automatically determined.
The number of allocated buffers is automatically reduced when grabbing a defined number of images smaller than the value of MaxNumBuffer, e.g. 5.
Note
A buffer factory can be attached to an Instant Camera object for using user provided buffers.
The Instant Camera grab engine consists of an empty buffer queue, an output queue, and a grab thread. The grab engine uses a Low Level API stream grabber to grab images. The empty buffer queue and the output queue can hold the number of buffers defined by the MaxNumBuffer parameter. MaxNumQueuedBuffer buffers are passed to the Low Level API stream grabber at any time. All queues work in FIFO mode (First-In-First-Out). The grab engine thread ensures that the stream grabber does not run out of buffers as long as buffers are available in the empty buffer queue.
The Instant Camera supports different grab strategies. The default strategy is One By One. When the grab strategy One By One is used images are processed in the order of their acquisition.
The Buffer Flow Using Grab Strategy One By One
The Instant Camera grab engine unqueues buffers from the Empty Buffer Queue and queues the empty buffers at the Low Level API stream grabber (1).
The camera device is triggered (2). An image is acquired by the camera device, it is transfered to the computer and then grabbed into an empty buffer.
The Instant Camera grab engine thread is notified that a filled buffer is available. The filled buffer is retrieved by the grab engine thread (3) and is put into the Output Queue.
The application thread waiting inside the RetrieveResult() method is notified, it stops waiting for a grab result, and it retrieves the filled buffer (4) as part of a grab result data object.
The grab result data object is held by a grab result smart pointer. After the application has processed the image data the filled buffer is returned to the Empty Buffer Queue (5). This is done by the grab result smart pointer destructor or when the grab result data object is explicitly released. Returned buffers are used again for grabbing.
More information about grab strategies can be found in the Grab Strategies section.
// Create an instant camera object with the camera device found first.CInstantCameracamera(CTlFactory::GetInstance().CreateFirstDevice());// Print the model name of the camera.cout<<"Using device "<<camera.GetDeviceInfo().GetModelName()<<endl;// Start the grabbing of c_countOfImagesToGrab images.// The camera device is parameterized with a default configuration which// sets up free-running continuous acquisition.camera.StartGrabbing(c_countOfImagesToGrab);// This smart pointer will receive the grab result data.CGrabResultPtrptrGrabResult;// Camera.StopGrabbing() is called automatically by the RetrieveResult() method// when c_countOfImagesToGrab images have been retrieved.while(camera.IsGrabbing()){// Wait for an image and then retrieve it. A timeout of 5000 ms is used.camera.RetrieveResult(5000,ptrGrabResult,TimeoutHandling_ThrowException);// Image grabbed successfully?if(ptrGrabResult->GrabSucceeded()){// Access the image data.cout<<"SizeX: "<<ptrGrabResult->GetWidth()<<endl;cout<<"SizeY: "<<ptrGrabResult->GetHeight()<<endl;constuint8_t*pImageBuffer=(uint8_t*)ptrGrabResult->GetBuffer();cout<<"Gray value of first pixel: "<<(uint32_t)pImageBuffer[0]<<endl<<endl;}else{cout<<"Error: "<<std::hex<<ptrGrabResult->GetErrorCode()<<std::dec<<" "<<ptrGrabResult->GetErrorDescription()<<endl;}}
The camera object is created. The grabbing is started by calling StartGrabbing(). Since the camera is not open yet, it is automatically opened by the StartGrabbing() method. The default configuration event handler is called and it applies the default configuration. Images are grabbed continuously by the Instant Camera object and the grab results are placed into the Instant Camera's output queue in the order they are aqcuired by the camera (Grab Strategy One By One). The RetrieveResult() method is used to wait for a grab result and for retrieving it from the output queue. Some of the grab result data is printed to the screen after it is retrieved. StopGrabbing() is called automatically by the RetrieveResult() method when c_countOfImagesToGrab images have been retrieved. The while statement condition is used to check if the grabbing has been stopped.
It is possible to start grabbing for an unlimited number of images by omitting the maximum number of images to grab in the StartGrabbing() call and call StopGrabbing() from inside the grab loop to finish grabbing.
The above code snippet can be found in the Grab Sample code sample.
Grabbing Images Using the Grab Loop Thread Provided by the Instant Camera#
The Instant Camera class can optionally provide a grab loop thread. The thread runs a grab loop calling RetrieveResult() repeatedly. When using the provided grab loop thread an image event handler is required to process the grab results.
The following image event handler is used:
classCImageEventPrinter:publicCImageEventHandler{public:virtualvoidOnImageGrabbed(CInstantCamera&camera,constCGrabResultPtr&ptrGrabResult){std::cout<<"OnImageGrabbed event for device "<<camera.GetDeviceInfo().GetModelName()<<std::endl;// Image grabbed successfully?if(ptrGrabResult->GrabSucceeded()){std::cout<<"SizeX: "<<ptrGrabResult->GetWidth()<<std::endl;std::cout<<"SizeY: "<<ptrGrabResult->GetHeight()<<std::endl;constuint8_t*pImageBuffer=(uint8_t*)ptrGrabResult->GetBuffer();std::cout<<"Gray value of first pixel: "<<(uint32_t)pImageBuffer[0]<<std::endl;std::cout<<std::endl;}else{std::cout<<"Error: "<<std::hex<<ptrGrabResult->GetErrorCode()<<std::dec<<" "<<ptrGrabResult->GetErrorDescription()<<std::endl;}}};
The following example shows how to grab using the grab loop thread provided by the Instant Camera object:
// The image event printer serves as sample image processing.// When using the grab loop thread provided by the Instant Camera object, an image event handler processing the grab// results must be created and registered.camera.RegisterImageEventHandler(newCImageEventPrinter,RegistrationMode_Append,Cleanup_Delete);// Start the grabbing using the grab loop thread, by setting the grabLoopType parameter// to GrabLoop_ProvidedByInstantCamera. The grab results are delivered to the image event handlers.// The GrabStrategy_OneByOne default grab strategy is used.camera.StartGrabbing(GrabStrategy_OneByOne,GrabLoop_ProvidedByInstantCamera);// Wait for user input to trigger the camera or exit the program.// The grabbing is stopped, the device is closed and destroyed automatically when the camera object goes out of scope.boolrunLoop=true;while(runLoop){cout<<endl<<"Enter \"t\" to trigger the camera or \"e\" to exit and press enter? (t/e) ";cout.flush();stringuserInput;getline(cin,userInput);for(size_ti=0;i<userInput.size();++i){charkey=userInput[i];if((key=='t'||key=='T')){// Execute the software trigger. Wait up to 1000 ms for the camera to be ready for trigger.if(camera.WaitForFrameTriggerReady(1000,TimeoutHandling_ThrowException)){camera.ExecuteSoftwareTrigger();}}elseif((key=='e')||(key=='E')){runLoop=false;break;}}// Wait some time to allow the OnImageGrabbed handler print its output,// so the printed text on the console is in the expected order.WaitObject::Sleep(250);}
First, the image event handler is registered. It prints a message on the screen for every grabbed image. It serves as image processing in this example. The grabbing is started using StartGrabbing() for an unlimited number of images and uses the grab loop thread provided by the Instant Camera object by setting the second parameter to GrabLoop_ProvidedByInstantCamera. The main thread can now be used to query the user for input to either trigger an image or to exit the input loop. The grabbing is not explicitly stopped in this example and could be stopped by calling StopGrabbing(). The above code snippet can be found in the Grab_UsingGrabLoopThread code sample.
For convenience, the GrabOne() method can be used to grab a single image. The following code shows a simplified version of what is done:
//grab one imageStartGrabbing(1,GrabStrategy_OneByOne,GrabLoop_ProvidedByUser);//grab is stopped automatically due to maxImages = 1returnRetrieveResult(timeoutMs,grabResult,timeoutHandling)&&grabResult->GrabSucceeded();
Note
Using GrabOne() is more efficient if the pylon Device is already open, otherwise the pylon Device is opened and closed automatically for each call. Grabbing single images using Software Trigger (CSoftwareTriggerConfiguration) is recommended if you want to maximize the frame rate. This is because the overhead per grabbed image is reduced compared to Single Frame Acquisition. The grabbing can be started using StartGrabbing(). Images are grabbed using the WaitForFrameTriggerReady(),ExecuteSoftwareTrigger() and RetrieveResult() methods instead of using GrabOne(). The grabbing can be stopped using StopGrabbing() when done.
Basler GigE Vision and USB3 Vision cameras can send event messages. For example, when a sensor exposure has finished, the camera can send an Exposure End event to the computer. Events can be received by registering an image event handler at an Instant Camera class. See the Handling Camera Events section for more information.
Basler Cameras are able to send additional information as so-called data chunks appended to the image data, such as frame counters, time stamps, or CRC checksums. Data chunks are automatically parsed by the Instant Camera class if activated. See the Accessing Chunk Features section for more information.
GigE Multicast/Broadcast: Grab Images of One Camera on Multiple Computers#
Basler GigE cameras can be configured to send the image data stream to multiple destinations. Either IP multicasts or IP broadcasts can be used. For more information consult the Grab Images of One Camera on Multiple Computers section.
Besides the Instant Camera classes used for grabbing images pylon offers additional Image Handling Support support for handling grabbed images. There are an image class, Windows bitmap image support, an image format converter, an image window, and the loading and saving of images.
When working with image data the handling of buffer size and lifetime often involves a lot of coding. The Pylon::CPylonImage class simplifies this. It also allows to attach a buffer of a grab result preventing its reuse as long as required. Additionally, user buffers or buffers provided by third party software packages can be connected. Besides that, the pylon Image class helps when working with image planes or AOIs. The Utility_Image code sample shows the use of the pylon Image class.
The Pylon::CPylonBitmapImage class simplifies the creation of Windows bitmap images for displaying image data. The Utility_Image code sample shows the use of the pylon Bitmap Image class.
The Pylon::CImageFormatConverter creates new images by converting a source image to a different format. Once the format converter is configured, it can convert almost all image formats supported by Basler camera devices. If you want to use multiple threads to speed up the conversion, specify the desired number of threads via the Pylon::CImageFormatConverter::MaxNumThreads parameter. The Utility_ImageFormatConverter code sample shows the use of the Image Format Converter class.
The Pylon::CAviWriter can be used to create video files in the Audio Video Interleave (AVI) format. The Utility_GrabAvi code sample shows the use of the AVI Writer class.
The Pylon::CVideoWriter can be used to create video files in the MP4 format. The Utility_GrabVideo code sample shows the use of the Video Writer class.
The Pylon::CImagePersistence class supports loading and saving images to disk. The pylon Image classes use this interface internally and provide methods for loading and saving. The Utility_ImageLoadAndSave code sample shows how to load and save images.
The pylon Image Window allows you to easily display images on the screen using the DisplayImage or the CPylonImageWindow class. You can use the CPylonImageWindow class to inspect the image retrieved from the camera or the results of CPixelFormatConverter.
pylon Image Window
Every pylon image window is addressed by a unique image window index. Valid image window indexes range from 0 to 31.
The DisplayImage() global function provides the easiest way to display an image on the screen. You need to specify the image window index of the image window that will be used for image display and pass the image or grab result. This will create the window if neccessary, set the contents, and display the window on the screen. The image window will create a copy of the image in memory so you can free the image or grab result safely after the function returns.
To clear the window and release the memory needed for the image you can display an empty image.
When the user closes the image window using the mouse or by pressing Alt+F4 the image window will only be hidden. You can call CPylonImageWindow::Show() to make it visible again.
To actually destroy the window, you must call CPylonImageWindow::Close() . If you don't close the window yourself pylon will close all existing image windows when PylonTerminate is called.