Impact Acquire SDK C++
ContinuousCapture.cpp

The ContinuousCapture program is a simple example for a continuous acquisition.

Note
On Linux this example can only be built when using CMake with C++11 compliant compiler (e.g. gcc 5.0 or greater).
Program location
The source file ContinuousCapture.cpp can be found under:
%INSTALLDIR%\apps\ContinuousCapture\
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.
ContinuousCapture example:
  1. Opens a Balluff device.
  2. Snaps images continuously (without display using Linux).
Console Output
[0]: BF000306 (mvBlueFOX-202C, Family: mvBlueFOX, interface layout: DeviceSpecific)

Please enter the number in front of the listed device followed by [ENTER] to open it: 0
Using device number 0.
Press [ENTER] to end the application
Initialising the device. This might take some time...
Info from BF000306: FramesPerSecond: 28.655660, ErrorCount: 0, CaptureTime_s: 0.104195
Info from BF000306: FramesPerSecond: 28.655636, ErrorCount: 0, CaptureTime_s: 0.104017
Info from BF000306: FramesPerSecond: 28.655659, ErrorCount: 0, CaptureTime_s: 0.104153
Info from BF000306: FramesPerSecond: 28.655636, ErrorCount: 0, CaptureTime_s: 0.104072
Info from BF000306: FramesPerSecond: 28.655660, ErrorCount: 0, CaptureTime_s: 0.104234
How it works

The continuous acquisition is similar to the single capture. The only major difference is, that this sample starts a separate thread that continuously requests images from the device.

However the general stuff (selection of a device etc.) is similar to the SingleCapture.cpp source example.

First of all the user is prompted to select the device he wants to use for this sample:

DeviceManager devMgr;
Device* pDev = getDeviceFromUserInput( devMgr );

The function getDeviceFromUserInput() is included via

#include <apps/Common/exampleHelper.h>

Then after the device has been initialized successfully a continuous acquisition is started using the mvIMPACT::acquire::helper::RequestProvider class:

helper::RequestProvider requestProvider( pDev );
requestProvider.acquisitionStart( myThreadCallback, std::ref( threadParam ) );

The function myThreadCallback will be called for each mvIMPACT::acquire::Request object becoming ready. An application can define an arbitrary function with arbitrary parameters for this operation. The first parameter however always has to be std::shared_ptr<mvIMPACT::acquire::Request>.

In this example the thread callback looks like this:

//-----------------------------------------------------------------------------
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;
}
}

Accessing the mvIMPACT::acquire::Request object can be done after it has been checked using the mvIMPACT::acquire::Request::isOK function. The image attached to the request can then be processed and/or displayed if the request does not report an error.

