First of all the user will be prompted to select the device he wants to use for this sample:
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:
Within the capture thread the single images will be added to the AVI file constantly by the following function:
As it can be seen in the code of this function the image must be flipped in order to be stored in the file correctly. This also influence the way images are stored as because of that the current image can't be stored into the stream as certain window messages might cause the image to be redrawn by the display window during or after the flipping, which would produce a unstable live display. Because of that we will store each image AFTER the display has been assigned a new one:
To provide an absolute frame rate, the mvBlueFOX makes a Hardware Real-Time Controller available (HRTC).
shows, how to program a HRTC loop.
#ifdef _MSC_VER
# if _MSC_VER < 1300
# pragma warning( disable : 4786 )
# endif
#endif
#include <windows.h>
#include <process.h>
#include <conio.h>
#include <iostream>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvDisplay/Include/mvIMPACT_acquire_display.h>
#include <apps/Common/exampleHelper.h>
#include <apps/Common/aviwrapper.h>
using namespace std;
static bool s_boTerminated = false;
struct ThreadParameter
{
AVIWrapper* pAVIWrapper;
ThreadParameter(
Device* p, std::string& windowTitle, AVIWrapper* pAVI )
: pDev( p ), displayWindow( windowTitle ), pAVIWrapper( pAVI ) {}
};
void displayCommandLineOptions( void )
{
cout << "Available parameters:" << endl
<< " 'outputFile' or 'of' to specify the name of the resulting AVI file" << endl
<< " 'frameRate' or 'fr' to specify the frame rate(frames per second for playback) of the resulting AVI file" << endl
<< " 'recordingTime' or 'rt' to specify the time in ms the sample shall capture image data. If this parameter" << endl
<< " is omitted, the capture process will be aborted after the user pressed a key" << endl
<< endl
<< "USAGE EXAMPLE:" << endl
<< " ContinuousCaptureToAVIFile rt=5000 of=myfile.avi frameRate=25" << endl << endl;
}
void inplaceHorizontalMirror( void* pData, int height, size_t pitch )
{
int upperHalfOfLines = height / 2;
char* pLowerLine = static_cast<char*>( pData ) + ( ( height - 1 ) * pitch );
char* pUpperLine = static_cast<char*>( pData );
char* pTmpLine = new char[pitch];
for( int y = 0; y < upperHalfOfLines; y++ )
{
memcpy( pTmpLine, pUpperLine, pitch );
memcpy( pUpperLine, pLowerLine, pitch );
memcpy( pLowerLine, pTmpLine, pitch );
pUpperLine += pitch;
pLowerLine -= pitch;
}
delete [] pTmpLine;
}
void setupBlueFOXFrameRate(
Device* pDev,
int frameRate_Hz )
{
cout << "To use the HRTC to configure the mvBlueFOX to capture with a defined frequency press 'y'." << endl;
if( _getch() != 'y' )
{
return;
}
cout << "Trying to capture at " << frameRate_Hz << " frames per second. Please make sure the device can deliver this frame rate" << endl
<< "as otherwise the resulting AVI stream will be replayed with an incorrect speed" << endl;
int frametime_us = static_cast<int>( 1000000.0 * ( 1.0 / static_cast<double>( frameRate_Hz ) ) );
const int TRIGGER_PULSE_WIDTH_us = 100;
if( frametime_us < 2 * TRIGGER_PULSE_WIDTH_us )
{
cout << "frame rate too high (" << frameRate_Hz << "). Using 10 Hz." << endl;
frametime_us = 100000;
}
if( bfs.expose_us.read() > frametime_us / 2 )
{
ostringstream oss;
oss << "Reducing frame-time from " << bfs.expose_us.read() << " us to " << frametime_us / 2 << " us." << endl
<< "Higher values are possible but require a more sophisticated HRTC program" << endl;
bfs.expose_us.write( frametime_us / 2 );
}
bfs.triggerSource.write( ctsRTCtrl );
bfs.triggerMode.write( ctmOnRisingEdge );
if( bfIOs.RTCtrProgramCount() == 0 )
{
cout <<
"This device (" << pDev->
product.
read() <<
") doesn't support HRTC" << endl;
return;
}
if( !pRTCtrlprogram )
{
cout << "Error! No valid program. Short of memory?" << endl;
return;
}
int progStep = 0;
pRTCtrlStep = pRTCtrlprogram->
programStep( progStep++ );
pRTCtrlStep->
clocks_us.
write( frametime_us - TRIGGER_PULSE_WIDTH_us );
pRTCtrlStep = pRTCtrlprogram->
programStep( progStep++ );
pRTCtrlStep = pRTCtrlprogram->
programStep( progStep++ );
pRTCtrlStep = pRTCtrlprogram->
programStep( progStep++ );
pRTCtrlStep = pRTCtrlprogram->
programStep( progStep++ );
}
void storeImageToStream(
FunctionInterface& fi,
int requestNr, AVIWrapper* pAVIWrapper )
{
{
{
try
{
}
catch( const AVIException& e )
{
cout << "Could not store image to stream(" << string( e.what() ) << ")" << endl;
}
}
}
}
unsigned int __stdcall liveThread( void* pData )
{
ThreadParameter* pThreadParameter = reinterpret_cast<ThreadParameter*>( pData );
ImageDisplay& display = pThreadParameter->displayWindow.GetImageDisplay();
if( result != DEV_NO_FREE_REQUEST_AVAILABLE )
{
cout << "'FunctionInterface.imageRequestSingle' returned with an unexpected result: " << result
<< "(" << ImpactAcquireException::getErrorCodeAsString( result ) << ")" << endl;
}
manuallyStartAcquisitionIfNeeded( pThreadParameter->pDev, fi );
const unsigned int timeout_ms = 500;
while( !s_boTerminated )
{
{
{
}
else
{
}
storeImageToStream( fi, lastRequestNr, pThreadParameter->pAVIWrapper );
{
}
lastRequestNr = requestNr;
}
}
manuallyStopAcquisitionIfNeeded( pThreadParameter->pDev, fi );
storeImageToStream( fi, requestNr, pThreadParameter->pAVIWrapper );
{
}
return 0;
}
int main( int argc, char* argv[] )
{
Device* pDev = getDeviceFromUserInput( devMgr );
if( !pDev )
{
cout << "Unable to continue! Press any key to end the program." << endl;
return _getch();
}
string fileName( ".\\output.avi" );
unsigned int frameRate = 25;
unsigned int recordingTime = 0;
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 == "outputFile" ) || ( key == "of" ) )
{
fileName = value;
}
else if( ( key == "frameRate" ) || ( key == "fr" ) )
{
frameRate = static_cast<unsigned int>( atoi( value.c_str() ) );
}
else if( ( key == "recordingTime" ) || ( key == "rt" ) )
{
recordingTime = static_cast<unsigned int>( atoi( value.c_str() ) );
}
else
{
cout << "Invalid command-line parameter: '" << param << "' (ignored)." << endl;
boInvalidCommandLineParameterDetected = true;
}
}
}
if( boInvalidCommandLineParameterDetected )
{
displayCommandLineOptions();
}
}
else
{
cout << "No command-line parameters specified." << endl;
displayCommandLineOptions();
}
cout << endl
<< "PLEASE NOTE THAT THIS EXAMPLE APPLICATION MAKES USE OF A VERY OLD, OUTDATED WINDOWS ONLY API WHICH IS NOT RECOMMENDED FOR NEW PROJECTS!" << endl
<< "There are various other, more portable ways to encode/store a video stream there day. Please consider using the FFmpeg library (see" << endl
<< "'ContinuousCaptureFFmpeg' in the C++ manual) or something similar instead!" << endl
<< endl
<< "Using output file '" << fileName << "' with " << frameRate << " frames per second for playback (this has nothing to do with the capture frame rate but only affects the frame rate stored in the header of the AVI file)" << endl
<< endl
<< "Please note that if the frame rate specified only affects the playback speed for the resulting AVI file." << endl
<< "Devices that support a fixed frame rate should be set to the same rate, but this won't be done" << endl
<< "in this sample, thus the playback speed of the AVI file might differ from the real acquisition speed" << endl;
cout << "Initialising the device. This might take some time..." << endl << endl;
try
{
}
{
cout <<
"An error occurred while opening device " << pDev->
serial.
read()
<<
"(error code: " << e.
getErrorCode() <<
"). Press any key to end the application..." << endl;
return _getch();
}
int width = 0, height = 0, bitcount = 0;
try
{
id.pixelFormat.write( idpfRGB888Packed );
Request* pCurrentCaptureBufferLayout = 0;
}
{
<< "Unable to continue. Press any key to end the application." << endl << endl;
return _getch();
}
{
setupBlueFOXFrameRate( pDev, frameRate );
}
try
{
AVIWrapper myAVIWrapper;
myAVIWrapper.OpenAVIFile( fileName.c_str(), OF_WRITE | OF_CREATE | OF_SHARE_DENY_WRITE );
cout << "Please select a compression handler from the dialog box" << endl << endl;
myAVIWrapper.CreateAVIStreamFromDIBs( width, height, bitcount, frameRate, 8000, "myStream" );
unsigned int dwThreadID;
string windowTitle(
"mvIMPACT_acquire sample, Device " + pDev->
serial.
read() );
ThreadParameter threadParam( pDev, windowTitle, &myAVIWrapper );
HANDLE hThread = ( HANDLE )_beginthreadex( 0, 0, liveThread, ( LPVOID )( &threadParam ), 0, &dwThreadID );
if( recordingTime == 0 )
{
cout << "Press any key to end the application" << endl;
if( _getch() == EOF )
{
cout << "'_getch()' did return EOF..." << endl;
}
s_boTerminated = true;
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );
}
else
{
cout << "Recording for " << recordingTime << " ms. Please wait..." << endl;
Sleep( recordingTime );
s_boTerminated = true;
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );
cout << "Press any key to end the application" << endl;
return _getch();
}
}
catch( const AVIException& e )
{
cout << "Error while creating AVI stream(" << string( e.what() ) << ")." << endl
<< "Please note, that not every codec will accept every pixel format, thus this error might" << endl
<< "appear without changing the destination pixel format within the driver. However the" << endl
<< "format selected in this sample (RGB888Packed) works for the greatest number of codecs" << endl
<< "Unable to continue. Press any key to end the application." << endl;
return _getch();
}
return 0;
}
mvBlueFOX related camera settings(Device specific interface layout only).
Definition mvIMPACT_acquire.h:20032
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 product
A string property (read-only) containing the product name of this device.
Definition mvIMPACT_acquire.h:6537
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
PropertyS family
A string property (read-only) containing the family name of this device.
Definition mvIMPACT_acquire.h:6526
ZYX read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:4300
const EnumPropertyI & write(ZYX value, int index=0) const
Writes one value to the property.
Definition mvIMPACT_acquire.h:4426
The function interface to devices supported by this interface.
Definition mvIMPACT_acquire.h:10758
int imageRequestWaitFor(int timeout_ms, int queueNr=0) const
Waits for a request object to become ready.
Definition mvIMPACT_acquire.h:11616
int imageRequestUnlock(int nr) const
Unlocks the request for the driver again.
Definition mvIMPACT_acquire.h:11584
int imageRequestSingle(ImageRequestControl *pImageRequestControl=0, int *pRequestUsed=0) const
Sends an image request to the mvIMPACT::acquire::Device driver.
Definition mvIMPACT_acquire.h:11503
bool isRequestNrValid(int nr) const
Check if nr specifies a valid mvIMPACT::acquire::Request.
Definition mvIMPACT_acquire.h:11763
int getCurrentCaptureBufferLayout(ImageRequestControl &imageRequestControl, Request **ppRequest=0, int *pAlignment=0) const
Returns information about the current capture buffer requirements.
Definition mvIMPACT_acquire.h:11659
int imageRequestReset(int requestCtrlNr, int mode) const
Deletes all requests currently queued for the specified mvIMPACT::acquire::ImageRequestControl.
Definition mvIMPACT_acquire.h:11450
Request * getRequest(int nr) const
Returns a pointer to the desired mvIMPACT::acquire::Request.
Definition mvIMPACT_acquire.h:11189
A class to handle the digital inputs and outputs for mvBlueFOX USB cameras(Device specific interface ...
Definition mvIMPACT_acquire.h:16787
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 getErrorString(void) const
Returns an error string containing information about the reason for the error.
Definition mvIMPACT_acquire.h:270
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
A class to represent one step of a real time control(RTCtr) program (Device specific interface layout...
Definition mvIMPACT_acquire.h:15681
PropertyI address
An integer property, which defines the absolute jump address within this mvIMPACT::acquire::RTCtrProg...
Definition mvIMPACT_acquire.h:15706
PropertyIRTProgOpCodes opCode
An enumerated integer property defining the general purpose of this mvIMPACT::acquire::RTCtrProgramSt...
Definition mvIMPACT_acquire.h:15743
PropertyI clocks_us
An integer property, which defines the waiting time mvIMPACT::acquire::RTCtrProgram.
Definition mvIMPACT_acquire.h:15716
A class to represent real time control programs(Device specific interface layout only).
Definition mvIMPACT_acquire.h:16026
PropertyIRTCtrlModes mode
An enumerated integer property defining the current state this program is into.
Definition mvIMPACT_acquire.h:16187
RTCtrProgramStep * programStep(unsigned int nr) const
Returns a pointer to a program instruction of the program.
Definition mvIMPACT_acquire.h:16169
void setProgramSize(int newSize)
A function to define the number of instructions this program should consist of.
Definition mvIMPACT_acquire.h:16145
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
PropertyI imageBytesPerPixel
An integer property (read-only) containing the number of bytes per pixel in this image.
Definition mvIMPACT_acquire.h:10306
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
PropertyPtr imageData
A pointer property (read-only) containing the start address of the image data.
Definition mvIMPACT_acquire.h:10187
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
A class that can be used to display images in a window.
Definition mvIMPACT_acquire_display.h:606
A class that can be used for displaying images within existing windows or GUI elements that can provi...
Definition mvIMPACT_acquire_display.h:176
void RemoveImage(void)
Removes the current image from the display.
Definition mvIMPACT_acquire_display.h:395
void SetImage(const void *pData, int width, int height, int bitsPerPixel, int pitch)
Sets the next image to display.
Definition mvIMPACT_acquire_display.h:316
void Update(void) const
Immediately redraws the current image.
Definition mvIMPACT_acquire_display.h:405
const int INVALID_ID
A constant to check for an invalid ID returned from the property handling module.
Definition mvPropHandlingDatatypes.h:62
@ DMR_NO_ERROR
The function call was executed successfully.
Definition mvDriverBaseEnums.h:2603
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