Created
January 23, 2017 15:29
-
-
Save fernandoc1/395f77d868d51a154c2ebd34408b76a9 to your computer and use it in GitHub Desktop.
GeniCam image grabbing with Pleora SDK on Ubuntu 16.04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 2.8.3) | |
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -g3") | |
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3 -fPIC") | |
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC") | |
find_package(OpenCV 2.4 REQUIRED opencv_core opencv_highgui opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_objdetect opencv_ocl) | |
set(PLEORA_BASE_DIR /opt/pleora/ebus_sdk/Ubuntu-14.04-x86_64/) | |
set(PLEORA_INCLUDE_DIR ${PLEORA_BASE_DIR}/include/) | |
set(PLEORA_LIBRARY_DIR ${PLEORA_BASE_DIR}/lib/) | |
set(PLEORA_GENICAM_ROOT ${PLEORA_BASE_DIR}/lib/genicam) | |
file(GLOB IVSN_FLIR_SOURCES ${CMAKE_SOURCE_DIR}/src/*.cpp) | |
message("\n ${IVSN_FLIR_SOURCES} \n") | |
include_directories(${PLEORA_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/include) | |
link_directories(${PLEORA_LIBRARY_DIR}) | |
add_executable(IvsnFlir.bin ${IVSN_FLIR_SOURCES}) | |
target_link_libraries(IvsnFlir.bin PvBase PvBuffer PvStream PvDevice PvGenICam opencv_core opencv_highgui pthread) | |
set(EXECUTABLE_SCRIPT ${CMAKE_BINARY_DIR}/IvsnFlir) | |
file(WRITE ${EXECUTABLE_SCRIPT} "#! /bin/bash \n\nGENICAM_ROOT_V2_4=${PLEORA_GENICAM_ROOT} ./IvsnFlir.bin\n\n") | |
execute_process(COMMAND /bin/chmod +x "${EXECUTABLE_SCRIPT}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "gev_camera.hpp" | |
#include <opencv2/highgui/highgui.hpp> | |
#include <iostream> | |
#include <iomanip> | |
GEVCamera::GEVCamera(std::string macAddress) | |
: macAddress(macAddress.c_str()) | |
, running(true) | |
, system() | |
, stream(NULL) | |
, device(NULL) | |
, bufferList() | |
, deviceInfo() | |
, imgWidth() | |
, imgHeight() | |
, imgBufferPtr(NULL) | |
, threadPtr() | |
, imgReadyConditionVariable() | |
, imgReadyMutex() | |
{ | |
} | |
void GEVCamera::connect() | |
{ | |
if(this->threadPtr != nullptr) | |
{ | |
std::cerr << "GEVCamera::connect: error: there is a connection running." << std::endl; | |
return; | |
} | |
PvResult result = this->system.FindDevice(this->macAddress, &this->deviceInfo); | |
this->device = PvDevice::CreateAndConnect(this->deviceInfo, &result); | |
this->stream = this->openStream(deviceInfo); | |
this->configureStream(device, stream); | |
this->createStreamBuffers(this->device, stream, &this->bufferList); | |
this->running = true; | |
this->threadPtr = std::make_shared<std::thread>(&GEVCamera::acquireImages, this, this->device, this->stream); | |
} | |
PvStream* GEVCamera::openStream(const PvDeviceInfo *aDeviceInfo) | |
{ | |
PvStream *lStream; | |
PvResult lResult; | |
// Open stream to the GigE Vision or USB3 Vision device | |
std::cout << "Opening stream to device." << std::endl; | |
lStream = PvStream::CreateAndOpen( aDeviceInfo->GetConnectionID(), &lResult ); | |
if ( lStream == NULL ) | |
{ | |
std::cout << "Unable to stream from " << aDeviceInfo->GetDisplayID().GetAscii() << "." << std::endl; | |
} | |
return lStream; | |
} | |
void GEVCamera::configureStream(PvDevice* aDevice, PvStream* aStream) | |
{ | |
// If this is a GigE Vision device, configure GigE Vision specific streaming parameters | |
PvDeviceGEV* lDeviceGEV = dynamic_cast<PvDeviceGEV *>( aDevice ); | |
if ( lDeviceGEV != NULL ) | |
{ | |
PvStreamGEV *lStreamGEV = static_cast<PvStreamGEV *>( aStream ); | |
// Negotiate packet size | |
lDeviceGEV->NegotiatePacketSize(); | |
// Configure device streaming destination | |
lDeviceGEV->SetStreamDestination( lStreamGEV->GetLocalIPAddress(), lStreamGEV->GetLocalPort() ); | |
} | |
} | |
void GEVCamera::createStreamBuffers(PvDevice* aDevice, PvStream* aStream, BufferList* aBufferList) | |
{ | |
// Reading payload size from device | |
uint32_t lSize = aDevice->GetPayloadSize(); | |
// Use BUFFER_COUNT or the maximum number of buffers, whichever is smaller | |
uint32_t lBufferCount = ( aStream->GetQueuedBufferMaximum() < BUFFER_COUNT ) ? | |
aStream->GetQueuedBufferMaximum() : | |
BUFFER_COUNT; | |
// Allocate buffers | |
for ( uint32_t i = 0; i < lBufferCount; i++ ) | |
{ | |
// Create new buffer object | |
PvBuffer *lBuffer = new PvBuffer; | |
// Have the new buffer object allocate payload memory | |
lBuffer->Alloc( static_cast<uint32_t>( lSize ) ); | |
// Add to external list - used to eventually release the buffers | |
aBufferList->push_back( lBuffer ); | |
} | |
// Queue all buffers in the stream | |
BufferList::iterator lIt = aBufferList->begin(); | |
while ( lIt != aBufferList->end() ) | |
{ | |
aStream->QueueBuffer( *lIt ); | |
lIt++; | |
} | |
} | |
cv::Mat1b GEVCamera::getImage() | |
{ | |
std::unique_lock<std::mutex> lock(this->imgReadyMutex); | |
this->imgReadyConditionVariable.wait(lock); | |
return cv::Mat1b(this->imgHeight, this->imgWidth, this->imgBufferPtr); | |
} | |
void GEVCamera::acquireImages(PvDevice *aDevice, PvStream *aStream) | |
{ | |
// Get device parameters need to control streaming | |
PvGenParameterArray *lDeviceParams = aDevice->GetParameters(); | |
// Map the GenICam AcquisitionStart and AcquisitionStop commands | |
PvGenCommand *lStart = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStart")); | |
// Get stream parameters | |
PvGenParameterArray *lStreamParams = aStream->GetParameters(); | |
// Map a few GenICam stream stats counters | |
PvGenFloat *lFrameRate = dynamic_cast<PvGenFloat *>(lStreamParams->Get("AcquisitionRate")); | |
PvGenFloat *lBandwidth = dynamic_cast<PvGenFloat *>(lStreamParams->Get("Bandwidth")); | |
// Enable streaming and send the AcquisitionStart command | |
std::cout << "Enabling streaming and sending AcquisitionStart command." << std::endl; | |
aDevice->StreamEnable(); | |
lStart->Execute(); | |
double lFrameRateVal = 0.0; | |
double lBandwidthVal = 0.0; | |
while(this->running) | |
{ | |
PvBuffer *lBuffer = NULL; | |
PvResult lOperationResult; | |
// Retrieve next buffer | |
PvResult lResult = aStream->RetrieveBuffer( &lBuffer, &lOperationResult, 1000 ); | |
if ( lResult.IsOK() ) | |
{ | |
//std::cout << "Result OK" << std::endl; | |
if ( lOperationResult.IsOK() ) | |
{ | |
//std::cout << "Operation OK" << std::endl; | |
PvPayloadType lType; | |
// | |
// We now have a valid buffer. This is where you would typically process the buffer. | |
// ----------------------------------------------------------------------------------------- | |
// ... | |
lFrameRate->GetValue( lFrameRateVal ); | |
lBandwidth->GetValue( lBandwidthVal ); | |
// If the buffer contains an image, display width and height. | |
lType = lBuffer->GetPayloadType(); | |
if ( lType == PvPayloadTypeImage ) | |
{ | |
// Get image specific buffer interface. | |
PvImage *lImage = lBuffer->GetImage(); | |
// Read width, height. | |
this->imgWidth = lImage->GetWidth(); | |
this->imgHeight = lImage->GetHeight(); | |
//std::cout << " W: " << std::dec << lWidth << " H: " << lHeight; | |
uint32_t imgSize = this->imgHeight*this->imgWidth; | |
if(this->imgBufferPtr == NULL) | |
{ | |
this->imgBufferPtr = (uint8_t*)malloc(imgSize); | |
} | |
memcpy(this->imgBufferPtr, lImage->GetDataPointer(), imgSize); | |
this->imgReadyConditionVariable.notify_one(); | |
//cv::Mat1b img(this->imgHeight, this->imgWidth, lImage->GetDataPointer()); | |
//cv::imshow("Display", img); | |
//cv::waitKey(1); | |
} | |
else | |
{ | |
std::cout << " (buffer does not contain image)"; | |
} | |
} | |
// Re-queue the buffer in the stream object | |
aStream->QueueBuffer( lBuffer ); | |
} | |
else | |
{ | |
std::cout << "error: " << lResult.GetCodeString().GetAscii() << std::endl; | |
} | |
} | |
// Tell the device to stop sending images. | |
} | |
void GEVCamera::disconnect() | |
{ | |
this->running = false; | |
this->threadPtr.get()->join(); | |
PvGenParameterArray *lDeviceParams = this->device->GetParameters(); | |
PvGenCommand *lStop = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStop")); | |
std::cout << "Sending AcquisitionStop command to the device" << std::endl; | |
lStop->Execute(); | |
// Disable streaming on the device | |
std::cout << "Disable streaming on the controller." << std::endl; | |
this->device->StreamDisable(); | |
// Abort all buffers from the stream and dequeue | |
std::cout << "Aborting buffers still in stream" << std::endl; | |
this->stream->AbortQueuedBuffers(); | |
while (this->stream->GetQueuedBufferCount() > 0) | |
{ | |
PvBuffer *lBuffer = NULL; | |
PvResult lOperationResult; | |
this->stream->RetrieveBuffer(&lBuffer, &lOperationResult); | |
} | |
this->threadPtr.reset(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <PvSystem.h> | |
#include <PvInterface.h> | |
#include <PvDevice.h> | |
#include <PvStream.h> | |
#include <PvBuffer.h> | |
#include <PvStreamGEV.h> | |
#include <PvDeviceGEV.h> | |
#include <PvPixelType.h> | |
#include <PvBufferWriter.h> | |
#include <PvBufferConverterRGBFilter.h> | |
#include <opencv2/core/core.hpp> | |
#include <list> | |
#include <thread> | |
#include <memory> | |
#include <mutex> | |
#include <condition_variable> | |
typedef std::list<PvBuffer *> BufferList; | |
#define BUFFER_COUNT ( 16 ) | |
class GEVCamera | |
{ | |
public: | |
GEVCamera(std::string macAddress); | |
void connect(); | |
void disconnect(); | |
PvStream* openStream(const PvDeviceInfo *aDeviceInfo); | |
void configureStream(PvDevice* aDevice, PvStream* aStream); | |
void createStreamBuffers(PvDevice* aDevice, PvStream* aStream, BufferList* aBufferList); | |
void acquireImages(PvDevice *aDevice, PvStream *aStream); | |
cv::Mat1b getImage(); | |
bool running; | |
std::mutex imgReadyMutex; | |
std::condition_variable imgReadyConditionVariable; | |
PvString macAddress; | |
PvSystem system; | |
PvStream* stream; | |
PvDevice* device; | |
BufferList bufferList; | |
uint32_t imgWidth; | |
uint32_t imgHeight; | |
uint8_t* imgBufferPtr; | |
const PvDeviceInfo* deviceInfo; | |
std::shared_ptr<std::thread> threadPtr; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "gev_camera.hpp" | |
#include <iostream> | |
#include <iomanip> | |
#include <thread> | |
#include <chrono> | |
#include <opencv2/core/core.hpp> | |
#include <opencv2/highgui/highgui.hpp> | |
int main() | |
{ | |
GEVCamera camera("00:11:1c:02:32:54"); | |
camera.connect(); | |
std::cout << "Waiting for 10 seconds" << std::endl; | |
//std::this_thread::sleep_for(std::chrono::seconds(10)); | |
for(int i = 0; i < 100; i++) | |
{ | |
cv::Mat1b img = camera.getImage(); | |
cv::imshow("DISPLAY", img); | |
cv::waitKey(1); | |
} | |
camera.disconnect(); | |
std::cout << "Done" << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment