It can also be helpful to familiarize yourself with the ImageEvents example, as image callbacks follow the same general procedure as relayed image events, but with a few less steps.
#include <chrono>
#include <iomanip>
#include <iostream>
#include <string>
#include <thread>
using namespace std;
uint64_t
timeout = EVENT_TIMEOUT_INFINITE;
{
const std::chrono::system_clock::time_point
invalid_time = std::chrono::system_clock::time_point{};
std::chrono::system_clock::time_point
startTime;
std::chrono::system_clock::time_point
lastEvent;
{
}
{
}
{
}
};
{
{
}
};
{
cout <<
"Use '" <<
argPrintUsage <<
"' to see list of supported arguments." << endl << endl;
cout << "ImageRelay [options] <ip>" << endl << endl;
cout << "Example Usage:" << endl;
<< " <ReceiverIP>" << endl;
<< endl;
cout << "Options:" << endl;
<< "<Starts as receiver (listen on IP:Port)>" << endl;
<< "<Starts as sender (connect to receiver IP:Port)>" << endl;
<<
"<Optional. Number of images to transmit (default " <<
numImagesToGrab <<
")>" << endl;
<< "<Optional. Saves grabbed images to disk>" << endl;
<< "<Optional. Connection timeout in ms (default is EVENT_TIMEOUT_INFINITE for waiting indefinitely)>" << endl;
<< "<IPv4 Sender Address>" << endl;
<<
"<IPv4 Sender Port (default " <<
senderPort <<
")>" << endl;
<< "<IPv4 Receiver Address>" << endl;
<<
"<IPv4 Receiver Port (default " <<
receiverPort <<
")>" << endl;
}
{
cout << "*** PARSING ARGUMENTS ***" << endl << endl;
if (argc == 1)
{
return false;
}
for (int argument = 1; argument < argc; ++argument)
{
std::string arg = argv[argument];
{
return false;
}
{
if (argument + 1 <= argc)
{
}
}
{
if (argument + 1 <= argc)
{
}
}
{
if (argument + 1 <= argc)
{
argument++;
}
}
{
if (argument + 1 <= argc)
{
argument++;
}
}
{
if (argument + 1 <= argc)
{
argument++;
}
}
{
if (argument + 1 <= argc)
{
argument++;
}
}
{
if (argument + 1 <= argc)
{
argument++;
}
}
{
}
{
if (argument + 1 <= argc)
{
timeout = atoi(argv[argument + 1]);
argument++;
}
}
}
{
cout << "Exactly one of receiver (-r) or sender (-s) must be specified." << endl << endl;
return false;
}
{
cout << "Please provide source IP address with -si <ip address>" << endl;
return false;
}
{
}
{
}
return true;
}
{
const auto currentTime = std::chrono::system_clock::now();
if (printSummary)
{
const auto totalDuration = currentTime - timeInfo->
startTime;
const auto totalDurationInMicroSeconds =
std::chrono::duration_cast<std::chrono::microseconds>(totalDuration).count();
const auto totalDurationInSeconds = static_cast<double>(totalDurationInMicroSeconds) / 1000000;
const auto activeDurationInMicroSeconds =
std::chrono::duration_cast<std::chrono::microseconds>(activeDuration).count();
const auto activeDurationInSeconds = static_cast<double>(activeDurationInMicroSeconds) / 1000000;
bool dataTransferred = false;
{
std::cout << "Transfer Duration (seconds) : " << activeDurationInSeconds << std::endl;
std::cout << "Total Duration (seconds) : " << totalDurationInSeconds << std::endl;
if (activeDurationInSeconds > 1)
{
std::cout << "Transfer FPS : " << totalRecvFrameRate << std::endl;
std::cout << "Transfer data rate : " << totalRecvDataRate / 1024 / 1024 << " MBps"
<< std::endl;
}
dataTransferred = true;
}
{
std::cout << "Transfer Duration (seconds) : " << activeDurationInSeconds << std::endl;
std::cout << "Total Duration (seconds) : " << totalDurationInSeconds << std::endl;
if (activeDurationInSeconds > 1)
{
std::cout << "Transfer FPS : " << totalSendFrameRate << std::endl;
std::cout << "Transfer data rate : " << totalSendDataRate / 1024 / 1024 << " MBps"
<< std::endl;
}
dataTransferred = true;
}
if (!dataTransferred)
{
std::cout << "Duration (seconds) : " << totalDurationInSeconds << std::endl;
std::cout << "No relay data transferred.\n";
}
}
else
{
const auto transferDurationInMicroSeconds =
std::chrono::duration_cast<std::chrono::microseconds>(transferDuration).count();
const auto transferDurationInSeconds = static_cast<double>(transferDurationInMicroSeconds) / 1000000;
bool dataTransferred = false;
{
if (transferDurationInSeconds > 1)
{
std::cout << "Transfer FPS: " << std::fixed << std::setprecision(3) << transferRecvFrameRate
<< "; ";
std::cout << "Transfer data Rate: " << std::fixed << std::setprecision(3) << transferRecvDataRate / 1024 / 1024
<< " MBps; ";
}
dataTransferred = true;
}
{
if (transferDurationInSeconds > 1)
{
std::cout << "Transfer FPS: " << std::fixed << std::setprecision(3) << transferSendFrameRate << "; ";
std::cout << "Transfer data Rate: " << std::fixed << std::setprecision(3) << transferSendDataRate / 1024 / 1024
<< " MBps; ";
}
dataTransferred = true;
}
if (!dataTransferred)
{
std::cout << "No relay data transferred.\n";
}
}
}
{
public:
{
m_imageCnt = 0;
m_numImages = maxImages;
m_saveImages = saveImagesToDisk;
timeInfo = timeInformation;
}
{
INodeMap& nodeMap = pCam->GetTLDeviceNodeMap();
m_deviceSerialNumber = "";
CStringPtr ptrDeviceSerialNumber = nodeMap.GetNode(
"DeviceSerialNumber");
{
m_deviceSerialNumber = ptrDeviceSerialNumber->GetValue();
}
m_imageCnt = 0;
m_numImages = maxImages;
m_saveImages = saveImagesToDisk;
timeInfo = timeInformation;
pCam = nullptr;
m_processor.SetColorProcessing(SPINNAKER_COLOR_PROCESSING_ALGORITHM_HQ_LINEAR);
}
{
}
{
const auto imageEventTime = std::chrono::system_clock::now();
if (m_imageCnt < m_numImages)
{
if (image->IsIncomplete())
{
cout << "Image incomplete with image status " << image->GetImageStatus() << "..." << endl << endl;
}
else
{
const uint64_t frameID = image->GetFrameID();
if (frameID < 10 || frameID % 200 == 0)
{
cout << "Grabbed image " << m_imageCnt << ", id = " << frameID << ", width = " << image->GetWidth()
<< ", height = " << image->GetHeight() << endl;
}
if (m_saveImages)
{
ostringstream filename;
filename << "ImageRelay-";
if (m_deviceSerialNumber != "")
{
filename << m_deviceSerialNumber.c_str() << "-";
}
filename << m_imageCnt << ".si";
image->Save(filename.str().c_str());
cout << "Image saved at " << filename.str() << endl << endl;
}
m_imageCnt++;
}
}
}
{
return m_imageCnt;
}
{
return m_numImages;
}
{
m_numImages = maxImages;
return m_numImages;
}
private:
unsigned int m_numImages = 10;
unsigned int m_imageCnt;
bool m_saveImages = false;
string m_deviceSerialNumber;
};
{
int result = 0;
try
{
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
try
{
pCam->RegisterEventHandler(*imageEventHandler);
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
try
{
const int sleepDuration = 1000;
bool printConnectingMsg = true;
{
Sleep(sleepDuration);
{
{
if (printConnectingMsg)
{
cout << "Relay is connecting. Please wait..." << endl;
printConnectingMsg = false;
}
}
else
{
cout << "Relay is disconnected." << endl;
break;
}
}
else
{
printConnectingMsg = true;
}
}
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
try
{
delete imageEventHandler;
cout << "Image events unregistered..." << endl << endl;
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
try
{
pCam->UnregisterEventHandler(*imageEventHandler);
delete imageEventHandler;
cout << "Image events unregistered..." << 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)
{
try
{
cout << pfeatureNode->GetName() << " : ";
cout << (
IsReadable(pValue) ? pValue->ToString() :
"Node not readable");
cout << endl;
}
{
cout << "Node not readable" << endl;
}
}
}
else
{
cout << "Device control information not readable." << endl;
}
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
INodeMap& nodeMap,
INodeMap& nodeMapTLDevice,
{
int result = 0;
cout << endl << endl << "*** IMAGE ACQUISITION ***" << endl << endl;
try
{
{
cout << "Unable to get or set acquisition mode to continuous (node retrieval). Aborting..." << endl << endl;
return -1;
}
CEnumEntryPtr ptrAcquisitionModeContinuous = ptrAcquisitionMode->GetEntryByName(
"Continuous");
{
cout << "Unable to get acquisition mode to continuous (enum entry retrieval). Aborting..." << endl << endl;
return -1;
}
int64_t acquisitionModeContinuous = ptrAcquisitionModeContinuous->GetValue();
ptrAcquisitionMode->SetIntValue(acquisitionModeContinuous);
cout << "Acquisition mode set to continuous..." << endl;
{
CEnumEntryPtr ptrBayerGB8 = ptrPixelFormat->GetEntryByName(
"BayerGB8");
{
int64_t pixelFormatBayerGB8 = ptrBayerGB8->GetValue();
ptrPixelFormat->SetIntValue(pixelFormatBayerGB8);
cout << "PixelFormat set to BayerGB8..." << endl;
}
}
CCommandPtr ptrAcquisitionMaxFrameRate = nodeMap.GetNode(
"AcquisitionMaxFrameRate");
{
ptrAcquisitionMaxFrameRate->Execute();
cout << "Acquisition framerate set to maximum" << endl;
}
CEnumerationPtr ptrDeviceTapGeometry = nodeMap.GetNode(
"DeviceTapGeometry");
{
CEnumEntryPtr ptrGeometry_1X_2YE = ptrDeviceTapGeometry->GetEntryByName(
"Geometry_1X_2YE");
{
ptrDeviceTapGeometry->SetIntValue(ptrGeometry_1X_2YE->GetValue());
cout << "DeviceTapGeometry set to Geometry_1X_2YE" << endl;
}
}
{
double maxGain = ptrGain->GetMax();
ptrGain->SetValue(maxGain);
cout << "Gain set to maximum value: " << ptrGain->GetValue() << endl;
}
CCommandPtr ptrWhiteBalanceCalibrate = nodeMap.GetNode(
"WhiteBalanceCalibrate");
{
ptrWhiteBalanceCalibrate->Execute();
cout << "White balance calibrated." << endl;
}
CCommandPtr ptrDeviceResync = nodeMapTLDevice.GetNode(
"ResyncWithRemoteDevice");
{
ptrDeviceResync->Execute();
cout << "Device resync executed." << endl;
}
pCam->BeginAcquisition();
cout << "Acquiring images..." << endl;
pCam->EndAcquisition();
}
{
cout <<
"Error: " << e.
what() << endl;
result = -1;
}
return result;
}
{
const DWORD sleepDuration = 2000;
do
{
if (isSender)
{
{
{
}
}
}
Sleep(sleepDuration);
return 0;
}
{
int result = 0;
try
{
int err = 0;
if (err < 0)
{
return err;
}
std::cout << "Connecting to the sender...." << std::endl;
std::cout << "Sender connected!" << std::endl;
DWORD threadId;
threadParams->
relay = &relay;
HANDLE hStatsThread = CreateThread(
nullptr, 0,
PrintStatsThread, threadParams, 0, &threadId);
assert(hStatsThread != nullptr);
cout << endl << "*** WAITING FOR RELAYED IMAGES ***" << endl << endl;
cout << endl <<
"# Grabbed Images: " << imageEventHandler->
getImageCount() << endl;
WaitForSingleObject(hStatsThread, INFINITE);
CloseHandle(hStatsThread);
delete threadParams;
}
catch (const std::exception& e)
{
cout << "Receiver aborted due to an error:" << e.what() << endl;
result = -1;
}
return result;
}
{
int result = 0;
int err = 0;
try
{
INodeMap& nodeMapTLDevice = pCam->GetTLDeviceNodeMap();
pCam->Init();
if (err < 0)
{
return err;
}
std::cout << "Connecting to the receiver...." << std::endl;
std::cout << "Receiver connected!" << std::endl;
DWORD threadId;
threadParams->
relay = &relay;
threadParams->
pCam = pCam;
HANDLE hStatsThread = CreateThread(
nullptr, 0,
PrintStatsThread, threadParams, 0, &threadId);
assert(hStatsThread != nullptr);
result = result |
AcquireImages(pCam, relay, nodeMap, nodeMapTLDevice, imageEventHandler);
cout << endl <<
"# Grabbed Images: " << imageEventHandler->
getImageCount() << endl;
pCam->DeInit();
WaitForSingleObject(hStatsThread, INFINITE);
CloseHandle(hStatsThread);
threadParams->
pCam =
nullptr;
delete threadParams;
}
{
cout <<
"Sender aborted due to an error: " << e.
what() << endl;
result = -1;
}
return result;
}
int main(
int argc,
char** argv)
{
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;
{
{
}
else
{
const LibraryVersion spinnakerLibraryVersion = system->GetLibraryVersion();
cout <<
"Spinnaker library version: " << spinnakerLibraryVersion.
major <<
"."
<< spinnakerLibraryVersion.
minor <<
"." << spinnakerLibraryVersion.
type <<
"."
<< spinnakerLibraryVersion.
build << endl
<< endl;
unsigned int numProducers = producerList.
GetSize();
for (unsigned int i = 0; i < numProducers; i++)
{
cout << "Producer " << i << endl;
cout << " \tFilePath: " << producer->GetProducerFilePath() << endl;
unsigned int numInterfaces = interfaceList.
GetSize();
cout << "\tNumber of interfaces detected: " << numInterfaces << endl;
unsigned int numCameras = camList.
GetSize();
cout << "\tNumber of cameras detected: " << numCameras << 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;
}
int result = 0;
cout << "Running example with camera index 0" << endl;
pCam = nullptr;
system->ReleaseInstance();
}
}
cout << endl << "Done! Press Enter to exit..." << endl;
getchar();
return result;
}
int AcquireImages(CameraPtr pCam, INodeMap &nodeMap, INodeMap &nodeMapTLDevice)
Definition Acquisition.cpp:200
int main(int, char **)
Definition Acquisition.cpp:536
int PrintDeviceInfo(INodeMap &nodeMap)
Definition Acquisition.cpp:442
void PrintUsage()
Definition FileAccess_QuickSpin.cpp:1026
int WaitForImages(ImageEventHandlerImpl *&imageEventHandler)
Definition ImageEvents.cpp:214
int ResetImageEvents(CameraPtr pCam, ImageEventHandlerImpl *&imageEventHandler)
Definition ImageEvents.cpp:249
int ConfigureImageEvents(CameraPtr pCam, ImageEventHandlerImpl *&imageEventHandler)
Definition ImageEvents.cpp:171
uint64_t timeout
Definition ImageRelay.cpp:70
bool bReceiver
Definition ImageRelay.cpp:60
const char * argTimeout
Definition ImageRelay.cpp:130
gcstring receiverIPAddress
Definition ImageRelay.cpp:63
int RunSender(CameraPtr pCam)
Definition ImageRelay.cpp:1033
ConnectParameters relayConnectParams
Definition ImageRelay.cpp:67
const char * argReceiverPort
Definition ImageRelay.cpp:125
int RunReceiver()
Definition ImageRelay.cpp:963
unsigned int senderPort
Definition ImageRelay.cpp:64
const char * argSenderIP
Definition ImageRelay.cpp:126
bool bSourceIPSpecified
Definition ImageRelay.cpp:66
bool bSender
Definition ImageRelay.cpp:61
DWORD WINAPI PrintStatsThread(LPVOID lpParam)
Definition ImageRelay.cpp:926
gcstring senderIPAddress
Definition ImageRelay.cpp:62
void PrintRelayStatistics(const RelayStatistics *stats, TimeInformation *timeInfo, bool printSummary=false)
Definition ImageRelay.cpp:300
const char * argReceiverIP
Definition ImageRelay.cpp:124
bool saveImages
Definition ImageRelay.cpp:69
const char * argStartSender
Definition ImageRelay.cpp:123
const char * argSenderPort
Definition ImageRelay.cpp:127
unsigned int receiverPort
Definition ImageRelay.cpp:65
unsigned int numImagesToGrab
Definition ImageRelay.cpp:68
const char * argStartReceiver
Definition ImageRelay.cpp:122
const char * argSaveImages
Definition ImageRelay.cpp:129
Definition AcquisitionMultipleCameraRecovery.cpp:57
int getImageCount()
Definition ImageEvents.cpp:151
int getMaxImages()
Definition ImageEvents.cpp:157
void OnImageEvent(ImagePtr image)
Image event callback.
Definition AcquisitionMultipleCameraRecovery.cpp:109
~ImageEventHandlerImpl()
Definition AcquisitionMultipleCameraRecovery.cpp:66
int setMaxImages(unsigned int maxImages)
Definition ImageRelay.cpp:545
Used to hold a list of camera objects.
Definition CameraList.h:42
void Clear()
Clears the list of cameras and destroys their corresponding reference counted objects.
CameraPtr GetByIndex(unsigned int index) const
Returns a pointer to a camera object at the "index".
unsigned int GetSize() const
Returns the size of the camera list.
A reference tracked pointer to a camera object.
Definition CameraPtr.h:44
The Exception object represents an error that is returned from the library.
Definition Exception.h:51
virtual const char * what() const
virtual override for what().
SmartPointer for IFloat interface pointer.
Definition Pointer.h:421
Encapsulates a GenApi pointer dealing with the dynamic_cast automatically.
Definition Pointer.h:75
A handler for capturing image arrival events.
Definition ImageEventHandler.h:46
Image post processing class for converting a source image to another pixel format.
Definition ImageProcessor.h:160
A reference tracked pointer to an image object.
Definition ImagePtr.h:46
A list of the available interfaces on the system.
Definition InterfaceList.h:42
unsigned int GetSize() const
Returns the size of the interface list.
A list of the available producers on the system.
Definition ProducerList.h:42
ProducerPtr GetByIndex(unsigned int index) const
Returns a pointer to an Producer object at the "index".
void Clear()
Clears the list of producers and destroys their corresponding objects.
unsigned int GetSize() const
Returns the size of the producer list.
A reference tracked pointer to the producer object.
Definition ProducerPtr.h:44
Spinnaker Relay class that enables forwarding of Spinnaker images from source to destination PC.
Definition SpinnakerRelay.h:42
virtual bool IsConnected()
Returns a boolean value indicating if this relay is connected.
virtual void SetNumBuffers(uint64_t numBuffers)
Sets number of relay buffers.
virtual void Disconnect()
Disconnects a Spinnaker Relay connection.
virtual void SetConnectParameters(const ConnectParameters connectParam)
Sets relay connect parameters.
virtual void GetStatistics(RelayStatistics *statistics)
Returns a RelayStatistics struct containing statistics about the performance of the relay connection:...
virtual void UnregisterEventHandler(EventHandler &eventHandler)
Unregisters an event handler from the receiver.
virtual bool IsConnecting()
Returns a boolean value indicating if the relay is currently attempting to connect.
virtual void RegisterEventHandler(EventHandler &eventHandler)
Registers an image event handler for the receiver.
virtual void AddSource(CameraPtr pCamera)
Adds a camera as a streaming source to the sender.
virtual void Connect()
Initiates a Spinnaker Relay connection.
A reference tracked pointer to a system object.
Definition SystemPtr.h:44
Part of the QuickSpin API to provide access to camera information without having to first initialize ...
Definition TransportLayerStream.h:45
GenApi::IInteger & StreamLostFrameCount
Description: Number of times new data could not be acquired and was lost because there was no free bu...
Definition TransportLayerStream.h:195
bool IsWritable(EAccessMode AccessMode)
Tests if writable.
Definition INode.h:277
bool IsReadable(EAccessMode AccessMode)
Tests if readable.
Definition INode.h:253
interface SPINNAKER_API_ABSTRACT INodeMap
Interface to access the node map.
Definition INodeMap.h:54
@ SPINNAKER_ROLE_RECEIVER
Definition SpinnakerRelayDefs.h:55
@ SPINNAKER_ROLE_SENDER
Definition SpinnakerRelayDefs.h:54
Definition AutoPollController.h:33
Definition EventHandler.h:29
Provides easier access to the current version of Spinnaker.
Definition SpinnakerDefs.h:706
unsigned int minor
Minor version of the library.
Definition SpinnakerDefs.h:711
unsigned int major
Major version of the library.
Definition SpinnakerDefs.h:708
unsigned int type
Version type of the library.
Definition SpinnakerDefs.h:714
unsigned int build
Build number of the library.
Definition SpinnakerDefs.h:717
Connection Parameters.
Definition SpinnakerRelayDefs.h:68
Relay Statistics.
Definition SpinnakerRelayDefs.h:92
uint64_t instanceSendSuccessCount
Definition SpinnakerRelayDefs.h:95
uint64_t totalRecvDataCount
Definition SpinnakerRelayDefs.h:116
uint64_t totalSendDropCount
Definition SpinnakerRelayDefs.h:110
uint64_t totalRecvSuccessCount
Definition SpinnakerRelayDefs.h:113
uint64_t totalRecvErrorCount
Definition SpinnakerRelayDefs.h:114
uint64_t totalSendErrorCount
Definition SpinnakerRelayDefs.h:109
uint64_t instanceSendDropCount
Definition SpinnakerRelayDefs.h:97
uint64_t instanceSendDataCount
Definition SpinnakerRelayDefs.h:98
uint64_t instanceRecvErrorCount
Definition SpinnakerRelayDefs.h:101
uint64_t totalRecvDropCount
Definition SpinnakerRelayDefs.h:115
uint64_t totalSendSuccessCount
Definition SpinnakerRelayDefs.h:108
uint64_t instanceRecvSuccessCount
Definition SpinnakerRelayDefs.h:100
uint64_t instanceRecvDataCount
Definition SpinnakerRelayDefs.h:103
uint64_t totalSendDataCount
Definition SpinnakerRelayDefs.h:111
uint64_t instanceRecvDropCount
Definition SpinnakerRelayDefs.h:102
uint64_t instanceSendErrorCount
Definition SpinnakerRelayDefs.h:96
Definition ImageRelay.cpp:105
TimeInformation * timeInfo
Definition ImageRelay.cpp:109
SpinnakerRelay * relay
Definition ImageRelay.cpp:106
CameraPtr pCam
Definition ImageRelay.cpp:108
bool isSender
Definition ImageRelay.cpp:107
ThreadParameters()
Definition ImageRelay.cpp:111