69815

Taking image with Sapera and copying data to vector

Question:

How do I take images with <a href="https://www.teledynedalsa.com/en/products/imaging/vision-software/sapera-lt/" rel="nofollow">Sapera SDK</a> and transfer the image data from the SapBuffer object to vector?

Answer1:

To handle images taken by camera using Sapera, you should make specialization of SapProcessing class, which is used to process buffers. Otherwise the buffer is cleared automatically after each frame, and you lose the data.

The imaging process goes as follows:

<ol><li>You call Grab() on the camera object to start imaging</li> <li>After each frame has been taken, transfer callback is called. Here you request your SapProcessing object to process the next frame.</li> <li>Run() function of your SapProcessing object is called. Here you can read data from the buffer.</li> <li>After Run() function, processing callback is called.</li> <li>When you have received enough frames, call Freeze() to stop imaging.</li> </ol>

This example code takes images using default settings on the camera (monochrome 8-bit pixel format).

#include <string> #include <vector> #include <memory> #include <stdexcept> #include <iostream> #include <iomanip> #include <atomic> #include "SapClassBasic.h" // Helper function to find the camera by its serial number SapAcqDevice getDeviceBySN(const std::string& sn) { char serverName[CORSERVER_MAX_STRLEN]; char serialNumberName[2048]; const int serverCount = SapManager::GetServerCount(); for (int i = 0; i < serverCount; i++) { if (SapManager::GetResourceCount(i, SapManager::ResourceAcqDevice) != 0) { SapManager::GetServerName(i, serverName, sizeof(serverName)); SapAcqDevice camera(serverName); if (!camera.Create()) { throw std::runtime_error("Failed to create camera object."); } int featureCount; if (camera.GetFeatureCount(&featureCount) && featureCount > 0) { if (camera.GetFeatureValue("DeviceID", serialNumberName, sizeof(serialNumberName)) && serialNumberName == sn) { return camera; } } camera.Destroy(); } } const auto errorStr = "Camera \"" + sn + "\" was not found."; throw std::runtime_error(errorStr.c_str()); } class SapMyProcessing : public SapProcessing { public: SapMyProcessing(SapBuffer* pBuffers, SapProCallback pCallback, void* pContext); virtual ~SapMyProcessing(); protected: virtual BOOL Run(); }; SapMyProcessing::SapMyProcessing(SapBuffer* pBuffers, SapProCallback pCallback, void* pContext) : SapProcessing(pBuffers, pCallback, pContext) {} SapMyProcessing::~SapMyProcessing() { if (m_bInitOK) Destroy(); } BOOL SapMyProcessing::Run() { // Get the current buffer index const int proIndex = GetIndex(); // If this is not true, buffer has overflown SapBuffer::State state; bool goodContent = m_pBuffers->GetState(proIndex, &state) && state == SapBuffer::StateFull; if (goodContent) { void *inAddress = nullptr; m_pBuffers->GetAddress(proIndex, &inAddress); int inSize = 0; m_pBuffers->GetSpaceUsed(proIndex, &inSize); // Width, height and pixel format are received from the camera const int width = m_pBuffers->GetWidth(); const int height = m_pBuffers->GetHeight(); const auto format = m_pBuffers->GetFormat(); const int outSize = width * height; // Skip unexpected pixel format or incomplete frame goodContent = format == SapFormatMono8 && inSize == outSize; if (goodContent) { // Copy data to vector std::vector<uint8_t> outBuffer(outSize); std::copy((uint8_t*)inAddress, (uint8_t*)(inAddress) + outSize, outBuffer.begin()); // Print the first line for (int i = 0; i < width; i++) { std::cout << std::hex << int(outBuffer[i]); } std::cout << std::endl << std::endl; } } return TRUE; } // Information to pass to callbacks struct TransferContext { std::atomic_int frameGrabCount = 0, frameProcessingCount = 0; std::shared_ptr<SapMyProcessing> processing; }; void transferCallback(SapXferCallbackInfo *info) { auto context = (TransferContext*)info->GetContext(); context->frameGrabCount++; if (!info->IsTrash()) { // Execute Run() for this frame context->processing->ExecuteNext(); } } // Processing callback is called after Run() void processingCallback(SapProCallbackInfo* info) { auto context = (TransferContext*)info->GetContext(); // Processing has finished context->frameProcessingCount++; } // The main imaging function void grab(const std::string& serialNumber) { // Number of frames to receive from the camera const int maxFrameCount = 10; TransferContext context; auto camera = getDeviceBySN(serialNumber); std::unique_ptr<SapBuffer> buffer = std::make_unique<SapBufferWithTrash>(maxFrameCount, &camera); std::unique_ptr<SapTransfer> transfer = std::make_unique<SapAcqDeviceToBuf>(&camera, buffer.get(), transferCallback, &context); context.processing = std::make_shared<SapMyProcessing>(buffer.get(), processingCallback, &context); auto cleanup = [&]() { if (context.processing) context.processing->Destroy(); if (transfer) transfer->Destroy(); if (buffer) buffer->Destroy(); camera.Destroy(); }; try { if (!buffer->Create()) { throw std::runtime_error("Failed to create buffer object."); } if (!transfer->Create()) { throw std::runtime_error("Failed to create transfer object."); } if (!context.processing->Create()) { throw std::runtime_error("Failed to create processing object."); } transfer->SetAutoEmpty(false); context.processing->SetAutoEmpty(true); context.processing->Init(); transfer->Grab(); // Wait for the camera to grab all frames while (context.frameGrabCount < maxFrameCount); transfer->Freeze(); if (!transfer->Wait(5000)) { throw std::runtime_error("Failed to stop grab."); } // Wait for processing to complete while (context.frameProcessingCount < maxFrameCount); cleanup(); } catch (...) { cleanup(); throw; } }

