mvIMPACT Acquire SDK C++
GenICamInterfaceLayout.cpp

Parts of the GenICamInterfaceLayout program are based on the ContinuousCapture.cpp example concerning the image acquisition. The sample shows all GenICam interface properties which can be modified.

Program location
The source file GenICamInterfaceLayout.cpp can be found under:
%INSTALLDIR%\apps\GenICamInterfaceLayout\
Note
If you have installed the package without example applications, this file will not be available. On Windows the sample application can be installed or removed from the target system at any time by simply restarting the installation package.
GenICamInterfaceLayout example:
  1. Opens a MATRIX VISION device.
  2. Shows some GenICam interface properties.
  3. You can set some properties.
  4. Snaps an image using these properties (without display using Linux).
Console Output
[0]: GX001559 (mvBlueCOUGAR-X122G, Family: mvBlueCOUGAR, interface layout: DeviceSpecific)

Please enter the number in front of the listed device followed by [ENTER] to open it: 0
Using device number 0.
Interface layout of device GX001559(mvBlueCOUGAR-X122G) set to 'GenICam'.

Acquisition start/stop behaviour(Defines the start/stop behaviour of the acquisition engine) of device 
GX001559(mvBlueCOUGAR-X122G) set to 'User'.
In 'Default' mode the acquisition engine will be started and stopped automatically, when set 
to 'User' it is up to the user to start and stop the acquisition engine. When this driver is
running with a 3rd party GenICam GenTL producer only 'User' will be available).

Initialising the device. This might take some time...

Property 'DeviceVendorName' currently specifies the following flags: cfAlwaysForceClone | cfFixedSize | cfReadAccess
The current value of 'DeviceVendorName' is: MATRIX VISION GmbH

Property 'DeviceModelName' currently specifies the following flags: cfAlwaysForceClone | cfFixedSize | cfReadAccess
The current value of 'DeviceModelName' is: mvBlueCOUGAR-X122G

Property 'ExposureTime' currently specifies the following flags: cfAlwaysForceClone | cfFixedSize | cfWriteAccess | cfReadAccess
The minimum value of 'ExposureTime' is 10.000
The maximum value of 'ExposureTime' is 10000000.000
The current value of 'ExposureTime' is: 20000.000
Enter the new value for 'ExposureTime': 20000

Property 'PixelFormat' currently specifies the following flags: cfShouldBeDisplayedAsEnumeration | cfAlwaysForceClone | cfFixedSize | cfWriteAccess | cfReadAcce
ss
'PixelFormat' defines a dictionary. Valid values are:
  [17301505]: Mono8
  [17825799]: Mono16
  [17563654]: Mono12Packed
The current value of 'PixelFormat' is: Mono8
Enter the new value for 'PixelFormat': Mono16

Property 'Width' currently specifies the following flags: cfAlwaysForceClone | cfFixedSize | cfWriteAccess | cfReadAccess
The minimum value of 'Width' is 16
The maximum value of 'Width' is 1280
The increment of 'Width' is 1
The current value of 'Width' is: 1280
Enter the new value for 'Width': 1280

Property 'Height' currently specifies the following flags: cfAlwaysForceClone | cfFixedSize | cfWriteAccess | cfReadAccess
The minimum value of 'Height' is 16
The maximum value of 'Height' is 960
The increment of 'Height' is 1
The current value of 'Height' is: 960
Enter the new value for 'Height': 960

Press [ENTER] to end the application
Info from GX001559: FramesPerSecond: 22.679294, ErrorCount: 0, CaptureTime_s: 0.394700
Info from GX001559: FramesPerSecond: 22.679315, ErrorCount: 0, CaptureTime_s: 0.394691
Info from GX001559: FramesPerSecond: 22.679311, ErrorCount: 0, CaptureTime_s: 0.394728
...
How it works
After getting the device from user input the sample tries to
  1. set the mvIMPACT::acquire::Device::interfaceLayout to mvIMPACT::acquire::dilGenICam
    pDev->interfaceLayout.write( dilGenICam );
    @ dilGenICam
    A GenICamâ„¢ like interface layout shall be used.
    Definition: mvDriverBaseEnums.h:2004
    and to
  2. open the device by calling
    pDev->open();
  3. The sample shows, how to work with SFNC (Standard Feature Naming Convention) using the helper functions from exampleHelper.h.
    I.e. displayPropertyDataWithValidation() shows the mentioned property (after it was checked if it is available). Additional to displayPropertyDataWithValidation() the displayAndModifyPropertyDataWithValidation() function starts a routine, to set the property.
