The example will list all available devices first. After selecting a device, the pixel formats supported by the display are listed for selection. If a device doesn't transmit the desired format the driver's internal format converter will generate the appropriate format. This consumes some time and should be avoided in a real world application if possible. After selecting a format to use, the image acquisition will start and display the output within a OpenGL supported window. To end the application the display window must be closed.
To display images, a window is created and set to the current OpenGL context.
One texture object is also needed and at least one pixel buffer object. The pixel buffers are now supplied as user managed memory to the image requests.
After receiving a request with an acquired image, the pixel buffer is bound to the texture object. This texture can now be displayed by assigning it to a 2D canvas, that uses the whole window area.
#include <iostream>
#include <memory>
#include <apps/Common/exampleHelper.h>
#include <common/minmax.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_GenICam.h>
#include <apps/CaptureToOpenGLMemory/OpenGLDisplay.h>
#include <chrono>
using namespace std;
static bool s_boTerminated = false;
class UserSuppliedHeapBuffer
{
char* pBuf_;
unique_ptr<PixelBuffer> pPB_;
unsigned int bufSize_;
public:
explicit UserSuppliedHeapBuffer( int bufSize ) : pBuf_( nullptr ), bufSize_( bufSize )
{
if( bufSize_ > 0 )
{
pPB_ = unique_ptr<PixelBuffer>( new PixelBuffer( bufSize_ ) );
pBuf_ = reinterpret_cast<char*>( pPB_->Map() );
}
}
~UserSuppliedHeapBuffer()
{
if( pPB_ )
{
pPB_->Unmap();
}
}
char* getPtr( void )
{
return pBuf_;
}
int getSize( void ) const
{
return bufSize_;
}
char* reallocate( void )
{
pBuf_ = reinterpret_cast<char*>( pPB_->Map() );
return getPtr();
}
PixelBuffer* getBuffer( void ) const
{
return pPB_.get();
}
};
using CaptureBufferContainer = std::vector<shared_ptr<UserSuppliedHeapBuffer>>;
struct CaptureParameter
{
int bufferSize;
int bufferAlignment;
int bufferPitch;
CaptureBufferContainer buffers;
GLenum bufferDataFormat;
GLenum outputImageFormat;
unique_ptr<OGLDisplayWindow> pDisplay;
Texture* pTex;
explicit CaptureParameter(
Device* p ) : pDev{ p }, fi{ p }, irc{ p }, statistics{ p },
bufferSize{ 0 }, bufferAlignment{ 0 }, bufferPitch{ 0 }, bufferDataFormat( GL_BGRA ), outputImageFormat( GL_RGBA ), pDisplay{ nullptr }, pTex{ nullptr }
{}
{
switch( imageBufferPixelFormat )
{
bufferDataFormat = GL_BGRA;
outputImageFormat = GL_RGBA;
break;
bufferDataFormat = GL_RED;
outputImageFormat = GL_LUMINANCE8;
break;
bufferDataFormat = GL_BGR;
outputImageFormat = GL_RGB;
break;
default:
std::cout << "Unsupported imageBufferPixelFormat used in function " << __FUNCTION__ << ". Going to exit now!" << std::endl;
exit( 42 );
}
}
};
int createCaptureBuffer(
FunctionInterface& fi, CaptureBufferContainer& buffers,
const int bufferSize,
const int bufferAlignment,
const int bufferPitch,
unsigned int requestNr );
int createCaptureBuffers(
FunctionInterface& fi, CaptureBufferContainer& buffers,
const int bufferSize,
const int bufferAlignment,
const int bufferPitch );
void freeCaptureBuffer(
FunctionInterface& fi, CaptureBufferContainer& buffers,
unsigned int requestNr );
void runLiveLoop( CaptureParameter& captureParams );
int createCaptureBuffer(
FunctionInterface& fi, CaptureBufferContainer& buffers,
const int bufferSize,
const int ,
unsigned int requestNr )
{
shared_ptr<UserSuppliedHeapBuffer> pBuffer = make_shared<UserSuppliedHeapBuffer>( bufferSize );
if( ( functionResult = pRequest->
attachUserBuffer( pBuffer->getPtr(), pBuffer->getSize() ) ) != DMR_NO_ERROR )
{
cout << "An error occurred while attaching a buffer to request number " << requestNr << ": " << ImpactAcquireException::getErrorCodeAsString( functionResult ) << "." << endl;
return -1;
}
buffers.push_back( pBuffer );
return 0;
}
int createCaptureBuffers(
FunctionInterface& fi, CaptureBufferContainer& buffers,
const int bufferSize,
const int bufferPitch )
{
freeCaptureBuffers( fi, buffers );
for( unsigned int i = 0; i < requestCnt; i++ )
{
try
{
const int result = createCaptureBuffer( fi, buffers, bufferSize, bufferPitch, i );
if( result != 0 )
{
freeCaptureBuffers( fi, buffers );
return result;
}
}
{
freeCaptureBuffers( fi, buffers );
}
}
return 0;
}
void freeCaptureBuffer(
FunctionInterface& fi, CaptureBufferContainer& buffers,
unsigned int requestNr )
{
try
{
{
{
cout << "An error occurred while detaching a buffer from request number " << requestNr << " : " << ImpactAcquireException::getErrorCodeAsString( functionResult ) << "." << endl;
}
}
CaptureBufferContainer::iterator it = find_if( buffers.begin(), buffers.end(), [pAddr]( const shared_ptr<UserSuppliedHeapBuffer>& buffer )
{
return pAddr == buffer->getPtr();
} );
if( it != buffers.end() )
{
buffers.erase( it );
}
}
{
cout <<
"An error occurred while changing the mode of request number " << requestNr <<
": " << e.
getErrorCodeAsString() <<
"." << endl;
}
}
{
for( unsigned int i = 0; i < requestCnt; i++ )
{
freeCaptureBuffer( fi, buffers, i );
}
if( !buffers.empty() )
{
cout << "Error! The buffer container should be empty now but still contains " << buffers.size() << " elements!" << endl;
}
}
void liveLoop( CaptureParameter* pParameter )
{
while( ( result =
static_cast<TDMR_ERROR>( pParameter->fi.imageRequestSingle() ) ) == DMR_NO_ERROR ) {};
if( result != DEV_NO_FREE_REQUEST_AVAILABLE )
{
cout << "'FunctionInterface.imageRequestSingle' returned with an unexpected result: " << result
<< "(" << ImpactAcquireException::getErrorCodeAsString( result ) << ")" << endl;
}
manuallyStartAcquisitionIfNeeded( pParameter->pDev, pParameter->fi );
unsigned int cnt = {0};
const unsigned int timeout_ms = {500};
Request* pPreviousRequest =
nullptr;
CaptureBufferContainer::iterator it;
shared_ptr<UserSuppliedHeapBuffer> previousBuffer;
while( !s_boTerminated )
{
const int requestNr = pParameter->fi.imageRequestWaitFor( timeout_ms );
pRequest = pParameter->fi.isRequestNrValid( requestNr ) ? pParameter->fi.getRequest( requestNr ) : 0;
if( pRequest != nullptr )
{
{
++cnt;
if( cnt % 100 == 0 )
{
cout << "Info from " << pParameter->pDev->serial.read()
<< ": " << pParameter->statistics.framesPerSecond.name() << ": " << pParameter->statistics.framesPerSecond.readS()
<< ", " << pParameter->statistics.errorCount.name() << ": " << pParameter->statistics.errorCount.readS()
<< ", " << pParameter->statistics.captureTime_s.name() << ": " << pParameter->statistics.captureTime_s.readS()
}
it = find_if( pParameter->buffers.begin(), pParameter->buffers.end(), [pAddr]( const shared_ptr<UserSuppliedHeapBuffer>& buffer )
{
return pAddr == buffer->getPtr();
} );
pParameter->pTex->Draw( ( *it )->getBuffer() );
pParameter->pDisplay->WindowUpdate();
}
else
{
}
if( pPreviousRequest != nullptr )
{
{
cout << "Error: Could not detach the buffer from the previous request. Error: " << ImpactAcquireException::getErrorCodeAsString( functionResult ) << "(" << functionResult << ")" << endl;
glfwTerminate();
manuallyStopAcquisitionIfNeeded( pParameter->pDev, pParameter->fi );
return;
}
if( ( functionResult = pPreviousRequest->
attachUserBuffer( previousBuffer->reallocate(), previousBuffer->getSize() ) ) != DMR_NO_ERROR )
{
cout << "Error: Could not attach a new buffer to the previous request. Error: " << ImpactAcquireException::getErrorCodeAsString( functionResult ) << "(" << functionResult << ")" << endl;
glfwTerminate();
manuallyStopAcquisitionIfNeeded( pParameter->pDev, pParameter->fi );
return;
}
}
previousBuffer = *it;
pPreviousRequest = pRequest;
pParameter->fi.imageRequestSingle();
}
if( glfwWindowShouldClose( pParameter->pDisplay->GetContextWindow() ) )
{
s_boTerminated = true;
}
}
glfwTerminate();
manuallyStopAcquisitionIfNeeded( pParameter->pDev, pParameter->fi );
if( pRequest != nullptr )
{
}
pParameter->fi.imageRequestReset( 0, 0 );
}
int main( void )
{
unsigned int mode = 4;
Device* pDev = getDeviceFromUserInput( devMgr );
if( pDev == nullptr )
{
cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
while( mode > 3 )
{
std::cout << "Select Mode:" << std::endl
<< "[0] 32-bit RGB" << std::endl
<< "[1] 24-bit RGB" << std::endl
<< "[2] 8-bit Mono" << std::endl
<< "[3] EXIT the application" << std::endl;
std::cin >> mode;
std::cin.get();
if( mode == 3 )
{
return 0;
}
}
cout << "Initialising the device. This might take some time..." << endl;
try
{
}
{
cout <<
"An error occurred while opening device " << pDev->
serial.
read()
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 1;
}
CaptureParameter captureParams( pDev );
switch( mode )
{
case 0:
id.pixelFormat.write( idpfRGBx888Packed );
captureParams.initPixelFormat( ibpfRGBx888Packed );
break;
case 1:
id.pixelFormat.write( idpfRGB888Packed );
captureParams.initPixelFormat( ibpfRGB888Packed );
break;
case 2:
id.pixelFormat.write( idpfMono8 );
captureParams.initPixelFormat( ibpfMono8 );
break;
}
GLuint width = 640;
GLuint height = 480;
{
std::cout << "GenICam device detected" << std::endl;
if( ifc.width.isValid() && ifc.height.isValid() )
{
width = GLuint( ifc.width.read() );
height = GLuint( ifc.height.read() );
}
else
{
cout << "ERROR: Cannot read width and height from device!" << endl;
return 1;
}
}
else
{
height = csb.aoiHeight.read();
width = csb.aoiWidth.read();
}
std::cout << width << "x" << height << std::endl;
captureParams.pDisplay = unique_ptr<OGLDisplayWindow>( new OGLDisplayWindow( GLuint( width ), GLuint( height ), std::string( "CaptureToOpenGLMemory" ) ) );
if( !captureParams.pDisplay->WindowInit() )
{
std::cerr << "ERROR: OpenGL Window not initialized." << std::endl;
}
glfwSetWindowAspectRatio( captureParams.pDisplay->GetContextWindow(), int( width ), int( height ) );
captureParams.pTex = new Texture( GLuint( width ), GLuint( height ), captureParams.bufferDataFormat, captureParams.outputImageFormat, GL_UNSIGNED_BYTE );
int bufferAlignment = { 0 };
Request* pCurrentCaptureBufferLayout =
nullptr;
int result = captureParams.fi.getCurrentCaptureBufferLayout( captureParams.irc, &pCurrentCaptureBufferLayout, &bufferAlignment );
if( result != 0 )
{
cout << "An error occurred while querying the current capture buffer layout for device " << captureParams.pDev->serial.read()
<< "(error code: " << ImpactAcquireException::getErrorCodeAsString( result ) << ")." << endl
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 1;
}
cout << "Buffer Data: Size " << bufferSize << ", Pitch " << bufferPitch << endl;
result = createCaptureBuffers( captureParams.fi, captureParams.buffers, bufferSize, bufferPitch );
if( result != 0 )
{
cout << "An error occurred while setting up the user supplied buffers for device " << captureParams.pDev->serial.read()
<< "(error code: " << ImpactAcquireException::getErrorCodeAsString( result ) << ")." << endl
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 1;
}
cout << "**************************************************************************************" << endl
<< " Acquisition started. Close the display window to end the application." << endl
<< "**************************************************************************************" << endl << endl;
liveLoop( &captureParams );
return 0;
}
A base class for camera related settings(Device specific interface layout only).
Definition mvIMPACT_acquire.h:18811
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 close(void)
Closes an opened device.
Definition mvIMPACT_acquire.h:6272
void open(void)
Opens a device.
Definition mvIMPACT_acquire.h:6420
PropertyIDeviceInterfaceLayout interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition mvIMPACT_acquire.h:6644
ZYX read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:4300
The function interface to devices supported by this interface.
Definition mvIMPACT_acquire.h:10758
unsigned int requestCount(void) const
Returns the number of available request objects.
Definition mvIMPACT_acquire.h:11927
Request * getRequest(int nr) const
Returns a pointer to the desired mvIMPACT::acquire::Request.
Definition mvIMPACT_acquire.h:11189
Properties to define the format of resulting images.
Definition mvIMPACT_acquire.h:12376
A helper class to control the way an image request will be processed.
Definition mvIMPACT_acquire.h:10360
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
int getErrorCode(void) const
Returns a unique numerical representation for this error.
Definition mvIMPACT_acquire.h:275
void * read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:5176
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 information about a captured buffer.
Definition mvIMPACT_acquire.h:8640
PropertyI imageHeight
An integer property (read-only) containing the height of the image in pixels.
Definition mvIMPACT_acquire.h:10331
bool isOK(void) const
Convenience function to check if a request has been processed successfully.
Definition mvIMPACT_acquire.h:9474
PropertyIRequestResult requestResult
An enumerated integer property (read-only) defining the result of this request.
Definition mvIMPACT_acquire.h:9780
PropertyI imageSize
An integer property (read-only) containing the size (in bytes) of the whole image.
Definition mvIMPACT_acquire.h:10202
PropertyI imageWidth
An integer property (read-only) containing the width of the image in pixels.
Definition mvIMPACT_acquire.h:10320
PropertyIRequestImageMemoryMode imageMemoryMode
An enumerated integer property (read-only) containing the memory mode used for this request.
Definition mvIMPACT_acquire.h:10124
int attachUserBuffer(void *pBuf, int bufSize)
Convenience function to attach a user supplied buffer to a mvIMPACT::acquire::Request object.
Definition mvIMPACT_acquire.h:9665
PropertyIImageBufferPixelFormat imagePixelFormat
An enumerated integer property (read-only) containing the pixel format of this image.
Definition mvIMPACT_acquire.h:10132
PropertyPtr imageData
A pointer property (read-only) containing the start address of the image data.
Definition mvIMPACT_acquire.h:10187
int detachUserBuffer(void)
Convenience function to detach a user supplied buffer from a mvIMPACT::acquire::Request object.
Definition mvIMPACT_acquire.h:9757
int unlock(void)
Unlocks the request for the driver again.
Definition mvIMPACT_acquire.h:9614
PropertyI imageLinePitch
An integer property (read-only) containing the offset (in bytes) to the next line of each channel bel...
Definition mvIMPACT_acquire.h:10262
PropertyI imageFooterSize
An integer property (read-only) containing the size (in bytes) of the footer associated with this ima...
Definition mvIMPACT_acquire.h:10217
Contains basic statistical information.
Definition mvIMPACT_acquire.h:14509
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.h:2601
TImageBufferPixelFormat
Valid image buffer pixel formats.
Definition TImageBufferPixelFormat.h:41
@ DMR_NO_ERROR
The function call was executed successfully.
Definition mvDriverBaseEnums.h:2603
@ ibpfRGB888Packed
A three channel interleaved RGB format containing 24 bit per pixel. (PFNC name: BGR8)
Definition TImageBufferPixelFormat.h:155
@ ibpfMono8
A single channel 8 bit per pixel format. (PFNC name: Mono8)
Definition TImageBufferPixelFormat.h:45
@ ibpfRGBx888Packed
A four channel interleaved RGB format with 32 bit per pixel containing one alpha byte per pixel....
Definition TImageBufferPixelFormat.h:70
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition mvCommonDataTypes.h:34