#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 <deque>
#include <apps/Common/exampleHelper.h>
#include <apps/Common/aviwrapper.h>
using namespace std;
static bool s_boTerminated = false;
typedef deque<ImageBufferDesc> ImageQueue;
class ThreadParameter
{
ImageQueue& imageQueue_;
ImageQueue::size_type maxQueueSize_;
int frameRate_;
ThreadParameter& operator=( const ThreadParameter& rhs );
public:
ThreadParameter(
Device* p,
const std::string& windowTitle, ImageQueue& q, ImageQueue::size_type maxSize,
int fr )
: pDev_( p ), displayWindow_( windowTitle ), imageQueue_( q ), maxQueueSize_( maxSize ), frameRate_( fr ) {}
int getFrameRate( void ) const
{
return frameRate_;
}
void setFrameRate( int fr )
{
frameRate_ = fr;
}
Device* getDevice(
void )
const
{
return pDev_;
}
{
return displayWindow_;
}
ImageQueue& getImageQueue( void ) const
{
return imageQueue_;
}
ImageQueue::size_type getMaxQueueSize( void ) const
{
return maxQueueSize_;
}
};
{
int upperHalfOfLines = p->
iHeight / 2;
char* pLowerLine =
static_cast<char*
>( p->
vpData ) + ( ( p->
iHeight - 1 ) * pitch );
char* pUpperLine =
static_cast<char*
>( p->
vpData );
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 << "Enter the desired capture frame rate in Hz: ";
cin >> frameRate_Hz;
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 );
}
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->
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++ );
}
unsigned int __stdcall liveThread( void* pData )
{
ThreadParameter* pThreadParameter = reinterpret_cast<ThreadParameter*>( pData );
cout << "Initialising the device. This might take some time..." << endl;
try
{
if( !pThreadParameter->getDevice()->isOpen() )
{
pThreadParameter->getDevice()->open();
}
}
{
cout << "An error occurred while opening device " << pThreadParameter->getDevice()->serial.read()
<<
"(error code: " << e.
getErrorCodeAsString() <<
"). Press any key to end the application..." << endl;
return _getch();
}
Statistics statistics( pThreadParameter->getDevice() );
{
cout << "'FunctionInterface.imageRequestSingle' returned with an unexpected result: " << result
}
manuallyStartAcquisitionIfNeeded( pThreadParameter->getDevice(), fi );
const unsigned int timeout_ms = 500;
unsigned int cnt = 0;
while( !s_boTerminated )
{
const int requestNr = fi.imageRequestWaitFor( timeout_ms );
if( fi.isRequestNrValid( requestNr ) )
{
const Request* pRequest = fi.getRequest( requestNr );
{
++cnt;
if( cnt % 100 == 0 )
{
cout << "Info from " << pThreadParameter->getDevice()->serial.read()
<< ": " << statistics.framesPerSecond.name() << ": " << statistics.framesPerSecond.readS()
<< ", " << statistics.errorCount.name() << ": " << statistics.errorCount.readS()
<< ", " << statistics.captureTime_s.name() << ": " << statistics.captureTime_s.readS() << endl;
}
if( pThreadParameter->getImageQueue().size() > pThreadParameter->getMaxQueueSize() )
{
pThreadParameter->getImageQueue().pop_front();
}
}
else
{
}
if( fi.isRequestNrValid( lastRequestNr ) )
{
fi.imageRequestUnlock( lastRequestNr );
}
lastRequestNr = requestNr;
fi.imageRequestSingle();
}
else
{
<< ", timeout value too small?" << endl;
}
}
const double fr = statistics.framesPerSecond.read();
pThreadParameter->setFrameRate( static_cast<int>( fr ) );
if( ( fr - static_cast<double>( static_cast<int>( fr ) ) ) >= 0.5 )
{
pThreadParameter->setFrameRate( pThreadParameter->getFrameRate() + 1 );
}
manuallyStopAcquisitionIfNeeded( pThreadParameter->getDevice(), fi );
if( fi.isRequestNrValid( lastRequestNr ) )
{
fi.imageRequestUnlock( lastRequestNr );
}
fi.imageRequestReset( 0, 0 );
return 0;
}
int main( void )
{
Device* pDev = getDeviceFromUserInput( devMgr );
if( !pDev )
{
cout << "Could not obtain a valid pointer to a device. Unable to continue! Press any key to end the program." << endl;
return _getch();
}
int captureFrameRate = 0;
{
setupBlueFOXFrameRate( pDev, captureFrameRate );
}
ImageQueue::size_type maxQueueSize = 0;
cout << "Enter the length of the sequence to buffer (please note that this might be limited by your systems memory): ";
cin >> maxQueueSize;
vector<pair<string, TImageDestinationPixelFormat> > vAvailableDestinationFormats;
id.pixelFormat.getTranslationDict( vAvailableDestinationFormats );
int vSize = static_cast<int>( vAvailableDestinationFormats.size() );
cout << "Available destination formats: " << endl;
for( int i = 0; i < vSize; i++ )
{
cout << "[" << vAvailableDestinationFormats[i].first << "]: " << vAvailableDestinationFormats[i].second << endl;
}
cout << endl << endl;
cout << "If AVI files shall be written please note, that most AVI compression handlers" << endl
<< "accept RGB888Packed formats only. Apart from that planar formats are not supported" << endl
<< "by this sample in order to keep things simple." << endl << endl
<< "Destination format (as integer): ";
int destinationPixelFormat = 0;
cin >> destinationPixelFormat;
try
{
}
{
cout <<
"Failed to set destination pixel format(" << e.
getErrorCodeAsString() <<
"), using default" << endl;
}
cout << "Using " << id.pixelFormat.readS() << "." << endl;
cout << "Press [ENTER] to stop the acquisition thread" << endl;
unsigned int dwThreadID;
ImageQueue imageQueue;
string windowTitle(
"mvIMPACT_acquire sample, Device " + pDev->
serial.
read() );
ThreadParameter threadParam( pDev, windowTitle, imageQueue, maxQueueSize, captureFrameRate );
HANDLE hThread = ( HANDLE )_beginthreadex( 0, 0, liveThread, ( LPVOID )( &threadParam ), 0, &dwThreadID );
if( _getch() == EOF )
{
cout << "Calling '_getch()' did return EOF...\n";
}
s_boTerminated = true;
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );
if( imageQueue.empty() )
{
cout << "No images have been captured thus no playback or storage can be performed"
<< "Press any key to end the application" << endl;
if( _getch() == EOF )
{
cout << "Calling '_getch()' did return EOF...\n";
}
return 1;
}
const ImageQueue::size_type qSize = imageQueue.size();
bool boRun = true;
while( boRun )
{
cout << "Press 'y' to replay the captured sequence of " << qSize << " images from memory or any other key to end the replay loop." << endl;
char c = static_cast<char>( _getch() );
if( c != 'y' )
{
boRun = false;
continue;
}
const DWORD frameDelay = ( threadParam.getFrameRate() > 0 ) ? 1000 / threadParam.getFrameRate() : 40;
cout << "Replaying the last " << qSize << " captured images with " << 1000 / frameDelay << " Hz..." << endl;
for( ImageQueue::size_type i = 0; i < qSize; i++ )
{
display.SetImage( imageQueue[i].getBuffer() );
Sleep( frameDelay );
}
}
cout << endl;
cout << "If you want to save the captured sequence press 'y' or any other key to end the application: ";
if( _getch() != 'y' )
{
return 0;
}
cout << endl << "Please enter the file name for the resulting AVI stream(use proper file extensions like *.avi as otherwise creating the stream may fail): ";
string fileName;
cin >> fileName;
boRun = true;
while( boRun )
{
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 (which might be hidden behind this window)" << endl << endl;
const ImageBuffer* pIB = imageQueue.front().getBuffer();
myAVIWrapper.CreateAVIStreamFromDIBs( pIB->
iWidth, pIB->
iHeight, pIB->
iBytesPerPixel * 8, threadParam.getFrameRate(), 8000,
"myStream" );
boRun = false;
for( ImageQueue::size_type x = 0; x < qSize; x++ )
{
cout << "Storing image " << x << " in stream " << fileName << ".\r";
inplaceHorizontalMirror( pIB );
myAVIWrapper.SaveDataToAVIStream(
reinterpret_cast<unsigned char*
>( pIB->
vpData ), pIB->
iSize );
}
}
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 'q' to end the application or any other key to select a different" << endl
<< "compression handler." << endl;
if( _getch() == 'q' )
{
return 1;
}
}
}
return 0;
}
mvBlueFOX related camera settings(Device specific interface layout only).
Definition mvIMPACT_acquire.h:20072
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
PropertyS family
A string property (read-only) containing the family name of this device.
Definition mvIMPACT_acquire.h:6526
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
A class to handle the digital inputs and outputs for mvBlueFOX USB cameras(Device specific interface ...
Definition mvIMPACT_acquire.h:16815
ImageBufferDesc clone(void) const
Returns a deep copy of the mvIMPACT::acquire::ImageBuffer object referenced by this descriptor.
Definition mvIMPACT_acquire.h:8276
Properties to define the format of resulting images.
Definition mvIMPACT_acquire.h:12377
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
A class to represent one step of a real time control(RTCtr) program (Device specific interface layout...
Definition mvIMPACT_acquire.h:15709
PropertyI address
An integer property, which defines the absolute jump address within this mvIMPACT::acquire::RTCtrProg...
Definition mvIMPACT_acquire.h:15734
PropertyIRTProgOpCodes opCode
An enumerated integer property defining the general purpose of this mvIMPACT::acquire::RTCtrProgramSt...
Definition mvIMPACT_acquire.h:15771
PropertyI clocks_us
An integer property, which defines the waiting time mvIMPACT::acquire::RTCtrProgram.
Definition mvIMPACT_acquire.h:15744
A class to represent real time control programs(Device specific interface layout only).
Definition mvIMPACT_acquire.h:16054
PropertyIRTCtrlModes mode
An enumerated integer property defining the current state this program is into.
Definition mvIMPACT_acquire.h:16215
RTCtrProgramStep * programStep(unsigned int nr) const
Returns a pointer to a program instruction of the program.
Definition mvIMPACT_acquire.h:16197
void setProgramSize(int newSize)
A function to define the number of instructions this program should consist of.
Definition mvIMPACT_acquire.h:16173
Contains information about a captured buffer.
Definition mvIMPACT_acquire.h:8640
const ImageBufferDesc & getImageBufferDesc(void) const
Returns a const reference to the image buffer descriptor of this request.
Definition mvIMPACT_acquire.h:9077
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
Contains basic statistical information.
Definition mvIMPACT_acquire.h:14517
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
int iHeight
The height of the image in pixel or lines.
Definition mvImageBuffer.h:100
int iWidth
The width of the image in pixel.
Definition mvImageBuffer.h:102
int iLinePitch
The offset (in bytes) to the next line of this channel.
Definition mvImageBuffer.h:72
void * vpData
The starting address of the image.
Definition mvImageBuffer.h:159
ChannelData * pChannels
A pointer to an array of channel specific image data.
Definition mvImageBuffer.h:168
int iBytesPerPixel
The number of bytes per pixel.
Definition mvImageBuffer.h:98
int iSize
The size (in bytes) of the whole image.
Definition mvImageBuffer.h:114
TImageDestinationPixelFormat
Defines the pixel format of the result image.
Definition mvDriverBaseEnums.h:3207
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.h:2601
const int INVALID_ID
A constant to check for an invalid ID returned from the property handling module.
Definition mvPropHandlingDatatypes.h:64
@ idpfRGB888Packed
A three channel interleaved RGB format containing 24 bit per pixel. (PFNC name: BGR8).
Definition mvDriverBaseEnums.h:3323
@ DEV_NO_FREE_REQUEST_AVAILABLE
The user requested a new image, but no free mvIMPACT::acquire::Request object is available to process...
Definition mvDriverBaseEnums.h:2713
@ DMR_NO_ERROR
The function call was executed successfully.
Definition mvDriverBaseEnums.h:2603
Fully describes a captured image.
Definition mvImageBuffer.h:96
@ ctsRTCtrl
Use real time controller (RTCtrl) as the source for the trigger signal.
Definition mvDriverBaseEnums.h:1584
@ rtctrlProgWaitClocks
Wait for n clocks.
Definition mvDriverBaseEnums.h:4727
@ rtctrlProgJumpLoc
Jump to location.
Definition mvDriverBaseEnums.h:4729
@ rtctrlProgTriggerReset
Reset internal trigger signal of the sensor controller.
Definition mvDriverBaseEnums.h:4733
@ rtctrlProgTriggerSet
Set internal trigger signal of the sensor controller.
Definition mvDriverBaseEnums.h:4731
@ ctmOnRisingEdge
Start the exposure of a frame when the trigger input level changes from low to high.
Definition mvDriverBaseEnums.h:1557
@ rtctrlModeRun
RTC switched on and NOT editable.
Definition mvDriverBaseEnums.h:4709
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