mvIMPACT Acquire SDK C++
ContinuousCaptureAllFormats.cpp

The ContinuousCaptureAllFormats program is based on the ContinuousCapture.cpp example. It however will show the captured images in all pixel formats supported by mvIMPACT Acquire. Each format will be displayed in a raw and a user friendly way on 2 separate display windows. The raw display will simply blit the raw memory on the canvas which e.g. for YUV will not result in something that should be presented to a user. The converted window however proofs that the display module of mvIMPACT Acquire can deal with every pixel format.

Note
This example will be available on Windows only.
Program location
The source file ContinuousCaptureAllFormats.cpp can be found under:
%INSTALLDIR%\apps\ContinuousCaptureAllFormats\
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.
ContinuousCaptureAllFormats example:
  1. Opens a MATRIX VISION device.
  2. Snaps images with all available pixel formats (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.
Initialising the device. This might take some time...
Please note that only the window displaying the converted image will display correct
images all the time. The other window will simply blit the raw image data in the client
area. This is faster but e.g. for 12 bit mono data or YUV data will result in unexpected
results. For planar formats e.g. just the first plane might be visible.
For certain other formats the unconverted window might even blit no data at all.

This e.g. will be the case for 10-16 bit RGB packed data.
The following formats are available:
[0]:  Auto
[1]:  Raw
[2]:  Mono8
[6]:  Mono10
[7]:  Mono12
[28]: Mono12Packed_V1
[19]: Mono12Packed_V2
[8]:  Mono14
[9]:  Mono16
[22]: BGR888Packed
[23]: BGR101010Packed_V2
[10]: RGB888Packed
[14]: RGB101010Packed
[15]: RGB121212Packed
[16]: RGB141414Packed
[17]: RGB161616Packed
[3]:  RGBx888Packed
[30]: RGB888Planar
[5]:  RGBx888Planar
[29]: YUV411_UYYVYY_Packed
[4]:  YUV422Packed
[18]: YUV422_UYVYPacked
[20]: YUV422_10Packed
[21]: YUV422_UYVY_10Packed
[24]: YUV444_UYVPacked
[25]: YUV444_UYV_10Packed
[26]: YUV444Packed
[27]: YUV444_10Packed
[13]: YUV422Planar
Currently using Auto. Press [ENTER] to switch to the next format
Info from BF000306: FramesPerSecond: 28.655655, ErrorCount: 0, CaptureTime_s: 0.103982, OK
Info from BF000306: FramesPerSecond: 28.655673, ErrorCount: 0, CaptureTime_s: 0.103329, OK
How it works

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

However the general stuff (selection of a device etc.) is similar to the SingleCapture.cpp source example. The sample initializes two display windows for the raw and the converted data when creating an instance of the ThreadParameter structure:

ThreadParameter threadParam( pDev, windowTitle );

The thread callback as shown in the ContinuousCapture.cpp example updates the displays and after pressing any key the next pixel format will be shown:

// raw (this might not always display a correct image but is fast and for certain applications the raw data will be the data to process
// IMPORTANT: In this example this display does indirectly store a raw pointer to request data right in the next line! When using the 'RequestProvider' class this
// is NOT allowed. Only because the other display does store the shared_ptr<Request> this can be done here!
threadParameter.dispRaw_.GetImageDisplay().SetImage( pRequest->imageData.read(), pRequest->imageWidth.read(), pRequest->imageHeight.read(), pRequest->imagePixelPitch.read() * 8, pRequest->imageLinePitch.read() );
threadParameter.dispRaw_.GetImageDisplay().Update();
// converted. This might be slower as conversions might be needed but will display a correct image (that is not necessarily the data
// transferred from the device) e.g. 12 bit mono data can't be displayed directly
threadParameter.dispConverted_.GetImageDisplay().SetImage( pRequest );
threadParameter.dispConverted_.GetImageDisplay().Update();

After the last pixel format the application stops after a last click on any key.

All pixel formats that are supported by mvIMPACT Acquire will be processed and display. To find out which pixel formats are supported refer to mvIMPACT::acquire::TImageBufferPixelFormat.

Source code
#include <functional>
#include <iostream>
#include <apps/Common/exampleHelper.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_helper.h>
#include <mvDisplay/Include/mvIMPACT_acquire_display.h>
using namespace std;
using namespace mvIMPACT::acquire;
//-----------------------------------------------------------------------------
struct ThreadParameter
//-----------------------------------------------------------------------------
{
Device* pDev_;
unsigned int requestsCaptured_;
Statistics statistics_;
ImageDisplayWindow dispConverted_;
explicit ThreadParameter( Device* pDev, const string& windowTitle ) : pDev_( pDev ), requestsCaptured_( 0 ), statistics_( pDev ), dispRaw_( windowTitle ), dispConverted_( windowTitle + "(converted)" ) {}
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() )
{
// raw (this might not always display a correct image but is fast and for certain applications the raw data will be the data to process
// IMPORTANT: In this example this display does indirectly store a raw pointer to request data right in the next line! When using the 'RequestProvider' class this
// is NOT allowed. Only because the other display does store the shared_ptr<Request> this can be done here!
threadParameter.dispRaw_.GetImageDisplay().SetImage( pRequest->imageData.read(), pRequest->imageWidth.read(), pRequest->imageHeight.read(), pRequest->imagePixelPitch.read() * 8, pRequest->imageLinePitch.read() );
threadParameter.dispRaw_.GetImageDisplay().Update();
// converted. This might be slower as conversions might be needed but will display a correct image (that is not necessarily the data
// transferred from the device) e.g. 12 bit mono data can't be displayed directly
threadParameter.dispConverted_.GetImageDisplay().SetImage( pRequest );
threadParameter.dispConverted_.GetImageDisplay().Update();
}
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 device " << pDev->serial.read()
<< "(error code: " << e.getErrorCodeAsString() << ")." << endl
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 1;
}
cout << "Please note that only the window displaying the converted image will display correct" << endl
<< "images all the time. The other window will simply blit the raw image data in the client" << endl
<< "area. This is faster but e.g. for 12 bit mono data or YUV data will result in unexpected" << endl
<< "results. For planar formats e.g. just the first plane might be visible." << endl
<< "For certain other formats the unconverted window might even blit no data at all." << endl
<< "This e.g. will be the case for 10-16 bit RGB packed data." << endl;
ImageDestination id( pDev );
cout << "The following formats are available:" << endl;
DisplayPropertyDictionary<PropertyIImageDestinationPixelFormat>( id.pixelFormat );
helper::RequestProvider requestProvider( pDev );
vector<pair<string, TImageDestinationPixelFormat>> validDestinationPixelFormats;
id.pixelFormat.getTranslationDict( validDestinationPixelFormats );
for( const auto validDestinationPixelFormat : validDestinationPixelFormats )
{
id.pixelFormat.write( validDestinationPixelFormat.second );
// initialise display windows
// IMPORTANT: It's NOT safe to create multiple display windows in multiple threads!!!
const string windowTitle( "Device " + pDev->serial.read() + "(pixel format " + validDestinationPixelFormat.first + ")" );
cout << "Currently using " << validDestinationPixelFormat.first << ". Press [ENTER] to switch to the next format" << endl;
ThreadParameter threadParam( pDev, windowTitle );
requestProvider.acquisitionStart( myThreadCallback, std::ref( threadParam ) );
cin.get();
requestProvider.acquisitionStop();
}
cout << "Press [ENTER] to end the application" << endl;
cin.get();
return 0;
}
std::string name(void) const
Returns the name of the component referenced by this object.
Definition: mvIMPACT_acquire.h:1089
Grants access to devices that can be operated by this software interface.
Definition: mvIMPACT_acquire.h:6964
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
Properties to define the format of resulting images.
Definition: mvIMPACT_acquire.h:12035
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
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 basic statistical information.
Definition: mvIMPACT_acquire.h:14159
PropertyF framesPerSecond
A float property (read-only) containing the current number of frames captured per second.
Definition: mvIMPACT_acquire.h:14226
PropertyF captureTime_s
A float property (read-only) containing the overall time an image request spent in the device drivers...
Definition: mvIMPACT_acquire.h:14210
PropertyI errorCount
An integer property (read-only) containing the overall count of image requests which returned with an...
Definition: mvIMPACT_acquire.h:14218
A class that can be used to display images in a window.
Definition: mvIMPACT_acquire_display.h:582
A helper class that can be used to implement a simple continuous acquisition from a device.
Definition: mvIMPACT_acquire_helper.h:429
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