#include "GalaxyDevice.h" #include "GalaxySDKManager.h" #include "VrError.h" #include "VrLog.h" #include #include #include #include // 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() { if (m_bSDKInitialized) { return SUCCESS; } int ret = GalaxySDKManager::GetInstance().InitSDK(); if (ret == SUCCESS) { m_bSDKInitialized = true; } return ret; } // 反初始化SDK int CGalaxyDevice::UninitSDK() { if (m_bSDKInitialized) { int ret = GalaxySDKManager::GetInstance().UninitSDK(); if (ret == SUCCESS) { m_bSDKInitialized = false; } return ret; } return SUCCESS; } // 获取SDK版本 int CGalaxyDevice::GetSDKVersion(std::string& version) { version = "GalaxySDK 1.1.2412.9031"; return SUCCESS; } // 枚举设备 int CGalaxyDevice::EnumerateDevices(std::vector& 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(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(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(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); } // 设置采集缓冲区数量为5,支持多线程并行取图 CIntFeaturePointer ptrBufferNum = m_objFeatureControlPtr->GetIntFeature("StreamBufferHandlingMode"); if (!ptrBufferNum.IsNull()) { ptrBufferNum->SetValue(5); } m_bDeviceOpen = true; return SUCCESS; } catch (CGalaxyException& e) { m_objFeatureControlPtr = CGXFeatureControlPointer(); m_objStreamPtr = CGXStreamPointer(); m_objDevicePtr = CGXDevicePointer(); return static_cast(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(serialNumber.c_str()); GX_STATUS status = GXOpenDevice(&openParam, &m_hDevice); if (status != GX_STATUS_SUCCESS) { m_hDevice = nullptr; return static_cast(status); } // 3. 设置触发模式为连续触发(无需外部触发) status = GXSetEnum(m_hDevice, GX_ENUM_TRIGGER_MODE, GX_TRIGGER_MODE_OFF); LOG_DEBUG("Set trigger mode to off %s\n", status == GX_STATUS_SUCCESS ? "success" : "failed"); //使能采集帧率调节模式 status = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); //设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 status = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 5); LOG_DEBUG("Set acquisition frame rate to 5 %s\n", status == GX_STATUS_SUCCESS ? "success" : "failed"); // 设置数据传输块大小(提高传输性能) bool bStreamTransferSize = false; status = GXIsImplemented(m_hDevice, GX_DS_INT_STREAM_TRANSFER_SIZE, &bStreamTransferSize); if (status == GX_STATUS_SUCCESS && bStreamTransferSize) { status = GXSetInt(m_hDevice, GX_DS_INT_STREAM_TRANSFER_SIZE, 64 * 1024); if (status == GX_STATUS_SUCCESS) { LOG_DEBUG("Set stream transfer size to 64KB\n"); } } // 设置数据传输块数量(提高传输性能) bool bStreamTransferNumberUrb = false; status = GXIsImplemented(m_hDevice, GX_DS_INT_STREAM_TRANSFER_NUMBER_URB, &bStreamTransferNumberUrb); if (status == GX_STATUS_SUCCESS && bStreamTransferNumberUrb) { status = GXSetInt(m_hDevice, GX_DS_INT_STREAM_TRANSFER_NUMBER_URB, 64); if (status == GX_STATUS_SUCCESS) { LOG_DEBUG("Set stream transfer number URB to 64\n"); } } m_bDeviceOpen = true; return SUCCESS; #endif } // 通过索引打开设备 int CGalaxyDevice::OpenDeviceByIndex(unsigned int index) { try { // 先枚举设备 std::vector 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(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(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(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(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(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(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(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(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; } // 1. 先调用 GXStreamOn 开始采集 GX_STATUS status = GXStreamOn(m_hDevice); if (status != GX_STATUS_SUCCESS) { LOG_DEBUG("GXStreamOn failed: %d\n", status); return static_cast(status); } LOG_DEBUG("GXStreamOn success\n"); m_bAcquisitioning = true; return SUCCESS; #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(e.GetErrorCode()); } catch (...) { return ERR_CODE(DEV_CTRL_ERR); } #else // Linux/ARM 平台:使用 C API if (!m_bAcquisitioning) { return SUCCESS; } // 1. 发送停止采集命令 if (m_hDevice) { // 2. 调用 GXStreamOff 停止采集 GX_STATUS status = GXStreamOff(m_hDevice); if (status != GX_STATUS_SUCCESS) { LOG_DEBUG("GXStreamOff failed: %d\n", status); m_bAcquisitioning = false; return static_cast(status); } } m_bAcquisitioning = false; LOG_DEBUG("Acquisition stopped successfully\n"); 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(pImageData->GetWidth()); image.height = static_cast(pImageData->GetHeight()); image.pixelFormat = static_cast(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(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(e.GetErrorCode()); } catch (...) { return ERR_CODE(DEV_CTRL_ERR); } #else // Linux/ARM 平台:使用 C API,注册回调 if (!m_hDevice) { return ERR_CODE(DEV_CTRL_ERR); } m_imageCallback = callback; // 注册采集回调函数 GX_STATUS status = GXRegisterCaptureCallback(m_hDevice, this, OnFrameCallbackFun); if (status != GX_STATUS_SUCCESS) { LOG_DEBUG("GXRegisterCaptureCallback failed: %d\n", status); m_imageCallback = nullptr; return static_cast(status); } LOG_DEBUG("GXRegisterCaptureCallback success\n"); 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(e.GetErrorCode()); } catch (...) { return ERR_CODE(DEV_CTRL_ERR); } #else // Linux/ARM 平台:使用 C API,取消注册回调 if (m_hDevice) { GX_STATUS status = GXUnregisterCaptureCallback(m_hDevice); if (status != GX_STATUS_SUCCESS) { LOG_DEBUG("GXUnregisterCaptureCallback failed: %d\n", status); } } 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(objImageDataPointer->GetWidth()); imageData.height = static_cast(objImageDataPointer->GetHeight()); imageData.pixelFormat = static_cast(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(objImageDataPointer->GetBuffer()); // 调用用户回调 if (m_imageCallback) { m_imageCallback(imageData); } } catch (...) { // 忽略回调中的异常 } } #else // Linux/ARM ��台:采图线程函数 void GX_STDC CGalaxyDevice::OnFrameCallbackFun(GX_FRAME_CALLBACK_PARAM* pFrame) { if (pFrame == nullptr || pFrame->pUserParam == nullptr) { return; } // 从用户参数中获取设备对象指针 CGalaxyDevice* pDevice = static_cast(pFrame->pUserParam); // 检查帧状态 if (pFrame->status == GX_FRAME_STATUS_SUCCESS) { // 如果有回调函数,调用回调 if (pDevice->m_imageCallback) { GalaxyImageData imageData; imageData.width = pFrame->nWidth; imageData.height = pFrame->nHeight; imageData.pixelFormat = pFrame->nPixelFormat; imageData.frameID = pFrame->nFrameID; imageData.timestamp = pFrame->nTimestamp; imageData.dataSize = pFrame->nImgSize; imageData.pData = reinterpret_cast(const_cast(pFrame->pImgBuf)); try { pDevice->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(ptrWidth->GetValue()); return SUCCESS; } return ERR_CODE(DEV_CTRL_ERR); } catch (CGalaxyException& e) { return static_cast(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(ptrHeight->GetValue()); return SUCCESS; } return ERR_CODE(DEV_CTRL_ERR); } catch (CGalaxyException& e) { return static_cast(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(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(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(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(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(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(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(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(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(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(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(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(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); // 简化实现 }