Recommend

  • Is there a Python library to list primes?
  • Wordpress PHP within PHP
  • Taxonomy is not working
  • How to warn user not to leave the page? [duplicate]
  • How to access WPF class library from Silverlight using iron python. Is it possible?
  • Unreadable characters displaying in ASP.NET MVC
  • Is Factory method more suitable for frameworks and Abstract facory for Library?
  • Using an interface to apply method to ArrayList
  • How to implement 'if' in Gherkin
  • Using simplemodal with wordpress
  • Radio button in xamarin.ios
  • how to migrate tasks from JIRA to TFS 2012
  • How to populate a Mutation for a different Cassandra table in a trigger
  • Creating separate data source for my session spring using JDBC and spring data jpa in spring boot
  • Angular not getting response when it's a non-200
  • AngularJS ng-repeat img ang video
  • Change JList item background color on hover
  • Adding items to an already existing jlist from another class
  • Covert RFC3339 DateTime to Date in java [duplicate]
  • Keyboard Extension Crash on Device
  • google fusion table- not able to color the layer in map after 5 colors
  • How to debug component/typescript code when running Protractor
  • Difference between assigning instantiation to parent class and derived class
  • Heroku Git Push Master Error
  • Faces Servlet not parsing .xhtml pages in jsf 2. running on tomcat 7
  • jQuery how to translate livequery to on?
  • Firebase suddenly reports invalid signature
  • Threads and Concurrent Modification Exception working with a list
  • jQuery Ajax call to WCF service returning “Method not allowed (405)”
  • Boolean filter using a timestamp value on a dataframe in Python
  • css: column-count 3, image floating spanning 2, chrome not playing. why?
  • Symfony - Setting Cookie onKernelRequest
  • Haskell program that can handle any arbitrary deterministic finite automaton
  • Fortran function variable length string return
  • Add checkbox dynamically using angular 2
  • Controller or RestController
  • Year over Year Stats from a Crossfilter Dataset
  • Ruby regex for matching simpliest Ruby's regexes
  • Why is ordered choice in pyparsing failing for my use case?
  • Google App Engine Datastore: Dealing with eventual consistency