使用 Sapera 拍摄图像并将数据复制到矢量
Posted
技术标签:
【中文标题】使用 Sapera 拍摄图像并将数据复制到矢量【英文标题】:Taking image with Sapera and copying data to vector 【发布时间】:2019-02-08 11:19:25 【问题描述】:如何使用Sapera SDK 拍摄图像并将图像数据从SapBuffer
对象传输到矢量?
【问题讨论】:
【参考方案1】:要使用 Sapera 处理相机拍摄的图像,您应该专门化 SapProcessing
类,该类用于处理缓冲区。否则缓冲区会在每一帧后自动清除,你会丢失数据。
成像过程如下:
-
您在相机对象上调用
Grab()
以开始成像
拍摄完每一帧后,调用传输回调。在这里,您请求您的 SapProcessing
对象来处理下一帧。
调用 SapProcessing
对象的 Run()
函数。在这里您可以从缓冲区中读取数据。
在Run()
函数之后,调用处理回调。
当您收到足够的帧时,请致电Freeze()
停止成像。
此示例代码使用相机上的默认设置(单色 8 位像素格式)拍摄图像。
#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;
【讨论】:
以上是关于使用 Sapera 拍摄图像并将数据复制到矢量的主要内容,如果未能解决你的问题,请参考以下文章
急求,arcgis中,如何求每个独立的栅格块的平均值,并将平均值赋予到对应的矢量图块上???