#include "GalaxyCamera.h" #include #include #ifdef _WIN32 #include #endif // 静态成员初始化 bool GalaxyCamera::s_sdkInitialized = false; int GalaxyCamera::s_instanceCount = 0; std::mutex GalaxyCamera::s_sdkMutex; GalaxyCamera::GalaxyCamera() : m_pCaptureEventHandler(nullptr) , m_bIsOpen(false) , m_bIsStreaming(false) , m_bHasNewFrame(false) { std::lock_guard lock(s_sdkMutex); s_instanceCount++; } GalaxyCamera::~GalaxyCamera() { try { StopStreaming(); Close(); } catch (...) { // 忽略清理异常 } std::lock_guard lock(s_sdkMutex); s_instanceCount--; // 注意:不在析构函数中反初始化SDK // SDK应该在程序退出时统一清理,或者由最后一个实际使用的相机来清理 // 因为DetectAvailableBrands会频繁创建/销毁临时实例 } // 检查大恒SDK DLL是否可用 static bool IsGalaxySDKAvailable() { #ifdef _WIN32 // 尝试加载大恒SDK主DLL // 使用 LOAD_LIBRARY_AS_DATAFILE 避免触发DLL的依赖加载 HMODULE hModule = LoadLibraryExA("GxIAPI.dll", nullptr, LOAD_LIBRARY_AS_DATAFILE); if (hModule == nullptr) { // DLL不在PATH中或不存在 return false; } FreeLibrary(hModule); // 进一步检查:尝试真正加载DLL(会检查依赖) hModule = LoadLibraryA("GxIAPI.dll"); if (hModule == nullptr) { // DLL存在但依赖项缺失(如缺少MSVCP140D.dll) return false; } FreeLibrary(hModule); return true; #else return true; // 非Windows平台假设可用 #endif } bool GalaxyCamera::Init(const std::string& sdkPath) { (void)sdkPath; std::lock_guard lock(s_sdkMutex); // 如果SDK已经初始化,直接返回成功 if (s_sdkInitialized) { return true; } // 首先检查SDK DLL是否可用 if (!IsGalaxySDKAvailable()) { return false; } try { // 尝试获取工厂实例并初始化 IGXFactory& factory = IGXFactory::GetInstance(); factory.Init(); s_sdkInitialized = true; return true; } catch (CGalaxyException& e) { (void)e; s_sdkInitialized = false; return false; } catch (std::exception& e) { (void)e; s_sdkInitialized = false; return false; } catch (...) { // 捕获所有其他异常 s_sdkInitialized = false; return false; } } std::vector GalaxyCamera::Discover() { std::vector devices; m_vectorDeviceInfo.clear(); if (!s_sdkInitialized) { return devices; } try { // 枚举设备,超时1000ms IGXFactory::GetInstance().UpdateDeviceList(1000, m_vectorDeviceInfo); for (uint32_t i = 0; i < m_vectorDeviceInfo.size(); i++) { DeviceInfo appDevInfo; // 获取设备序列号作为ID appDevInfo.id = m_vectorDeviceInfo[i].GetSN().c_str(); // 获取设备显示名称 appDevInfo.name = m_vectorDeviceInfo[i].GetDisplayName().c_str(); // 标记品牌 appDevInfo.brand = "Galaxy"; devices.push_back(appDevInfo); } } catch (CGalaxyException& e) { (void)e; } catch (std::exception& e) { (void)e; } return devices; } bool GalaxyCamera::Open(const std::string& deviceID) { if (m_bIsOpen) { Close(); } if (!s_sdkInitialized) { return false; } bool bIsDeviceOpen = false; bool bIsStreamOpen = false; try { // 通过序列号打开设备 m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN( deviceID.c_str(), GX_ACCESS_EXCLUSIVE); bIsDeviceOpen = true; // 获取远程属性控制器 m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl(); // 设置采集模式为连续采集 m_objFeatureControlPtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); // 设置触发模式为关(软件触发时先关闭,后续按需开启) m_objFeatureControlPtr->GetEnumFeature("TriggerMode")->SetValue("Off"); // 获取设备流个数 int nStreamCount = m_objDevicePtr->GetStreamCount(); if (nStreamCount > 0) { m_objStreamPtr = m_objDevicePtr->OpenStream(0); m_objStreamFeatureControlPtr = m_objStreamPtr->GetFeatureControl(); bIsStreamOpen = true; } else { throw std::exception("未发现设备流!"); } // 对于GigE相机,设置最优包长 GX_DEVICE_CLASS_LIST objDeviceClass = m_objDevicePtr->GetDeviceInfo().GetDeviceClass(); if (GX_DEVICE_CLASS_GEV == objDeviceClass) { if (m_objFeatureControlPtr->IsImplemented("GevSCPSPacketSize")) { int nPacketSize = m_objStreamPtr->GetOptimalPacketSize(); m_objFeatureControlPtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); } } // 创建采集回调处理器 m_pCaptureEventHandler = new CaptureEventHandler(this); m_bIsOpen = true; return true; } catch (CGalaxyException& e) { (void)e; if (bIsStreamOpen && !m_objStreamPtr.IsNull()) { m_objStreamPtr->Close(); } if (bIsDeviceOpen && !m_objDevicePtr.IsNull()) { m_objDevicePtr->Close(); } m_bIsOpen = false; return false; } catch (std::exception& e) { (void)e; if (bIsStreamOpen && !m_objStreamPtr.IsNull()) { m_objStreamPtr->Close(); } if (bIsDeviceOpen && !m_objDevicePtr.IsNull()) { m_objDevicePtr->Close(); } m_bIsOpen = false; return false; } } void GalaxyCamera::Close() { if (!m_bIsOpen) { return; } try { // 停止采集 StopStreaming(); // 关闭流对象 if (!m_objStreamPtr.IsNull()) { m_objStreamPtr->Close(); } // 关闭设备 if (!m_objDevicePtr.IsNull()) { m_objDevicePtr->Close(); } } catch (CGalaxyException&) { // 忽略关闭异常 } catch (std::exception&) { // 忽略关闭异常 } // 释放回调处理器 if (m_pCaptureEventHandler != nullptr) { delete m_pCaptureEventHandler; m_pCaptureEventHandler = nullptr; } m_bIsOpen = false; } bool GalaxyCamera::SetROI(int x, int y, int w, int h) { if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) { return false; } try { // 获取最大宽高 int64_t widthMax = m_objFeatureControlPtr->GetIntFeature("WidthMax")->GetValue(); int64_t heightMax = m_objFeatureControlPtr->GetIntFeature("HeightMax")->GetValue(); // 基本验证 if (w <= 0 || h <= 0 || x < 0 || y < 0 || (x + w) > widthMax || (y + h) > heightMax) { return false; } // 大恒相机ROI通常需要是4的倍数 w = (w / 4) * 4; h = (h / 4) * 4; x = (x / 4) * 4; y = (y / 4) * 4; if (w <= 0) w = 4; if (h <= 0) h = 4; // 设置ROI m_objFeatureControlPtr->GetIntFeature("Width")->SetValue(w); m_objFeatureControlPtr->GetIntFeature("Height")->SetValue(h); m_objFeatureControlPtr->GetIntFeature("OffsetX")->SetValue(x); m_objFeatureControlPtr->GetIntFeature("OffsetY")->SetValue(y); return true; } catch (CGalaxyException& e) { (void)e; return false; } catch (std::exception& e) { (void)e; return false; } } bool GalaxyCamera::StartStreaming(FrameCallback callback) { if (!m_bIsOpen || m_bIsStreaming) { return false; } try { // 保存回调函数 m_frameCallback = callback; // 设置Buffer处理模式 try { m_objStreamFeatureControlPtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); } catch (...) { // 部分相机可能不支持此特性,忽略 } // 注册采集回调 m_objStreamPtr->RegisterCaptureCallback(m_pCaptureEventHandler, this); // 开启流层采集 m_objStreamPtr->StartGrab(); // 发送开采命令 m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute(); m_bIsStreaming = true; return true; } catch (CGalaxyException& e) { (void)e; // 清理 try { m_objStreamPtr->StopGrab(); m_objStreamPtr->UnregisterCaptureCallback(); } catch (...) {} m_bIsStreaming = false; return false; } catch (std::exception& e) { (void)e; try { m_objStreamPtr->StopGrab(); m_objStreamPtr->UnregisterCaptureCallback(); } catch (...) {} m_bIsStreaming = false; return false; } } void GalaxyCamera::StopStreaming() { if (!m_bIsOpen || !m_bIsStreaming) { return; } try { // 发送停采命令 m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute(); // 关闭流层采集 m_objStreamPtr->StopGrab(); // 注销回调函数 m_objStreamPtr->UnregisterCaptureCallback(); } catch (CGalaxyException&) { // 忽略异常 } catch (std::exception&) { // 忽略异常 } m_bIsStreaming = false; m_bHasNewFrame = false; } bool GalaxyCamera::IsStreaming() const { return m_bIsStreaming; } bool GalaxyCamera::GrabCurrentFrame(ImageBuffer& out) { if (!m_bIsStreaming) { return false; } std::lock_guard lock(m_frameMutex); if (!m_latestFramePtr || m_latestFramePtr->data.empty()) { return false; } // 复制最新帧数据 out = *m_latestFramePtr; m_bHasNewFrame = false; return true; } bool GalaxyCamera::Capture(ImageBuffer& out) { if (!m_bIsOpen) { return false; } // 如果正在流模式,使用GrabCurrentFrame if (m_bIsStreaming) { return GrabCurrentFrame(out); } try { // 单帧采集模式 // 开启流层采集 m_objStreamPtr->StartGrab(); // 发送开采命令 m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute(); // 获取一帧图像,超时5000ms CImageDataPointer objImageDataPointer = m_objStreamPtr->GetImage(5000); if (objImageDataPointer.IsNull()) { m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute(); m_objStreamPtr->StopGrab(); return false; } // 检查图像状态 if (objImageDataPointer->GetStatus() != GX_FRAME_STATUS_SUCCESS) { m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute(); m_objStreamPtr->StopGrab(); return false; } // 转换图像数据 out.width = static_cast(objImageDataPointer->GetWidth()); out.height = static_cast(objImageDataPointer->GetHeight()); out.pixelFormat = convertPixelFormat(objImageDataPointer->GetPixelFormat()); // 计算数据大小 size_t dataSize = objImageDataPointer->GetPayloadSize(); out.data.resize(dataSize); // 复制图像数据 void* pBuffer = objImageDataPointer->GetBuffer(); if (pBuffer) { std::memcpy(out.data.data(), pBuffer, dataSize); } // 停止采集 m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute(); m_objStreamPtr->StopGrab(); return true; } catch (CGalaxyException& e) { (void)e; try { m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute(); m_objStreamPtr->StopGrab(); } catch (...) {} return false; } catch (std::exception& e) { (void)e; try { m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute(); m_objStreamPtr->StopGrab(); } catch (...) {} return false; } } bool GalaxyCamera::GetIntValue(const std::string& name, int& value) { if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) { return false; } try { // 映射参数名称 std::string gxName = name; if (name == "Width" || name == "Height" || name == "OffsetX" || name == "OffsetY") { // 直接使用 } value = static_cast(m_objFeatureControlPtr->GetIntFeature(gxName.c_str())->GetValue()); return true; } catch (CGalaxyException&) { return false; } catch (std::exception&) { return false; } } bool GalaxyCamera::SetIntValue(const std::string& name, int value) { if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) { return false; } try { m_objFeatureControlPtr->GetIntFeature(name.c_str())->SetValue(value); return true; } catch (CGalaxyException&) { return false; } catch (std::exception&) { return false; } } bool GalaxyCamera::GetFloatValue(const std::string& name, float& value) { if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) { return false; } try { // 映射参数名称到大恒SDK参数名 std::string gxName = name; if (name == "ExposureTime") { gxName = "ExposureTime"; } else if (name == "Gain") { gxName = "Gain"; } value = static_cast(m_objFeatureControlPtr->GetFloatFeature(gxName.c_str())->GetValue()); return true; } catch (CGalaxyException&) { return false; } catch (std::exception&) { return false; } } bool GalaxyCamera::SetFloatValue(const std::string& name, float value) { if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) { return false; } try { // 映射参数名称 std::string gxName = name; if (name == "ExposureTime") { gxName = "ExposureTime"; } else if (name == "Gain") { gxName = "Gain"; } m_objFeatureControlPtr->GetFloatFeature(gxName.c_str())->SetValue(value); return true; } catch (CGalaxyException&) { return false; } catch (std::exception&) { return false; } } bool GalaxyCamera::IsConnected() { return m_bIsOpen && !m_objDevicePtr.IsNull(); } void GalaxyCamera::Cleanup() { Close(); } void GalaxyCamera::UninitSDK() { std::lock_guard lock(s_sdkMutex); if (s_sdkInitialized) { try { IGXFactory::GetInstance().Uninit(); s_sdkInitialized = false; } catch (...) { // 忽略清理异常 } } } // 采集回调处理 void GalaxyCamera::CaptureEventHandler::DoOnImageCaptured( CImageDataPointer& objImageDataPointer, void* pUserParam) { try { GalaxyCamera* pCamera = static_cast(pUserParam); if (pCamera) { pCamera->processFrame(objImageDataPointer); } } catch (CGalaxyException&) { // 忽略异常 } catch (std::exception&) { // 忽略异常 } } void GalaxyCamera::processFrame(CImageDataPointer& objImageDataPointer) { if (objImageDataPointer.IsNull()) { return; } // 检查图像状态 if (objImageDataPointer->GetStatus() != GX_FRAME_STATUS_SUCCESS) { return; } try { // 创建新的图像缓冲区 auto newFrame = std::make_shared(); newFrame->width = static_cast(objImageDataPointer->GetWidth()); newFrame->height = static_cast(objImageDataPointer->GetHeight()); newFrame->pixelFormat = convertPixelFormat(objImageDataPointer->GetPixelFormat()); // 获取图像数据大小 size_t dataSize = objImageDataPointer->GetPayloadSize(); newFrame->data.resize(dataSize); // 复制图像数据 void* pBuffer = objImageDataPointer->GetBuffer(); if (pBuffer) { std::memcpy(newFrame->data.data(), pBuffer, dataSize); } // 更新最新帧 { std::lock_guard lock(m_frameMutex); m_latestFramePtr = newFrame; m_bHasNewFrame = true; } // 调用用户回调 if (m_frameCallback) { m_frameCallback(newFrame); } } catch (std::exception&) { // 忽略异常 } } PixelFormat GalaxyCamera::convertPixelFormat(GX_PIXEL_FORMAT_ENTRY gxFormat) { switch (gxFormat) { case GX_PIXEL_FORMAT_MONO8: return PixelFormat::Mono8; case GX_PIXEL_FORMAT_MONO10: return PixelFormat::Mono10; case GX_PIXEL_FORMAT_MONO12: return PixelFormat::Mono12; case GX_PIXEL_FORMAT_MONO16: return PixelFormat::Mono16; case GX_PIXEL_FORMAT_BAYER_RG8: return PixelFormat::BayerRG8; case GX_PIXEL_FORMAT_BAYER_GB8: return PixelFormat::BayerGB8; case GX_PIXEL_FORMAT_BAYER_GR8: return PixelFormat::BayerGR8; case GX_PIXEL_FORMAT_BAYER_BG8: return PixelFormat::BayerBG8; default: // 对于未知格式,默认返回Mono8 return PixelFormat::Mono8; } }