if( pRequest->isOK() )
{
// all good! Access the data!
}
else
{
cout << "Error: " << pRequest->requestResult.readS() << endl;
}
Source code
//
// @description: Example applications for Impact Acquire
// @copyright: Copyright (C) 2005 - 2024 Balluff GmbH
// @authors: APIs and drivers development team at Balluff GmbH
// @initial date: 2005-03-15
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,i
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#include <apps/Common/exampleHelper.h>
#include <functional>
#include <iostream>
#include <mvIMPACT_CPP/mvIMPACT_acquire_helper.h>
#ifdef _WIN32
# include <mvDisplay/Include/mvIMPACT_acquire_display.h>
# define USE_DISPLAY
#endif // #ifdef _WIN32
using namespace mvIMPACT::acquire;
using namespace std;
//=============================================================================
//================= Data type definitions =====================================
//=============================================================================
//-----------------------------------------------------------------------------
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
{
#ifdef USE_DISPLAY
cout << "Please note that there will be just one refresh for the display window, so if it is" << endl
<< "hidden under another window the result will not be visible." << endl;
#endif // #ifdef USE_DISPLAY
}
ThreadParameter( const ThreadParameter& src ) = delete;
ThreadParameter& operator=( const ThreadParameter& rhs ) = delete;
};
//=============================================================================
//================= implementation ============================================
//=============================================================================
//-----------------------------------------------------------------------------
void displayImageProcessingResults( Component it )
//-----------------------------------------------------------------------------
{
ostringstream data;
while( it.isValid() )
{
if( it.isVisible() && it.isProp() )
{
const TImageProcessingResult ipr = prop.read();
switch( ipr )
{
case iprApplied:
case iprFailure:
if( !data.str().empty() )
{
data << " -> ";
}
data << prop.name();
if( ipr == iprFailure )
{
data << "(FAILED)";
}
break;
default:
break;
}
}
++it;
}
if( !data.str().empty() )
{
cout << "Image Processing Applied: " << data.str() << endl;
}
}
//-----------------------------------------------------------------------------
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() )
{
const TPayloadType payloadType( pRequest->payloadType.read() );
const ImageBuffer* pImageBuffer = ( payloadType == pt2DImage ) ? pRequest->getImageBufferDesc().getBuffer() : handleAdvancedPayloadType( pRequest.get(), payloadType );
if( pImageBuffer )
{
#ifdef USE_DISPLAY
// everything went well. Display the result
threadParameter.displayWindow_.GetImageDisplay().SetImage( pImageBuffer );
threadParameter.displayWindow_.GetImageDisplay().Update();
#else
cout << "Image captured (" << pRequest->imagePixelFormat.readS() << ", " << pImageBuffer->iWidth << "x" << pImageBuffer->iHeight << ")" << endl;
#endif // USE_DISPLAY
}
if( threadParameter.requestsCaptured_ % 100 == 0 )
{
displayImageProcessingResults( pRequest->getImageProcessingResultsIterator() );
}
}
else
{
cout << "Error: " << pRequest->requestResult.readS() << endl;
}
}
//-----------------------------------------------------------------------------
int main( void )
//-----------------------------------------------------------------------------
{
DeviceManager devMgr;
Device* pDev = getDeviceFromUserInput( devMgr );
if( pDev == nullptr )
{
cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
cout << "Initialising the device. This might take some time..." << endl;
try
{
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 the device " << pDev->serial.read()
<< "(error code: " << e.getErrorCodeAsString() << ").";
return 1;
}
ThreadParameter threadParam( pDev );
helper::RequestProvider requestProvider( pDev );
cout << "Press [ENTER] to stop the acquisition thread" << endl;
requestProvider.acquisitionStart( myThreadCallback, std::ref( threadParam ) );
cin.get();
requestProvider.acquisitionStop();
return 0;
}
std::string name(void) const
Returns the name of the component referenced by this object.
Definition mvIMPACT_acquire.h:1206
A base class to implement access to internal driver components.
Definition mvIMPACT_acquire.h:1439
bool isValid(void) const
Checks if the internal component referenced by this object is still valid.
Definition mvIMPACT_acquire.h:1721
bool isProp(void) const
Checks if this component is of type mvIMPACT::acquire::Property or a derived type.
Definition mvIMPACT_acquire.h:1706
bool isVisible(void) const
Checks if the component is currently shadowed due to a settings made elsewhere or not.
Definition mvIMPACT_acquire.h:1745
Grants access to devices that can be operated by this software interface.
Definition mvIMPACT_acquire.h:7171
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition mvIMPACT_acquire.h:6551
void open(void)
Opens a device.
Definition mvIMPACT_acquire.h:6420
A template class to represent 32 bit integer properties and 32 bit enumerated integer properties.
Definition mvIMPACT_acquire.h:4067
A base class for exceptions generated by Impact Acquire.
Definition mvIMPACT_acquire.h:256
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition mvIMPACT_acquire.h:288
std::string read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:5323
std::string readS(int index=0, const std::string &format="") const
Reads data from this property as a string.
Definition mvIMPACT_acquire.h:3340
Contains basic statistical information.
Definition mvIMPACT_acquire.h:14509
PropertyF framesPerSecond
A float property (read-only) containing the current number of frames captured per second.
Definition mvIMPACT_acquire.h:14586
PropertyF captureTime_s
A float property (read-only) containing the overall time an image request spent in the device drivers...
Definition mvIMPACT_acquire.h:14560
PropertyI errorCount
An integer property (read-only) containing the overall count of image requests which returned with an...
Definition mvIMPACT_acquire.h:14568
A class that can be used to display images in a window.
Definition mvIMPACT_acquire_display.h:606
A helper class that can be used to implement a simple continuous acquisition from a device.
Definition mvIMPACT_acquire_helper.h:432
int iHeight
The height of the image in pixel or lines.
Definition mvImageBuffer.h:98
int iWidth
The width of the image in pixel.
Definition mvImageBuffer.h:100
TPayloadType
Defines supported payload types.
Definition mvDriverBaseEnums.h:4311
TImageProcessingResult
Defines valid values for the result of a certain image processing algorithm applied to a request.
Definition mvDriverBaseEnums.h:3838
@ pt2DImage
Color or monochrome (2D) image.
Definition mvDriverBaseEnums.h:4329
Fully describes a captured image.
Definition mvImageBuffer.h:94
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.
Definition mvCommonDataTypes.h:34