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.
int main( int argc, char* argv[] )
{
DeviceManager devMgr;
const unsigned int devCnt = devMgr.deviceCount();
if( devCnt == 0 )
{
cout << "No MATRIX VISION device found! Unable to continue!" << endl;
return 1;
}
string productFilter( "*" );
bool boInvalidCommandLineParameterDetected = false;
if( argc > 1 )
{
for( int i = 1; i < argc; i++ )
{
const string param( argv[i] );
const string::size_type keyEnd = param.find_first_of( "=" );
if( ( keyEnd == string::npos ) || ( keyEnd == param.length() - 1 ) )
{
cout << "Invalid command line parameter: '" << param << "' (ignored)." << endl;
boInvalidCommandLineParameterDetected = true;
}
else
{
const string key = param.substr( 0, keyEnd );
const string value = param.substr( keyEnd + 1 );
if( ( key == "product" ) || ( key == "p" ) )
{
productFilter = value;
}
else
{
cout << "Invalid command line parameter: '" << param << "' (ignored)." << endl;
boInvalidCommandLineParameterDetected = true;
}
}
}
if( boInvalidCommandLineParameterDetected )
{
displayCommandLineOptions();
}
}
else
{
cout << "No command line parameters specified." << endl;
displayCommandLineOptions();
}
map<shared_ptr<ThreadParameter>, shared_ptr<thread>> threads;
for( unsigned int i = 0; i < devCnt; i++ )
{
if( match( devMgr[i]->product.read(), productFilter, '*' ) == 0 )
{
shared_ptr<ThreadParameter> pParameter = make_shared<ThreadParameter>( devMgr[i] );
#ifdef USE_DISPLAY
pParameter->createDisplayWindow( "mvIMPACT_acquire sample, Device " + devMgr[i]->serial.read() );
#endif
threads[pParameter] = make_shared<thread>( liveThread, pParameter );
lock_guard<mutex> lockedScope( s_mutex );
cout << devMgr[i]->family.read() << "(" << devMgr[i]->serial.read() << ")" << endl;
}
}
if( threads.empty() )
{
cout << "No MATRIX VISION device found that matches the product filter '" << productFilter << "'! Unable to continue!" << endl;
return 1;
}
{
lock_guard<mutex> lockedScope( s_mutex );
cout << "Press [ENTER] to end the acquisition( the initialisation of the devices might take some time )" << endl;
}
if( getchar() == EOF )
{
lock_guard<mutex> lockedScope( s_mutex );
cout << "'getchar()' did return EOF..." << endl;
}
{
lock_guard<mutex> lockedScope( s_mutex );
cout << "Terminating live threads..." << endl;
}
s_boRunning = false;
for( auto& it : threads )
{
it.second->join();
}
return 0;
}
Then after the device has been initialised successfully image requests will constantly be sent to the drivers request queue and the application waits for the results:
The image attached to the request can then be processed and/or displayed if the request does not report an error.
When the image is no longer needed you have to unlock the image buffer as otherwise the driver will refuse to use it again. This makes sure, that no image, that is still used by the user will be overwritten by the device:
#include <iostream>
#include <map>
#include <memory>
#include <mutex>
#include <thread>
#include <apps/Common/exampleHelper.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#ifdef _WIN32
# define USE_DISPLAY
# include <mvDisplay/Include/mvIMPACT_acquire_display.h>
#endif
using namespace std;
static mutex s_mutex;
static bool s_boTerminated = false;
class ThreadParameter
{
#ifdef USE_DISPLAY
unique_ptr<ImageDisplayWindow> pDisplayWindow_;
#endif
public:
explicit ThreadParameter(
Device* pDev ) : pDev_( pDev ) {}
ThreadParameter( const ThreadParameter& src ) = delete;
{
return pDev_;
}
#ifdef USE_DISPLAY
void createDisplayWindow( const string& windowTitle )
{
pDisplayWindow_ = unique_ptr<ImageDisplayWindow>(
new ImageDisplayWindow( windowTitle ) );
}
{
return *pDisplayWindow_;
}
#endif
};
void displayCommandLineOptions( void )
{
cout << "Available parameters:" << endl
<< " 'product' or 'p' to specify a certain product type. All other products will be ignored then" << endl
<< " a '*' serves as a wildcard." << endl
<< endl
<< "USAGE EXAMPLE:" << endl
<< " ContinuousCaptureAllDevices p=mvBlue* " << endl << endl;
}
void writeToStdout( const string& msg )
{
lock_guard<mutex> lockedScope( s_mutex );
cout << msg << endl;
}
void liveThread( shared_ptr<ThreadParameter> parameter )
{
Device* pDev = parameter->device();
writeToStdout(
"Trying to open " + pDev->
serial.
read() );
try
{
}
{
lock_guard<mutex> lockedScope( s_mutex );
cout <<
"An error occurred while opening the device " << pDev->
serial.
read()
<< "Press [ENTER] to end the application..."
<< endl;
return;
}
while( ( result =
static_cast<TDMR_ERROR>( fi.imageRequestSingle() ) ) == DMR_NO_ERROR ) {};
if( result != DEV_NO_FREE_REQUEST_AVAILABLE )
{
lock_guard<mutex> lockedScope( s_mutex );
cout << "'FunctionInterface.imageRequestSingle' returned with an unexpected result: " << result
<< "(" << ImpactAcquireException::getErrorCodeAsString( result ) << ")" << endl;
}
manuallyStartAcquisitionIfNeeded( pDev, fi );
const unsigned int timeout_ms = {500};
unsigned int cnt = {0};
while( !s_boTerminated )
{
requestNr = fi.imageRequestWaitFor( timeout_ms );
if( fi.isRequestNrValid( requestNr ) )
{
pRequest = fi.getRequest( requestNr );
{
++cnt;
if( cnt % 100 == 0 )
{
lock_guard<mutex> lockedScope( s_mutex );
<< ": " << statistics.framesPerSecond.name() << ": " << statistics.framesPerSecond.readS()
<< ": " << statistics.bandwidthConsumed.name() << ": " << statistics.bandwidthConsumed.readS()
<< ", " << statistics.errorCount.name() << ": " << statistics.errorCount.readS()
<< ", " << statistics.captureTime_s.name() << ": " << statistics.captureTime_s.readS() << endl;
}
#ifdef USE_DISPLAY
ImageDisplay& display = parameter->displayWindow().GetImageDisplay();
#endif
}
else
{
}
if( fi.isRequestNrValid( lastRequestNr ) )
{
fi.imageRequestUnlock( lastRequestNr );
}
lastRequestNr = requestNr;
fi.imageRequestSingle();
}
}
manuallyStopAcquisitionIfNeeded( pDev, fi );
#ifdef USE_DISPLAY
parameter->displayWindow().GetImageDisplay().RemoveImage();
#endif
if( fi.isRequestNrValid( requestNr ) )
{
fi.imageRequestUnlock( requestNr );
}
fi.imageRequestReset( 0, 0 );
}
int main( int argc, char* argv[] )
{
if( devCnt == 0 )
{
cout << "No MATRIX VISION device found! Unable to continue!" << endl;
return 1;
}
string productFilter( "*" );
if( argc > 1 )
{
bool boInvalidCommandLineParameterDetected = false;
for( int i = 1; i < argc; i++ )
{
const string param( argv[i] );
const auto keyEnd = param.find_first_of( "=" );
if( ( keyEnd == string::npos ) || ( keyEnd == param.length() - 1 ) )
{
cout << "Invalid command line parameter: '" << param << "' (ignored)." << endl;
boInvalidCommandLineParameterDetected = true;
}
else
{
const string key( param.substr( 0, keyEnd ) );
if( ( key == "product" ) || ( key == "p" ) )
{
productFilter = param.substr( keyEnd + 1 );
}
else
{
cout << "Invalid command line parameter: '" << param << "' (ignored)." << endl;
boInvalidCommandLineParameterDetected = true;
}
}
}
if( boInvalidCommandLineParameterDetected )
{
displayCommandLineOptions();
}
}
else
{
cout << "No command line parameters specified." << endl;
displayCommandLineOptions();
}
map<shared_ptr<ThreadParameter>, shared_ptr<thread>> threads;
for( unsigned int i = 0; i < devCnt; i++ )
{
if( match( devMgr[i]->product.read(), productFilter, '*' ) == 0 )
{
shared_ptr<ThreadParameter> pParameter = make_shared<ThreadParameter>( devMgr[i] );
#ifdef USE_DISPLAY
pParameter->createDisplayWindow( "mvIMPACT_acquire sample, Device " + devMgr[i]->serial.read() );
#endif
threads[pParameter] = make_shared<thread>( liveThread, pParameter );
writeToStdout( devMgr[i]->family.read() + "(" + devMgr[i]->serial.read() + ")" );
}
}
if( threads.empty() )
{
cout << "No MATRIX VISION device found that matches the product filter '" << productFilter << "'! Unable to continue!" << endl;
return 1;
}
writeToStdout( "Press [ENTER] to end the acquisition( the initialisation of the devices might take some time )" );
if( getchar() == EOF )
{
writeToStdout( "'getchar()' did return EOF..." );
}
writeToStdout( "Terminating live threads..." );
s_boTerminated = true;
for( auto& it : threads )
{
it.second->join();
}
return 0;
}
Grants access to devices that can be operated by this software interface.
Definition: mvIMPACT_acquire.h:6964
unsigned int deviceCount(void) const
Returns the number of devices currently present in the system.
Definition: mvIMPACT_acquire.h:7193
This class and its functions represent an actual device detected by this interface in the current sys...
Definition: mvIMPACT_acquire.h:5948
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition: mvIMPACT_acquire.h:6351
void open(void)
Opens a device.
Definition: mvIMPACT_acquire.h:6238
PropertyIDeviceInterfaceLayout interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition: mvIMPACT_acquire.h:6444
PropertyIAcquisitionStartStopBehaviour acquisitionStartStopBehaviour
An enumerated integer property defining the start/stop behaviour during acquisition of this driver in...
Definition: mvIMPACT_acquire.h:6595
The function interface to devices supported by this interface.
Definition: mvIMPACT_acquire.h:10443
A base class for exceptions generated by mvIMPACT Acquire.
Definition: mvIMPACT_acquire.h:248
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition: mvIMPACT_acquire.h:280
int getErrorCode(void) const
Returns a unique numerical representation for this error.
Definition: mvIMPACT_acquire.h:267
std::string read(int index=0) const
Reads a value from a property.
Definition: mvIMPACT_acquire.h:5159
std::string readS(int index=0, const std::string &format="") const
Reads data from this property as a string.
Definition: mvIMPACT_acquire.h:3213
Contains information about a captured buffer.
Definition: mvIMPACT_acquire.h:8408
bool isOK(void) const
Convenience function to check if a request has been processed successfully.
Definition: mvIMPACT_acquire.h:9197
PropertyIRequestResult requestResult
An enumerated integer property (read-only) defining the result of this request.
Definition: mvIMPACT_acquire.h:9500
Contains basic statistical information.
Definition: mvIMPACT_acquire.h:14159
A class that can be used to display images in a window.
Definition: mvIMPACT_acquire_display.h:582
A class that can be used for displaying images within existing windows or GUI elements that can provi...
Definition: mvIMPACT_acquire_display.h:172
void SetImage(const void *pData, int width, int height, int bitsPerPixel, int pitch)
Sets the next image to display.
Definition: mvIMPACT_acquire_display.h:292
void Update(void) const
Immediately redraws the current image.
Definition: mvIMPACT_acquire_display.h:381
TDMR_ERROR
Errors reported by the device manager.
Definition: mvDriverBaseEnums.h:2260
@ DMR_NO_ERROR
The function call was executed successfully.
Definition: mvDriverBaseEnums.h:2265
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: mvImageBuffer.h:42