displayPropertyDataWithValidation( dc.deviceVendorName, "DeviceVendorName" );
cout << endl;
displayPropertyDataWithValidation( dc.deviceModelName, "DeviceModelName" );
cout << endl;
// show the current exposure time allow the user to change it
displayAndModifyPropertyDataWithValidation( ac.exposureTime, "ExposureTime" );
// show the current pixel format, width and height and allow the user to change it
displayAndModifyPropertyDataWithValidation( ifc.pixelFormat, "PixelFormat" );
displayAndModifyPropertyDataWithValidation( ifc.width, "Width" );
displayAndModifyPropertyDataWithValidation( ifc.height, "Height" );
Category for the acquisition and trigger control features.
Definition: mvIMPACT_acquire_GenICam.h:2075
Category for device information and control.
Definition: mvIMPACT_acquire_GenICam.h:79
Category for Image Format Control features.
Definition: mvIMPACT_acquire_GenICam.h:1104

Afterwards, the sample shows a live display (mvIMPACT::acquire::display)(Windows only) and you can end the application with [ENTER].

Source code
#include <functional>
#include <iostream>
#include <memory>
#include <apps/Common/exampleHelper.h>
#ifdef _WIN32
# include <conio.h>
# define USE_DISPLAY
#else
# include <stdio.h>
# include <unistd.h>
#endif // #ifdef _WIN32
using namespace std;
using namespace mvIMPACT::acquire;
//-----------------------------------------------------------------------------
struct ThreadParameter
//-----------------------------------------------------------------------------
{
Device* pDev_;
unsigned int requestsCaptured_;
Statistics statistics_;
#ifdef USE_DISPLAY
ImageDisplayWindow displayWindow_;
#endif // #ifdef USE_DISPLAY
explicit ThreadParameter( Device* pDev ) : pDev_( pDev ), requestsCaptured_( 0 ), statistics_( pDev )
#ifdef USE_DISPLAY
// initialise display window
// IMPORTANT: It's NOT safe to create multiple display windows in multiple threads!!!
, displayWindow_( "mvIMPACT_acquire sample, Device " + pDev_->serial.read() )
#endif // #ifdef USE_DISPLAY
{}
ThreadParameter( const ThreadParameter& src ) = delete;
ThreadParameter& operator=( const ThreadParameter& rhs ) = delete;
};
//-----------------------------------------------------------------------------
void myThreadCallback( shared_ptr<Request> pRequest, ThreadParameter& threadParameter )
//-----------------------------------------------------------------------------
{
++threadParameter.requestsCaptured_;
// display some statistical information every 100th image
if( threadParameter.requestsCaptured_ % 100 == 0 )
{
const Statistics& s = threadParameter.statistics_;
cout << "Info from " << threadParameter.pDev_->serial.read()
<< ": " << s.framesPerSecond.name() << ": " << s.framesPerSecond.readS()
<< ", " << s.errorCount.name() << ": " << s.errorCount.readS()
<< ", " << s.captureTime_s.name() << ": " << s.captureTime_s.readS() << endl;
}
if( pRequest->isOK() )
{
#ifdef USE_DISPLAY
threadParameter.displayWindow_.GetImageDisplay().SetImage( pRequest );
threadParameter.displayWindow_.GetImageDisplay().Update();
#else
cout << "Image captured: " << pRequest->imageOffsetX.read() << "x" << pRequest->imageOffsetY.read() << "@" << pRequest->imageWidth.read() << "x" << pRequest->imageHeight.read() << endl;
#endif // #ifdef USE_DISPLAY
}
else
{
cout << "Error: " << pRequest->requestResult.readS() << endl;
}
}
//-----------------------------------------------------------------------------
// This function will allow to select devices that support the GenICam interface
// layout(these are devices, that claim to be compliant with the GenICam standard)
// and that are bound to drivers that support the user controlled start and stop
// of the internal acquisition engine. Other devices will not be listed for
// selection as the code of the example relies on these features in the code.
bool isDeviceSupportedBySample( const Device* const pDev )
//-----------------------------------------------------------------------------
{
if( !pDev->interfaceLayout.isValid() &&
!pDev->acquisitionStartStopBehaviour.isValid() )
{
return false;
}
vector<TDeviceInterfaceLayout> availableInterfaceLayouts;
pDev->interfaceLayout.getTranslationDictValues( availableInterfaceLayouts );
return find( availableInterfaceLayouts.begin(), availableInterfaceLayouts.end(), dilGenICam ) != availableInterfaceLayouts.end();
}
//-----------------------------------------------------------------------------
int main( void )
//-----------------------------------------------------------------------------
{
DeviceManager devMgr;
Device* pDev = getDeviceFromUserInput( devMgr, isDeviceSupportedBySample );
if( pDev == nullptr )
{
cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
try
{
cout << "Initialising the device. This might take some time..." << endl << endl;
pDev->interfaceLayout.write( dilGenICam ); // This is also done 'silently' by the 'getDeviceFromUserInput' function but your application needs to do this as well so state this here clearly!
pDev->open();
}
catch( const ImpactAcquireException& e )
{
// this e.g. might happen if the same device is already opened in another process...
cout << "An error occurred while opening device " << pDev->serial.read()
<< "(error code: " << e.getErrorCodeAsString() << ")." << endl
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 1;
}
try
{
// now display some SFNC(Standard Feature Naming Convention) compliant features(see http://www.emva.org to find out more
// about the standard and to download the latest SFNC document version)
//
// IMPORTANT:
//
// The SFNC unfortunately does NOT define numerical values for enumerations, thus a device independent piece of software
// should use the enum-strings defined in the SFNC to ensure interoperability between devices. This is slightly slower
// but should not cause problems in real world applications. When the device type AND GenICam XML file version is
// guaranteed to be constant for a certain version of software, the driver internal code generator can be used to create
// and interface header, that has numerical constants for enumerations as well. See device driver documentation under
// 'Use Cases -> GenICam to mvIMPACT Acquire code generator' for details.
displayPropertyDataWithValidation( dc.deviceVendorName, "DeviceVendorName" );
cout << endl;
displayPropertyDataWithValidation( dc.deviceModelName, "DeviceModelName" );
cout << endl;
// show the current exposure time allow the user to change it
displayAndModifyPropertyDataWithValidation( ac.exposureTime, "ExposureTime" );
// show the current pixel format, width and height and allow the user to change it
displayAndModifyPropertyDataWithValidation( ifc.pixelFormat, "PixelFormat" );
displayAndModifyPropertyDataWithValidation( ifc.width, "Width" );
displayAndModifyPropertyDataWithValidation( ifc.height, "Height" );
// start the execution of the 'live' thread.
cout << "Press [ENTER] to end the application" << endl;
ThreadParameter threadParam( pDev );
helper::RequestProvider requestProvider( pDev );
requestProvider.acquisitionStart( myThreadCallback, std::ref( threadParam ) );
cin.get();
requestProvider.acquisitionStop();
}
catch( const ImpactAcquireException& e )
{
// this e.g. might happen if the same device is already opened in another process...
cout << "An error occurred while operating the device " << pDev->serial.read()
<< "(error code: " << e.getErrorCodeAsString() << ")." << endl
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 1;
}
return 0;
}
This namespace contains classes and functions that can be used to display images.
This namespace contains classes and functions belonging to the image acquisition module of this SDK.