It can also be helpful to familiarize yourself with the ImageFormatControl and Exposure examples as these examples provide a strong introduction to camera customization.
The sequencer is another very powerful tool, which can be used to create and store multiple states of customized image settings. A very useful application of the sequencer is creating high dynamic range images.
This example is probably the most complex and definitely the longest. As such, the configuration has been split between three functions. The first prepares the camera to set the sequences, the second sets the settings for a single state (it is run five times), and the third configures the camera to use the sequencer when it acquires images.
#include <iostream>
#include <sstream>
using namespace Spinnaker;
using namespace Spinnaker::GenApi;
using namespace Spinnaker::GenICam;
using namespace std;
{
cout << "Unable to get " << node << " (" << name << " " << node << " retrieval failed)." << endl << endl;
cout << "The " << node << " may not be available on all camera models..." << endl;
cout << "Please try a Blackfly S camera." << endl << endl;
}
{
int result = 0;
cout << endl << endl << "*** CONFIGURING SEQUENCER ***" << endl << endl;
try
{
CEnumerationPtr ptrSequencerConfigurationValid = nodeMap.GetNode(
"SequencerConfigurationValid");
{
return -1;
}
CEnumEntryPtr ptrSequencerConfigurationValidYes = ptrSequencerConfigurationValid->GetEntryByName(
"Yes");
{
return -1;
}
if (ptrSequencerConfigurationValid->GetCurrentEntry()->GetValue() ==
ptrSequencerConfigurationValidYes->GetValue())
{
{
return -1;
}
CEnumEntryPtr ptrSequencerModeOff = ptrSequencerMode->GetEntryByName(
"Off");
{
return -1;
}
ptrSequencerMode->SetIntValue(static_cast<int64_t>(ptrSequencerModeOff->GetValue()));
}
cout << "Sequencer mode disabled..." << endl;
{
return -1;
}
CEnumEntryPtr ptrExposureAutoOff = ptrExposureAuto->GetEntryByName(
"Off");
{
return -1;
}
ptrExposureAuto->SetIntValue(static_cast<int64_t>(ptrExposureAutoOff->GetValue()));
cout << "Automatic exposure disabled..." << endl;
{
return -1;
}
CEnumEntryPtr ptrGainAutoOff = ptrGainAuto->GetEntryByName(
"Off");
{
return -1;
}
ptrGainAuto->SetIntValue(static_cast<int64_t>(ptrGainAutoOff->GetValue()));
cout << "Automatic gain disabled..." << endl;
CEnumerationPtr ptrSequencerConfigurationMode = nodeMap.GetNode(
"SequencerConfigurationMode");
{
return -1;
}
CEnumEntryPtr ptrSequencerConfigurationModeOn = ptrSequencerConfigurationMode->GetEntryByName(
"On");
{
return -1;
}
ptrSequencerConfigurationMode->SetIntValue(static_cast<int64_t>(ptrSequencerConfigurationModeOn->GetValue()));
cout << "Sequencer configuration mode enabled..." << endl << endl;
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
unsigned int sequenceNumber,
int64_t widthToSet,
int64_t heightToSet,
double exposureTimeToSet,
double gainToSet)
{
int result = 0;
try
{
CIntegerPtr ptrSequencerSetSelector = nodeMap.GetNode(
"SequencerSetSelector");
{
cout << "Unable to set current state. Aborting..." << endl << endl;
return -1;
}
ptrSequencerSetSelector->SetValue(sequenceNumber);
cout << "Setting state " << sequenceNumber << "..." << endl;
{
int64_t widthInc = ptrWidth->GetInc();
if (widthToSet % widthInc != 0)
{
widthToSet = (widthToSet / widthInc) * widthInc;
}
ptrWidth->SetValue(widthToSet);
cout << "\tWidth set to " << ptrWidth->GetValue() << "..." << endl;
}
else
{
cout << "\tUnable to set width; width for sequencer not available on all camera models..." << endl;
}
{
int64_t heightInc = ptrHeight->GetInc();
if (heightToSet % heightInc != 0)
{
heightToSet = (heightToSet / heightInc) * heightInc;
}
ptrHeight->SetValue(heightToSet);
cout << "\tHeight set to " << ptrHeight->GetValue() << "..." << endl;
}
else
{
cout << "\tUnable to set height; height for sequencer not available on all camera models..." << endl;
}
CFloatPtr ptrExposureTime = nodeMap.GetNode(
"ExposureTime");
{
cout << "Unable to set exposure time (node retrieval). Aborting..." << endl << endl;
return -1;
}
double exposureTimeMax = ptrExposureTime->GetMax();
if (exposureTimeToSet > exposureTimeMax)
{
exposureTimeToSet = exposureTimeMax;
}
ptrExposureTime->SetValue(exposureTimeToSet);
cout << "\tExposure set to " << ptrExposureTime->GetValue() << "..." << endl;
{
cout << "Unable to set gain (node retrieval). Aborting..." << endl << endl;
return -1;
}
double gainMax = ptrGain->GetMax();
if (gainToSet > gainMax)
{
gainToSet = gainMax;
}
ptrGain->SetValue(gainToSet);
cout << "\tGain set to " << ptrGain->GetValue() << "..." << endl;
CEnumerationPtr ptrSequencerTriggerSource = nodeMap.GetNode(
"SequencerTriggerSource");
{
cout << "Unable to set trigger source (node retrieval). Aborting..." << endl << endl;
return -1;
}
CEnumEntryPtr ptrSequencerTriggerSourceFrameStart = ptrSequencerTriggerSource->GetEntryByName(
"FrameStart");
if (!
IsAvailable(ptrSequencerTriggerSourceFrameStart) || !
IsReadable(ptrSequencerTriggerSourceFrameStart))
{
cout << "Unable to set trigger source (enum entry retrieval). Aborting..." << endl << endl;
return -1;
}
ptrSequencerTriggerSource->SetIntValue(static_cast<int64_t>(ptrSequencerTriggerSourceFrameStart->GetValue()));
cout << "\tTrigger source set to start of frame..." << endl;
static const int finalSequenceIndex = 4;
CIntegerPtr ptrSequencerSetNext = nodeMap.GetNode(
"SequencerSetNext");
{
cout << "Unable to select next state. Aborting..." << endl << endl;
return -1;
}
if (sequenceNumber == finalSequenceIndex)
{
ptrSequencerSetNext->SetValue(0);
}
else
{
ptrSequencerSetNext->SetValue(sequenceNumber + 1);
}
cout << "\tNext state set to " << ptrSequencerSetNext->GetValue() << "..." << endl;
CCommandPtr ptrSequencerSetSave = nodeMap.GetNode(
"SequencerSetSave");
{
cout << "Unable to save state. Aborting..." << endl << endl;
return -1;
}
ptrSequencerSetSave->Execute();
cout << "Current state saved..." << endl << endl;
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
try
{
CEnumerationPtr ptrSequencerConfigurationMode = nodeMap.GetNode(
"SequencerConfigurationMode");
{
return -1;
}
CEnumEntryPtr ptrSequencerConfigurationModeOff = ptrSequencerConfigurationMode->GetEntryByName(
"Off");
{
return -1;
}
ptrSequencerConfigurationMode->SetIntValue(static_cast<int64_t>(ptrSequencerConfigurationModeOff->GetValue()));
cout << "Sequencer configuration mode disabled..." << endl;
{
return -1;
}
CEnumEntryPtr ptrSequencerModeOn = ptrSequencerMode->GetEntryByName(
"On");
{
return -1;
}
ptrSequencerMode->SetIntValue(static_cast<int64_t>(ptrSequencerModeOn->GetValue()));
cout << "Sequencer mode enabled..." << endl;
CEnumerationPtr ptrSequencerConfigurationValid = nodeMap.GetNode(
"SequencerConfigurationValid");
{
return -1;
}
CEnumEntryPtr ptrSequencerConfigurationValidYes = ptrSequencerConfigurationValid->GetEntryByName(
"Yes");
{
return -1;
}
if (ptrSequencerConfigurationValid->GetCurrentEntry()->GetValue() !=
ptrSequencerConfigurationValidYes->GetValue())
{
cout << "Sequencer configuration not valid. Aborting..." << endl << endl;
return -1;
}
cout << "Sequencer configuration valid..." << endl << endl;
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
try
{
{
return -1;
}
CEnumEntryPtr ptrSequencerModeOff = ptrSequencerMode->GetEntryByName(
"Off");
{
return -1;
}
ptrSequencerMode->SetIntValue(static_cast<int64_t>(ptrSequencerModeOff->GetValue()));
cout << "Turning off sequencer mode..." << endl;
{
CEnumEntryPtr ptrExposureAutoContinuous = ptrExposureAuto->GetEntryByName(
"Continuous");
{
ptrExposureAuto->SetIntValue(static_cast<int64_t>(ptrExposureAutoContinuous->GetValue()));
cout << "Turning automatic exposure back on..." << endl;
}
}
{
CEnumEntryPtr ptrGainAutoContinuous = ptrGainAuto->GetEntryByName(
"Continuous");
{
ptrGainAuto->SetIntValue(static_cast<int64_t>(ptrGainAutoContinuous->GetValue()));
cout << "Turning automatic gain mode back on..." << endl << endl;
}
}
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
cout << endl << "*** DEVICE INFORMATION ***" << endl << endl;
try
{
FeatureList_t features;
CCategoryPtr category = nodeMap.GetNode(
"DeviceInformation");
{
category->GetFeatures(features);
FeatureList_t::const_iterator it;
for (it = features.begin(); it != features.end(); ++it)
{
cout << pfeatureNode->GetName() << " : ";
cout << (
IsReadable(pValue) ? pValue->ToString() :
"Node not readable");
cout << endl;
}
}
else
{
cout << "Device control information not available." << endl;
}
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
cout << endl << "*** IMAGE ACQUISITION ***" << endl << endl;
try
{
{
cout << "Unable to set acquisition mode to continuous (node retrieval). Aborting..." << endl << endl;
return -1;
}
CEnumEntryPtr ptrAcquisitionModeContinuous = ptrAcquisitionMode->GetEntryByName(
"Continuous");
{
cout << "Unable to set acquisition mode to continuous (entry 'continuous' retrieval). Aborting..." << endl
<< endl;
return -1;
}
int64_t acquisitionModeContinuous = ptrAcquisitionModeContinuous->GetValue();
ptrAcquisitionMode->SetIntValue(acquisitionModeContinuous);
cout << "Acquisition mode set to continuous..." << endl;
pCam->BeginAcquisition();
cout << "Acquiring images..." << endl;
CStringPtr ptrStringSerial = nodeMapGenTL.GetNode(
"DeviceSerialNumber");
{
deviceSerialNumber = ptrStringSerial->GetValue();
cout << "Device serial number retrieved as " << deviceSerialNumber << "..." << endl;
}
cout << endl;
for (
unsigned int imageCnt = 0; imageCnt <
k_numImages; imageCnt++)
{
try
{
ImagePtr pResultImage = pCam->GetNextImage(timeout);
if (pResultImage->IsIncomplete())
{
cout << "Image incomplete with image status " << pResultImage->GetImageStatus() << "..." << endl
<< endl;
}
else
{
cout << "Grabbed image " << imageCnt << ", width = " << pResultImage->GetWidth()
<< ", height = " << pResultImage->GetHeight() << endl;
ostringstream filename;
filename << "Sequencer-";
if (deviceSerialNumber != "")
{
filename << deviceSerialNumber.c_str() << "-";
}
filename << imageCnt << ".jpg";
convertedImage->Save(filename.str().c_str());
cout << "Image saved at " << filename.str() << endl;
}
pResultImage->Release();
cout << endl;
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
}
pCam->EndAcquisition();
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
int err = 0;
try
{
INodeMap& nodeMapGenTL = pCam->GetTLDeviceNodeMap();
pCam->Init();
if (err < 0)
{
return err;
}
const unsigned int k_numSequences = 5;
{
cout << "Unable to retrieve maximum width. Aborting..." << endl << endl;
return -1;
}
const int64_t widthMax = ptrWidth->GetMax();
{
cout << "Unable to retrieve maximum height. Aborting..." << endl << endl;
return -1;
}
const int64_t heightMax = ptrHeight->GetMax();
const double k_exposureTimeMaxToSet = 2000000;
CFloatPtr ptrExposureTime = nodeMap.GetNode(
"ExposureTime");
{
cout << "Unable to retrieve maximum exposure time. Aborting..." << endl << endl;
return -1;
}
double exposureTimeMax = ptrExposureTime->GetMax();
if (exposureTimeMax > k_exposureTimeMaxToSet)
{
exposureTimeMax = k_exposureTimeMaxToSet;
}
{
cout << "Unable to retrieve maximum gain. Aborting..." << endl << endl;
return -1;
}
const double gainMax = ptrGain->GetMax();
int64_t widthToSet = widthMax / 4;
int64_t heightToSet = heightMax / 4;
double exposureTimeToSet = ptrExposureTime->GetMin();
double gainToSet = ptrGain->GetMin();
for (unsigned int sequenceNumber = 0; sequenceNumber < k_numSequences; sequenceNumber++)
{
err =
SetSingleState(nodeMap, sequenceNumber, widthToSet, heightToSet, exposureTimeToSet, gainToSet);
if (err < 0)
{
return err;
}
widthToSet += widthMax / 10;
heightToSet += heightMax / 10;
exposureTimeToSet += exposureTimeMax / 10.0;
gainToSet += gainMax / 50.0;
}
uint64_t timeout = static_cast<uint64_t>((exposureTimeToSet / 1000) + 1000);
if (err < 0)
{
return err;
}
result = result |
AcquireImages(pCam, nodeMap, nodeMapGenTL, timeout);
pCam->DeInit();
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
FILE* tempFile = fopen("test.txt", "w+");
if (tempFile == nullptr)
{
cout << "Failed to create file in current folder. Please check "
"permissions."
<< endl;
cout << "Press Enter to exit..." << endl;
getchar();
return -1;
}
fclose(tempFile);
remove("test.txt");
int result = 0;
cout << "Application build date: " << __DATE__ << " " << __TIME__ << endl << endl;
const LibraryVersion spinnakerLibraryVersion = system->GetLibraryVersion();
cout <<
"Spinnaker library version: " << spinnakerLibraryVersion.
major <<
"." << spinnakerLibraryVersion.
minor
<<
"." << spinnakerLibraryVersion.
type <<
"." << spinnakerLibraryVersion.
build << endl
<< endl;
unsigned int numCameras = camList.
GetSize();
cout << "Number of cameras detected: " << numCameras << endl << endl;
if (numCameras == 0)
{
system->ReleaseInstance();
cout << "Not enough cameras!" << endl;
cout << "Done! Press Enter to exit..." << endl;
getchar();
return -1;
}
for (unsigned int i = 0; i < numCameras; i++)
{
cout << endl << "Running example for camera " << i << "..." << endl;
cout << "Camera " << i << " example complete..." << endl << endl;
}
system->ReleaseInstance();
cout << endl << "Done! Press Enter to exit..." << endl;
getchar();
return result;
}