GrabBag/Device/GalaxyDevice/Src/GalaxyDevice.cpp

1234 lines
33 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "GalaxyDevice.h"
#include "VrError.h"
#include "VrLog.h"
#include <cstring>
#include <iostream>
#include <thread>
#include <chrono>
// Galaxy SDK头文件
#ifdef _WIN32
// Windows 平台使用 C++ API
#define _WINSOCKAPI_ // 防止winsock.h被包含避免与winsock2.h冲突
#include "GXIAPIBase.h"
#include "IGXFactory.h"
#include "IGXDevice.h"
#include "IGXStream.h"
#include "IGXFeatureControl.h"
#include "IImageData.h"
#include "IIntFeature.h"
#include "IFloatFeature.h"
#include "IEnumFeature.h"
#include "ICommandFeature.h"
#include "IVrUtils.h"
using namespace GxIAPICPP;
#else
// Linux/ARM 平台使用 C API
#include "GxIAPI.h"
#include "DxImageProc.h"
#endif
// 帧回调处理类实现
#ifdef _WIN32
void CGalaxyDevice::CCaptureEventHandler::DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam)
{
if (m_pDevice && !objImageDataPointer.IsNull())
{
m_pDevice->ProcessCapturedImage(objImageDataPointer);
}
}
#endif
// 创建设备对象
int IGalaxyDevice::CreateObject(IGalaxyDevice** ppDevice)
{
if (ppDevice == nullptr) {
return ERR_CODE(DEV_ARG_INVAILD);
}
try {
*ppDevice = new CGalaxyDevice();
return SUCCESS;
}
catch (...) {
return ERR_CODE(DATA_ERR_MEM);
}
}
// 构造函数
CGalaxyDevice::CGalaxyDevice()
: m_pCaptureEventHandler(nullptr)
, m_bSDKInitialized(false)
, m_bDeviceOpen(false)
, m_bAcquisitioning(false)
, m_bNewImageReady(false)
{
memset(&m_capturedImage, 0, sizeof(m_capturedImage));
#ifdef _WIN32
// Windows 平台初始化
#else
// Linux/ARM 平台初始化
m_hDevice = nullptr;
m_pDeviceInfo = nullptr;
m_nDeviceNum = 0;
#endif
}
// 析构函数
CGalaxyDevice::~CGalaxyDevice()
{
try {
if (m_bAcquisitioning) {
StopAcquisition();
}
if (m_bDeviceOpen) {
CloseDevice();
}
if (m_bSDKInitialized) {
UninitSDK();
}
#ifdef _WIN32
if (m_pCaptureEventHandler) {
delete m_pCaptureEventHandler;
m_pCaptureEventHandler = nullptr;
}
#else
// Linux/ARM 平台清理
if (m_pDeviceInfo) {
delete[] m_pDeviceInfo;
m_pDeviceInfo = nullptr;
}
#endif
}
catch (...) {
// 忽略析构函数中的异常
}
}
// 初始化SDK
int CGalaxyDevice::InitSDK()
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_bSDKInitialized) {
return SUCCESS;
}
IGXFactory::GetInstance().Init();
m_bSDKInitialized = true;
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_OPEN_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (m_bSDKInitialized) {
return SUCCESS;
}
GX_STATUS status = GXInitLib();
if (status == GX_STATUS_SUCCESS) {
m_bSDKInitialized = true;
return SUCCESS;
}
return static_cast<int>(status);
#endif
}
// 反初始化SDK
int CGalaxyDevice::UninitSDK()
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_bSDKInitialized) {
IGXFactory::GetInstance().Uninit();
m_bSDKInitialized = false;
}
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CLOSE_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (m_bSDKInitialized) {
GX_STATUS status = GXCloseLib();
m_bSDKInitialized = false;
if (status != GX_STATUS_SUCCESS) {
return static_cast<int>(status);
}
}
return SUCCESS;
#endif
}
// 获取SDK版本
int CGalaxyDevice::GetSDKVersion(std::string& version)
{
version = "GalaxySDK 1.1.2412.9031";
return SUCCESS;
}
// 枚举设备
int CGalaxyDevice::EnumerateDevices(std::vector<GalaxyDeviceInfo>& deviceList, unsigned int timeout)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (!m_bSDKInitialized) {
return ERR_CODE(DEV_NO_OPEN);
}
deviceList.clear();
// 更新设备列表
gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(timeout, vectorDeviceInfo);
// 转换为我们的数据结构
for (size_t i = 0; i < vectorDeviceInfo.size(); ++i) {
GalaxyDeviceInfo info;
info.serialNumber = vectorDeviceInfo[i].GetSN();
info.modelName = vectorDeviceInfo[i].GetModelName();
info.displayName = vectorDeviceInfo[i].GetDisplayName();
info.ipAddress = vectorDeviceInfo[i].GetIP();
info.macAddress = vectorDeviceInfo[i].GetMAC();
info.deviceClass = vectorDeviceInfo[i].GetDeviceClass();
info.width = 0;
info.height = 0;
deviceList.push_back(info);
}
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_NOT_FIND);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_bSDKInitialized) {
return ERR_CODE(DEV_NO_OPEN);
}
deviceList.clear();
// 更新设备列表
GX_STATUS status = GXUpdateDeviceList(&m_nDeviceNum, timeout);
if (status != GX_STATUS_SUCCESS) {
return static_cast<int>(status);
}
LOG_DEBUG("Find galaxy device size : %zd \n", m_nDeviceNum);
if (m_nDeviceNum == 0) {
return ERR_CODE(DEV_NOT_FIND);
}
// 分配设备信息缓存
if (m_pDeviceInfo) {
delete[] m_pDeviceInfo;
}
m_pDeviceInfo = new GX_DEVICE_BASE_INFO[m_nDeviceNum];
size_t nSize = m_nDeviceNum * sizeof(GX_DEVICE_BASE_INFO);
status = GXGetAllDeviceBaseInfo(m_pDeviceInfo, &nSize);
if (status != GX_STATUS_SUCCESS) {
delete[] m_pDeviceInfo;
m_pDeviceInfo = nullptr;
return static_cast<int>(status);
}
// 转换为我们的数据结构
for (uint32_t i = 0; i < m_nDeviceNum; ++i) {
GalaxyDeviceInfo info;
info.serialNumber = m_pDeviceInfo[i].szSN;
info.modelName = m_pDeviceInfo[i].szModelName;
info.displayName = m_pDeviceInfo[i].szDisplayName;
info.ipAddress = ""; // ARM 版本不提供 IP 地址
info.macAddress = ""; // ARM 版本不提供 MAC 地址
// 设备类型ARM 版本使用 deviceClass (enum),需要转换为字符串
switch (m_pDeviceInfo[i].deviceClass) {
case GX_DEVICE_CLASS_U3V:
info.deviceClass = "U3V";
break;
case GX_DEVICE_CLASS_GEV:
info.deviceClass = "GEV";
break;
case GX_DEVICE_CLASS_USB2:
info.deviceClass = "USB2.0";
break;
default:
info.deviceClass = "Unknown";
break;
}
info.width = 0;
info.height = 0;
deviceList.push_back(info);
}
return SUCCESS;
#endif
}
// 通过序列号打开设备
int CGalaxyDevice::OpenDevice(const std::string& serialNumber)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (!m_bSDKInitialized) {
return ERR_CODE(DEV_NO_OPEN);
}
if (m_bDeviceOpen) {
CloseDevice();
}
// 通过序列号打开设备
m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(
gxstring(serialNumber.c_str()),
GX_ACCESS_EXCLUSIVE
);
if (m_objDevicePtr.IsNull()) {
return ERR_CODE(DEV_NOT_FIND);
}
// 打开数据流
m_objStreamPtr = m_objDevicePtr->OpenStream(0);
if (m_objStreamPtr.IsNull()) {
m_objDevicePtr = CGXDevicePointer();
return ERR_CODE(DEV_OPEN_ERR);
}
// 获取远程特性控制
m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();
if (m_objFeatureControlPtr.IsNull()) {
m_objStreamPtr = CGXStreamPointer();
m_objDevicePtr = CGXDevicePointer();
return ERR_CODE(DEV_OPEN_ERR);
}
m_bDeviceOpen = true;
return SUCCESS;
}
catch (CGalaxyException& e) {
m_objFeatureControlPtr = CGXFeatureControlPointer();
m_objStreamPtr = CGXStreamPointer();
m_objDevicePtr = CGXDevicePointer();
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
m_objFeatureControlPtr = CGXFeatureControlPointer();
m_objStreamPtr = CGXStreamPointer();
m_objDevicePtr = CGXDevicePointer();
return ERR_CODE(DEV_OPEN_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_bSDKInitialized) {
return ERR_CODE(DEV_NO_OPEN);
}
if (m_bDeviceOpen) {
CloseDevice();
}
// 通过序列号打开设备
GX_OPEN_PARAM openParam;
openParam.accessMode = GX_ACCESS_EXCLUSIVE;
openParam.openMode = GX_OPEN_SN;
openParam.pszContent = const_cast<char*>(serialNumber.c_str());
GX_STATUS status = GXOpenDevice(&openParam, &m_hDevice);
if (status != GX_STATUS_SUCCESS) {
m_hDevice = nullptr;
return static_cast<int>(status);
}
// 设置网络相机的流通道包长(提高采集性能)
bool bImplementPacketSize = false;
status = GXIsImplemented(m_hDevice, GX_INT_GEV_PACKETSIZE, &bImplementPacketSize);
if (status == GX_STATUS_SUCCESS && bImplementPacketSize) {
// int64_t nPacketSize = 0;
// status = GXGetOptimalPacketSize(m_hDevice, &nPacketSize);
// if (status == GX_STATUS_SUCCESS) {
// GXSetInt(m_hDevice, GX_INT_GEV_PACKETSIZE, nPacketSize);
// }
}
m_bDeviceOpen = true;
return SUCCESS;
#endif
}
// 通过索引打开设备
int CGalaxyDevice::OpenDeviceByIndex(unsigned int index)
{
try {
// 先枚举设备
std::vector<GalaxyDeviceInfo> deviceList;
int ret = EnumerateDevices(deviceList, 2000);
if (ret != SUCCESS) {
return ret;
}
if (index >= deviceList.size()) {
return ERR_CODE(DEV_ID_ERR);
}
// 通过序列号打开
return OpenDevice(deviceList[index].serialNumber);
}
catch (...) {
return ERR_CODE(DEV_ID_ERR);
}
}
// 关闭设备
int CGalaxyDevice::CloseDevice()
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_bAcquisitioning) {
StopAcquisition();
}
m_objFeatureControlPtr = CGXFeatureControlPointer();
m_objStreamPtr = CGXStreamPointer();
if (!m_objDevicePtr.IsNull()) {
m_objDevicePtr->Close();
m_objDevicePtr = CGXDevicePointer();
}
m_bDeviceOpen = false;
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CLOSE_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (m_bAcquisitioning) {
StopAcquisition();
}
if (m_hDevice) {
GX_STATUS status = GXCloseDevice(m_hDevice);
m_hDevice = nullptr;
m_bDeviceOpen = false;
if (status != GX_STATUS_SUCCESS) {
return static_cast<int>(status);
}
}
m_bDeviceOpen = false;
return SUCCESS;
#endif
}
// 检查设备是否打开
bool CGalaxyDevice::IsDeviceOpen()
{
return m_bDeviceOpen;
}
// 获取设备信息
int CGalaxyDevice::GetDeviceInfo(GalaxyDeviceInfo& deviceInfo)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (!m_bDeviceOpen || m_objDevicePtr.IsNull()) {
return ERR_CODE(DEV_NO_OPEN);
}
const CGXDeviceInfo& info = m_objDevicePtr->GetDeviceInfo();
deviceInfo.serialNumber = info.GetSN();
deviceInfo.modelName = info.GetModelName();
deviceInfo.displayName = info.GetDisplayName();
deviceInfo.ipAddress = info.GetIP();
deviceInfo.macAddress = info.GetMAC();
deviceInfo.deviceClass = info.GetDeviceClass();
// 获取图像尺寸
GetWidth(deviceInfo.width);
GetHeight(deviceInfo.height);
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_NO_OPEN);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_bDeviceOpen || !m_hDevice) {
return ERR_CODE(DEV_NO_OPEN);
}
// 从缓存的设备信息中获取(在 EnumerateDevices 时已获取)
deviceInfo = m_deviceInfo;
// 获取图像尺寸
GetWidth(deviceInfo.width);
GetHeight(deviceInfo.height);
return SUCCESS;
#endif
}
// 设置触发模式
int CGalaxyDevice::SetTriggerMode(bool enable)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CEnumFeaturePointer ptrTriggerMode = m_objFeatureControlPtr->GetEnumFeature("TriggerMode");
if (!ptrTriggerMode.IsNull()) {
ptrTriggerMode->SetValue(enable ? "On" : "Off");
}
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXSetEnum(m_hDevice, GX_ENUM_TRIGGER_MODE,
enable ? GX_TRIGGER_MODE_ON : GX_TRIGGER_MODE_OFF);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 发送软触发
int CGalaxyDevice::SendSoftTrigger()
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CCommandFeaturePointer ptrTriggerSoftware = m_objFeatureControlPtr->GetCommandFeature("TriggerSoftware");
if (!ptrTriggerSoftware.IsNull()) {
ptrTriggerSoftware->Execute();
}
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXSendCommand(m_hDevice, GX_COMMAND_TRIGGER_SOFTWARE);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 开始采集
int CGalaxyDevice::StartAcquisition()
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objStreamPtr.IsNull() || m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
if (m_bAcquisitioning) {
return SUCCESS;
}
// 开始取流
m_objStreamPtr->StartGrab();
// 发送开始采集命令
CCommandFeaturePointer ptrAcquisitionStart = m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart");
if (!ptrAcquisitionStart.IsNull()) {
ptrAcquisitionStart->Execute();
}
m_bAcquisitioning = true;
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
if (m_bAcquisitioning) {
return SUCCESS;
}
// 发送开始采集命令
GX_STATUS status = GXStreamOn(m_hDevice);
if (status == GX_STATUS_SUCCESS) {
m_bAcquisitioning = true;
return SUCCESS;
}
return static_cast<int>(status);
#endif
}
// 停止采集
int CGalaxyDevice::StopAcquisition()
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (!m_bAcquisitioning) {
return SUCCESS;
}
// 发送停止采集命令
if (!m_objFeatureControlPtr.IsNull()) {
CCommandFeaturePointer ptrAcquisitionStop = m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop");
if (!ptrAcquisitionStop.IsNull()) {
ptrAcquisitionStop->Execute();
}
}
// 停止取流
if (!m_objStreamPtr.IsNull()) {
m_objStreamPtr->StopGrab();
}
// 注销回调
if (m_pCaptureEventHandler && !m_objStreamPtr.IsNull()) {
m_objStreamPtr->UnregisterCaptureCallback();
delete m_pCaptureEventHandler;
m_pCaptureEventHandler = nullptr;
}
m_bAcquisitioning = false;
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_bAcquisitioning) {
return SUCCESS;
}
if (m_hDevice) {
GX_STATUS status = GXStreamOff(m_hDevice);
m_bAcquisitioning = false;
if (status != GX_STATUS_SUCCESS) {
return static_cast<int>(status);
}
}
m_bAcquisitioning = false;
return SUCCESS;
#endif
}
// 检查是否正在采集
bool CGalaxyDevice::IsAcquisitioning()
{
return m_bAcquisitioning;
}
// 单次采集图像 - 简化实现
int CGalaxyDevice::CaptureImage(GalaxyImageData& image, unsigned int timeout)
{
#ifdef _WIN32
// Windows平台使用C++ API
try {
if (m_objStreamPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
// 同步获取一帧图像
CImageDataPointer pImageData = m_objStreamPtr->GetImage(timeout);
if (pImageData.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
// 填充图像数据
image.width = static_cast<unsigned int>(pImageData->GetWidth());
image.height = static_cast<unsigned int>(pImageData->GetHeight());
image.pixelFormat = static_cast<int>(pImageData->GetPixelFormat());
image.frameID = pImageData->GetFrameID();
image.timestamp = 0;
// 计算数据大小
image.dataSize = image.width * image.height;
if (image.pixelFormat == GX_PIXEL_FORMAT_MONO8) {
image.dataSize *= 1;
} else if (image.pixelFormat == GX_PIXEL_FORMAT_RGB8) {
image.dataSize *= 3;
}
// 分配内存并复制数据
image.pData = new unsigned char[image.dataSize];
memcpy(image.pData, pImageData->GetBuffer(), image.dataSize);
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM平台使用C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status;
// 获取图像 buffer 大小
int64_t nPayLoadSize = 0;
status = GXGetInt(m_hDevice, GX_INT_PAYLOAD_SIZE, &nPayLoadSize);
if (status != GX_STATUS_SUCCESS || nPayLoadSize <= 0) {
return ERR_CODE(DEV_CTRL_ERR);
}
// 分配图像缓冲区
GX_FRAME_DATA frameData;
memset(&frameData, 0, sizeof(GX_FRAME_DATA));
frameData.pImgBuf = malloc((size_t)nPayLoadSize);
if (!frameData.pImgBuf) {
return ERR_CODE(DATA_ERR_MEM);
}
status = GXSendCommand(m_hDevice, GX_COMMAND_ACQUISITION_START);
LOG_DEBUG("Command GX_COMMAND_ACQUISITION_START %d\n", status);
ERR_CODE_RETURN(status);
// 获取图像数据
while(GXGetImage(m_hDevice, &frameData, timeout) != GX_STATUS_SUCCESS)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
LOG_DEBUG("Command GXGetImage %d\n", frameData.nStatus);
// 检查帧状态
if (frameData.nStatus != GX_FRAME_STATUS_SUCCESS) {
free(frameData.pImgBuf);
return ERR_CODE(DEV_CTRL_ERR);
}else{
// 填充图像数据
image.width = frameData.nWidth;
image.height = frameData.nHeight;
image.pixelFormat = frameData.nPixelFormat;
image.frameID = frameData.nFrameID;
image.timestamp = frameData.nTimestamp;
image.dataSize = frameData.nImgSize;
// 分配内存并复制数据
image.pData = new unsigned char[image.dataSize];
memcpy(image.pData, frameData.pImgBuf, image.dataSize);
// 释放临时缓冲区
free(frameData.pImgBuf);
}
status = GXSendCommand(m_hDevice, GX_COMMAND_ACQUISITION_STOP);
return status;
#endif
}
// 注册图像回调
int CGalaxyDevice::RegisterImageCallback(GalaxyImageCallback callback)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objStreamPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
m_imageCallback = callback;
// 创建并注册回调处理器
if (!m_pCaptureEventHandler) {
m_pCaptureEventHandler = new CCaptureEventHandler(this);
}
m_objStreamPtr->RegisterCaptureCallback(m_pCaptureEventHandler, nullptr);
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API - 简化实现,不支持回调
m_imageCallback = callback;
return SUCCESS;
#endif
}
// 取消注册图像回调
int CGalaxyDevice::UnregisterImageCallback()
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (!m_objStreamPtr.IsNull()) {
m_objStreamPtr->UnregisterCaptureCallback();
}
if (m_pCaptureEventHandler) {
delete m_pCaptureEventHandler;
m_pCaptureEventHandler = nullptr;
}
m_imageCallback = nullptr;
return SUCCESS;
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API - 简化实现
m_imageCallback = nullptr;
return SUCCESS;
#endif
}
#ifdef _WIN32
// 图像回调处理(仅 Windows 平台)
void CGalaxyDevice::ProcessCapturedImage(CImageDataPointer& objImageDataPointer)
{
if (!m_imageCallback || objImageDataPointer.IsNull()) {
return;
}
try {
GalaxyImageData imageData;
// 获取图像信息
imageData.width = static_cast<unsigned int>(objImageDataPointer->GetWidth());
imageData.height = static_cast<unsigned int>(objImageDataPointer->GetHeight());
imageData.pixelFormat = static_cast<int>(objImageDataPointer->GetPixelFormat());
imageData.frameID = objImageDataPointer->GetFrameID();
imageData.timestamp = 0; // Galaxy SDK没有直接的GetTimestamp
// 计算数据大小
imageData.dataSize = imageData.width * imageData.height;
if (imageData.pixelFormat == GX_PIXEL_FORMAT_MONO8) {
imageData.dataSize *= 1;
} else if (imageData.pixelFormat == GX_PIXEL_FORMAT_RGB8) {
imageData.dataSize *= 3;
}
// 获取图像数据指针
imageData.pData = static_cast<unsigned char*>(objImageDataPointer->GetBuffer());
// 调用用户回调
if (m_imageCallback) {
m_imageCallback(imageData);
}
}
catch (...) {
// 忽略回调中的异常
}
}
#endif
// 获取图像宽度
int CGalaxyDevice::GetWidth(unsigned int& width)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CIntFeaturePointer ptrWidth = m_objFeatureControlPtr->GetIntFeature("Width");
if (!ptrWidth.IsNull()) {
width = static_cast<unsigned int>(ptrWidth->GetValue());
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:简化实现,返回默认值或通过其他方式获取
// 注意:如果需要实际获取宽度,需要使用 GxGetInt 等 C API
width = 0; // 默认值,或者从 m_capturedImage 中获取
if (m_capturedImage.width > 0) {
width = m_capturedImage.width;
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
#endif
}
// 获取图像高度
int CGalaxyDevice::GetHeight(unsigned int& height)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CIntFeaturePointer ptrHeight = m_objFeatureControlPtr->GetIntFeature("Height");
if (!ptrHeight.IsNull()) {
height = static_cast<unsigned int>(ptrHeight->GetValue());
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:简化实现,返回默认值或通过其他方式获取
height = 0; // 默认值,或者从 m_capturedImage 中获取
if (m_capturedImage.height > 0) {
height = m_capturedImage.height;
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
#endif
}
// 设置ROI - 简化实现
int CGalaxyDevice::SetROI(const GalaxyROI& roi)
{
// 简化实现:返回成功但不做处理
return SUCCESS;
}
// 获取ROI - 简化实现
int CGalaxyDevice::GetROI(GalaxyROI& roi)
{
// 简化实现:返回默认值
roi.offsetX = 0;
roi.offsetY = 0;
roi.width = 0;
roi.height = 0;
return SUCCESS;
}
// 设置曝光时间
int CGalaxyDevice::SetExposureTime(double exposureTime)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_UNSUPPORT);
}
CFloatFeaturePointer ptrExposureTime = m_objFeatureControlPtr->GetFloatFeature("ExposureTime");
if (!ptrExposureTime.IsNull()) {
ptrExposureTime->SetValue(exposureTime);
return SUCCESS;
}
return ERR_CODE(DEV_UNSUPPORT);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_UNSUPPORT);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXSetFloat(m_hDevice, GX_FLOAT_EXPOSURE_TIME, exposureTime);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 获取曝光时间
int CGalaxyDevice::GetExposureTime(double& exposureTime)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CFloatFeaturePointer ptrExposureTime = m_objFeatureControlPtr->GetFloatFeature("ExposureTime");
if (!ptrExposureTime.IsNull()) {
exposureTime = ptrExposureTime->GetValue();
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXGetFloat(m_hDevice, GX_FLOAT_EXPOSURE_TIME, &exposureTime);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 设置增益
int CGalaxyDevice::SetGain(double gain)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CFloatFeaturePointer ptrGain = m_objFeatureControlPtr->GetFloatFeature("Gain");
if (!ptrGain.IsNull()) {
ptrGain->SetValue(gain);
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXSetFloat(m_hDevice, GX_FLOAT_GAIN, gain);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 获取增益
int CGalaxyDevice::GetGain(double& gain)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CFloatFeaturePointer ptrGain = m_objFeatureControlPtr->GetFloatFeature("Gain");
if (!ptrGain.IsNull()) {
gain = ptrGain->GetValue();
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXGetFloat(m_hDevice, GX_FLOAT_GAIN, &gain);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 设置帧率
int CGalaxyDevice::SetFrameRate(double frameRate)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CFloatFeaturePointer ptrFrameRate = m_objFeatureControlPtr->GetFloatFeature("AcquisitionFrameRate");
if (!ptrFrameRate.IsNull()) {
ptrFrameRate->SetValue(frameRate);
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, frameRate);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 获取帧率
int CGalaxyDevice::GetFrameRate(double& frameRate)
{
#ifdef _WIN32
// Windows 平台:使用 C++ API
try {
if (m_objFeatureControlPtr.IsNull()) {
return ERR_CODE(DEV_CTRL_ERR);
}
CFloatFeaturePointer ptrFrameRate = m_objFeatureControlPtr->GetFloatFeature("AcquisitionFrameRate");
if (!ptrFrameRate.IsNull()) {
frameRate = ptrFrameRate->GetValue();
return SUCCESS;
}
return ERR_CODE(DEV_CTRL_ERR);
}
catch (CGalaxyException& e) {
return static_cast<int>(e.GetErrorCode());
}
catch (...) {
return ERR_CODE(DEV_CTRL_ERR);
}
#else
// Linux/ARM 平台:使用 C API
if (!m_hDevice) {
return ERR_CODE(DEV_CTRL_ERR);
}
GX_STATUS status = GXGetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, &frameRate);
return (status == GX_STATUS_SUCCESS) ? SUCCESS : static_cast<int>(status);
#endif
}
// 以下特性控制方法为简化实现
int CGalaxyDevice::SetIntFeature(const std::string& featureName, int64_t value)
{
return ERR_CODE(DEV_UNSUPPORT); // 简化实现
}
int CGalaxyDevice::GetIntFeature(const std::string& featureName, int64_t& value)
{
return ERR_CODE(DEV_CTRL_ERR); // 简化实现
}
int CGalaxyDevice::SetFloatFeature(const std::string& featureName, double value)
{
return ERR_CODE(DEV_UNSUPPORT); // 简化实现
}
int CGalaxyDevice::GetFloatFeature(const std::string& featureName, double& value)
{
return ERR_CODE(DEV_CTRL_ERR); // 简化实现
}
int CGalaxyDevice::SetEnumFeature(const std::string& featureName, int64_t value)
{
return ERR_CODE(DEV_UNSUPPORT); // 简化实现
}
int CGalaxyDevice::GetEnumFeature(const std::string& featureName, int64_t& value)
{
return ERR_CODE(DEV_CTRL_ERR); // 简化实现
}
int CGalaxyDevice::ExecuteCommand(const std::string& featureName)
{
return ERR_CODE(DEV_CTRL_ERR); // 简化实现
}